All TypeScript templates

TypeScript Monorepo (Turborepo)

Turborepo + pnpm workspaces: shared types, build pipelines, caching.

DevZone Tools1,410 copiesUpdated Feb 18, 2026TypeScript
# CLAUDE.md — TypeScript Monorepo (Turborepo)

## Layout

```
apps/
  web/              # the Next.js / React / etc. app
  api/              # backend
  marketing/
packages/
  ui/               # shared React components
  config/           # tsconfig, eslint, prettier presets
  utils/            # framework-agnostic utilities
  types/            # shared type definitions
turbo.json
package.json        # workspaces root
pnpm-workspace.yaml # if pnpm
```

- `apps/*` are deployable. `packages/*` are internal libraries.
- Each package has its own `package.json`, `tsconfig.json`, build scripts.

## Package manager

- **pnpm** is the default. It saves disk and enforces strict dep boundaries.
- `pnpm-workspace.yaml`:
  ```yaml
  packages:
    - "apps/*"
    - "packages/*"
  ```
- Add `"workspace:*"` for internal package versions in dependent `package.json`s.

## TypeScript config

- One base `tsconfig.json` in `packages/config/typescript`. Apps and packages extend it:
  ```json
  { "extends": "@repo/config/typescript/base.json", "include": ["src"] }
  ```
- Use **TypeScript project references** for incremental builds across packages. `tsc --build` walks the graph.
- Each package emits to its own `dist/`. Source-only consumers read from `src/` via the `exports` map.

## Turbo pipelines

- `turbo.json` declares task dependencies, inputs, outputs, and cache rules:
  ```json
  {
    "tasks": {
      "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
      "lint":  { "dependsOn": ["^build"] },
      "test":  { "dependsOn": ["^build"], "outputs": ["coverage/**"] }
    }
  }
  ```
- `^build` means "build my dependencies first." Get this right and CI flies.
- Outputs are what's cacheable. Inputs default to all package files; narrow them when relevant.

## Caching

- Local cache by default. **Remote cache** for CI: `turbo login` + `turbo link`, or self-hosted.
- Cache misses on `node_modules` mean your `inputs` are too broad.
- Don't cache flaky tests. Mark them `cache: false`.

## Internal package consumption

- Use `workspace:*` everywhere — never relative paths into other packages.
- Re-export the public surface from `package.json#exports`. Don't let consumers reach into `dist/internal/`.
- For server-only code, mark with `"type": "module"` or split into separate sub-paths.

## Linting & formatting

- One ESLint config in `packages/config/eslint/`. Apps extend it.
- Ban cross-package imports that aren't declared as deps via `eslint-plugin-import`.
- One Prettier config at the root. Don't fork per package.

## Don't

- Don't put deployable apps inside `packages/` or libraries inside `apps/`.
- Don't share devDependencies via the root `package.json` — each package declares what it actually uses.
- Don't `tsc` from the root and pretend it's a build. Use Turbo's `build` task or it won't cache.
- Don't depend on a package's internal files (`@repo/ui/dist/internal/x`). Always go through `exports`.

Other TypeScript templates