Agent skill
typescript-monorepo
Configure TypeScript in a Bun/npm workspaces monorepo with shared base config, package-specific overrides, path aliases, and cross-package type sharing. Use when setting up tsconfig files, configuring path aliases, resolving module errors, or sharing types between packages.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/typescript-monorepo
Metadata
Additional technical details for this skill
- author
- ftcmetrics
- version
- 1.0.0
- category
- tools
SKILL.md
TypeScript Monorepo Configuration
This guide covers TypeScript configuration patterns for monorepos using Bun/npm workspaces, with examples from the FTC Metrics project structure.
Project Structure
ftcmetrics-v2/
tsconfig.base.json # Shared compiler options
package.json # Workspaces: ["packages/*"]
packages/
web/ # Next.js frontend
tsconfig.json # Extends base, adds JSX/DOM
api/ # Hono API server
tsconfig.json # Extends base, adds Node types
db/ # Prisma database package
tsconfig.json # Extends base
shared/ # Shared types and utilities
tsconfig.json # Extends base
src/
index.ts # Re-exports all types
types.ts # Shared type definitions
Base Configuration
The tsconfig.base.json at the workspace root defines shared compiler options:
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"declaration": true,
"declarationMap": true
}
}
Key Settings Explained
| Option | Value | Purpose |
|---|---|---|
target |
ES2022 | Modern JS output with top-level await, class fields |
module |
ESNext | Native ESM with dynamic imports |
moduleResolution |
bundler | For bundlers (Bun, Vite, Next.js) |
strict |
true | Enables all strict type checks |
isolatedModules |
true | Required for bundlers/transpilers |
skipLibCheck |
true | Faster builds, skip .d.ts checking |
declaration |
true | Generate .d.ts for package consumers |
declarationMap |
true | Source maps for .d.ts files |
Package-Specific Configurations
Web Package (Next.js)
packages/web/tsconfig.json:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"lib": ["dom", "dom.iterable", "ES2022"],
"jsx": "preserve",
"module": "ESNext",
"moduleResolution": "bundler",
"plugins": [{ "name": "next" }],
"paths": {
"@/*": ["./src/*"]
},
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Additions:
lib: ["dom", "dom.iterable"]- Browser APIsjsx: "preserve"- Let Next.js handle JSX transformationpaths- Local import aliases (@/components/...)plugins- Next.js TypeScript plugin for route typing
API Package (Node/Hono)
packages/api/tsconfig.json:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"types": ["node"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Additions:
types: ["node"]- Node.js type definitionsoutDir/rootDir- Build output configuration
Shared Package (Types Only)
packages/shared/tsconfig.json:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
Path Aliases
Local Aliases (Within Package)
For imports within the same package, use paths in tsconfig:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/lib/*": ["./src/lib/*"],
"@/components/*": ["./src/components/*"]
}
}
}
Usage:
import { Button } from "@/components/Button";
import { fetchApi } from "@/lib/api";
Cross-Package Imports (Workspace)
For importing from other packages, use workspace dependencies in package.json:
{
"dependencies": {
"@ftcmetrics/shared": "workspace:*",
"@ftcmetrics/db": "workspace:*"
}
}
Usage:
import { Team, ApiResponse } from "@ftcmetrics/shared";
import { prisma } from "@ftcmetrics/db";
Shared Types Pattern
Structure the Shared Package
packages/shared/package.json:
{
"name": "@ftcmetrics/shared",
"main": "./src/index.ts",
"types": "./src/index.ts"
}
packages/shared/src/index.ts:
// Re-export all types
export * from './types';
export * from './constants';
export * from './utils';
packages/shared/src/types.ts:
// Domain types
export type TeamRole = 'mentor' | 'member';
export type SharingLevel = 'private' | 'event' | 'public';
export interface Team {
id: string;
teamNumber: number;
name: string;
sharingLevel: SharingLevel;
createdAt: Date;
}
// API response wrapper
export interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
}
Consume Shared Types
// In packages/api/src/routes/teams.ts
import type { Team, ApiResponse } from "@ftcmetrics/shared";
function getTeam(id: string): Promise<ApiResponse<Team>> {
// ...
}
Module Augmentation
Extend third-party types using declaration files:
packages/web/src/types/next-auth.d.ts:
import { DefaultSession } from "next-auth";
declare module "next-auth" {
interface Session {
user: {
id: string;
} & DefaultSession["user"];
}
}
Strict Mode Benefits
The strict: true flag enables these checks:
| Flag | What It Catches |
|---|---|
strictNullChecks |
Null/undefined access errors |
strictFunctionTypes |
Incorrect callback parameter types |
strictBindCallApply |
Wrong arguments to bind/call/apply |
strictPropertyInitialization |
Uninitialized class properties |
noImplicitAny |
Missing type annotations |
noImplicitThis |
Ambiguous this context |
useUnknownInCatchVariables |
Catch variables typed as unknown |
alwaysStrict |
Emits "use strict" in JS output |
Common Type Errors and Fixes
1. Module Not Found
Error: Cannot find module '@ftcmetrics/shared'
Fix: Ensure workspace dependency is added:
bun add @ftcmetrics/shared@workspace:*
2. Path Alias Not Resolving
Error: Cannot find module '@/lib/api'
Fix: Ensure baseUrl is set when using paths:
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}
3. Type Mismatch Across Packages
Error: Type 'import("pkg-a").Team' is not assignable to type 'import("pkg-b").Team'
Fix: Import from the shared package, not duplicate definitions:
// Wrong: duplicate type
interface Team { ... }
// Right: import from shared
import type { Team } from "@ftcmetrics/shared";
4. Declaration File Not Emitting
Error: Types not available to consumers
Fix: Enable declarations in tsconfig:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true
}
}
5. Implicit Any in Catch Blocks
Error: Catch clause variable is of type 'unknown'
Fix: Type-narrow the error:
try {
// ...
} catch (error) {
if (error instanceof Error) {
console.error(error.message);
}
}
6. Missing DOM Types in Node Package
Error: Cannot find name 'fetch'
Fix: Add to lib or use node-fetch:
{
"compilerOptions": {
"lib": ["ES2022", "DOM"]
}
}
Or with Node 18+:
{
"compilerOptions": {
"types": ["node"]
}
}
7. JSON Import Error
Error: Cannot find module './config.json'
Fix: Enable JSON imports:
{
"compilerOptions": {
"resolveJsonModule": true
}
}
Type Checking Commands
# Type check all packages
bun run typecheck
# Type check specific package
bun run --filter @ftcmetrics/web typecheck
# Type check with verbose output
tsc --noEmit --pretty
Best Practices
- Single Source of Truth: Define types once in
@ftcmetrics/shared - Use
typeImports: Preferimport type { }for type-only imports - Avoid Relative Imports Across Packages: Use workspace dependencies
- Keep Base Config Minimal: Package-specific settings in package tsconfig
- Enable Incremental Builds: Add
"incremental": truefor faster rebuilds - Exclude Build Outputs: Always exclude
node_modules,dist,.next
Adding a New Package
- Create package directory with
src/folder - Create
package.jsonwith workspace name - Create
tsconfig.jsonextending base:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
- Add typecheck script:
{
"scripts": {
"typecheck": "tsc --noEmit"
}
}
- If consuming shared types, add dependency:
{
"dependencies": {
"@ftcmetrics/shared": "workspace:*"
}
}
References
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?