---
name: js-monorepo
description: >
  JS/TS monorepo with pnpm workspaces and Turborepo.
  Use when setting up a monorepo, adding packages, or auditing config.
---

# JS Monorepo

Set up and maintain JavaScript/TypeScript monorepos with pnpm workspaces, Turborepo, and shared packages.

## Critical Rules

1. **pnpm workspaces only** - No yarn workspaces, no npm workspaces. pnpm is the package manager.
2. **Turborepo for task orchestration** - All cross-package scripts go through turbo.
3. **Two non-negotiable packages** - Every monorepo MUST have `contracts` and `ui` packages.
4. **`workspace:*` protocol** - Apps reference internal packages via `"@your-org/contracts": "workspace:*"`.
5. **pnpm catalogs for external deps** - Define versions once in `pnpm-workspace.yaml`, reference via `catalog:` protocol.
6. **Root owns tooling** - ESLint, Prettier, TypeScript base config, Husky all live at the root.
7. **Packages own their tsconfig** - Each package extends `tsconfig.base.json` from root.
8. **Standardized script names** - All packages use the same turbo-compatible script names (**Read** [references/package-patterns.md](references/package-patterns.md) for the full script table).
9. **Bootstrap script is mandatory** - New developers must be able to run one command to get started.

## Sub-Commands Overview

| Command | Purpose |
|---------|---------|
| `/js-monorepo init` | Set up a new monorepo from scratch |
| `/js-monorepo add-package` | Add a shared package to an existing monorepo |
| `/js-monorepo review` | Audit existing monorepo for issues |

## Monorepo Structure

```
your-project/
├── apps/                     # Deployable applications
│   ├── web-app/              # Next.js frontend
│   └── api/                  # NestJS/Express backend
├── packages/                 # Shared packages
│   ├── contracts/            # NON-NEGOTIABLE: Types, Zod schemas, interfaces
│   └── ui/                   # NON-NEGOTIABLE: React components, hooks, patterns
├── scripts/                  # Monorepo scripts (bootstrap, pre-commit, etc.)
├── turbo.json                # Turborepo pipeline
├── pnpm-workspace.yaml       # Workspace definition + dependency catalogs
├── tsconfig.base.json        # Shared TypeScript config
├── eslint.config.mjs         # ESLint 9 flat config (root)
├── prettier.config.mjs       # Prettier config (root)
├── .prettierignore            # Prettier ignore patterns
├── .gitignore                 # Git ignore patterns
├── .editorconfig             # Editor settings
├── .husky/pre-commit         # Pre-commit hook
└── package.json              # Root: engines, scripts, devDependencies
```

## Before Any Sub-Command

1. **Read** [references/config-templates.md](references/config-templates.md) - Root config file templates
2. **Read** [references/scripts-templates.md](references/scripts-templates.md) - Script and runtime config templates
3. **Read** [references/package-patterns.md](references/package-patterns.md) - Package structure, scripts, and guidance
4. **Read** [references/shadcn-setup.md](references/shadcn-setup.md) - shadcn/ui initialization and monorepo wiring (if project uses shadcn)

## Sub-Commands

### `/js-monorepo init`

**When:** Setting up a new monorepo from scratch or converting an existing project.

**Steps:**

1. **Scaffold directory structure:**
   ```
   mkdir -p apps packages/contracts/src packages/ui/src scripts .husky
   ```

2. **Create root config files** (use templates from [references/config-templates.md](references/config-templates.md)):
   - [ ] `pnpm-workspace.yaml` - Workspace packages + dependency catalogs
   - [ ] `turbo.json` - Task pipeline with env vars and caching config
   - [ ] `tsconfig.base.json` - Shared TypeScript base (strict, verbatimModuleSyntax)
   - [ ] `eslint.config.mjs` - ESLint 9 flat config with projectService
   - [ ] `prettier.config.mjs` - Prettier with import sorting + Tailwind
   - [ ] `.prettierignore` - Ignore build artifacts, lockfiles, cache
   - [ ] `.gitignore` - Comprehensive monorepo ignores
   - [ ] `.editorconfig` - Editor consistency

3. **Create scripts and runtime configs** (use templates from [references/scripts-templates.md](references/scripts-templates.md)):
   - [ ] `package.json` - Root with engines, scripts, devDependencies
   - [ ] `.husky/pre-commit` - Smart pre-commit hook
   - [ ] `scripts/pre-commit-checks.sh` - Pre-commit validation script (capture → fix → restage → validate)
   - [ ] `scripts/bootstrap.sh` - One-command developer setup

4. **Create non-negotiable packages** (use templates from [references/package-patterns.md](references/package-patterns.md)):
   - [ ] `packages/contracts/` - Types, Zod schemas, shared interfaces
   - [ ] `packages/ui/` - React components, hooks, utilities

5. **Update CLAUDE.md** (**Read** [CLAUDE.md Guidance](#claudemd-guidance) for the template)

6. **Verify structure:**
   - [ ] `pnpm install` succeeds
   - [ ] `pnpm build` succeeds (turbo)
   - [ ] `pnpm check` succeeds (format + lint + typecheck + build)

### `/js-monorepo add-package <name> [type]`

**When:** Adding a new shared package to an existing monorepo.

**Arguments:**
- `<name>` - Package name (e.g., `config-eslint`, `config-tailwind`, `email`)
- `[type]` - Optional: `source` (no build, consume as TypeScript) or `compiled` (builds to dist). Default: `source`.

**Steps:**

1. **Create package directory:**
   ```
   mkdir -p packages/<name>/src
   ```

2. **Determine package type:**

   | Type | Build | Main | Types | Use Case |
   |------|-------|------|-------|----------|
   | `source` | `noEmit: true` | `./src/index.ts` | `./src/index.ts` | UI components, hooks, config |
   | `compiled` | `tsc --build` | `./dist/index.js` | `./src/index.ts` | Contracts, utilities shared with backend |

3. **Create package files** (use templates from [references/package-patterns.md](references/package-patterns.md)):
   - [ ] `package.json` - Name, exports, standardized scripts, dependencies (use `catalog:` for external deps)
   - [ ] `tsconfig.json` - Extends root `tsconfig.base.json`
   - [ ] `src/index.ts` - Barrel export

4. **Wire into monorepo:**
   - Apps that need it: add `"@your-org/<name>": "workspace:*"` to dependencies
   - Run `pnpm install` to link

5. **Verify:**
   - [ ] `pnpm build` passes with new package in the graph
   - [ ] Importing from the package works in consuming apps

### `/js-monorepo review`

**When:** Auditing an existing monorepo for issues, after setup, or during troubleshooting.

**Steps:**

1. **Scan** root config files:
   - [ ] `pnpm-workspace.yaml` exists with `apps/*` + `packages/*` and catalogs
   - [ ] `turbo.json` exists with correct task dependencies, env vars, and outputLogs
   - [ ] `tsconfig.base.json` exists with strict mode and `verbatimModuleSyntax`
   - [ ] `eslint.config.mjs` exists with TypeScript projectService + allowDefaultProject
   - [ ] `prettier.config.mjs` exists with import sorting
   - [ ] `.prettierignore` exists (not formatting build artifacts)
   - [ ] `.gitignore` exists with monorepo patterns (.turbo, dist, .next, *.tsbuildinfo)
   - [ ] `.editorconfig` exists
   - [ ] `.husky/pre-commit` exists and calls pre-commit script

2. **Scan** non-negotiable packages:
   - [ ] `packages/contracts/` exists with proper exports
   - [ ] `packages/ui/` exists with fine-grained exports
   - [ ] Both have `tsconfig.json` extending root
   - [ ] Both have standardized scripts (lint, typecheck, validate, build/dev)

3. **Scan** standardized scripts across all packages:
   - [ ] All packages have `lint`, `typecheck`, `validate` scripts
   - [ ] Compiled packages have `build` and `dev` (watch) scripts
   - [ ] Source packages have `dev` (watch --noEmit) script
   - [ ] Root has all orchestration scripts (**Read** [references/scripts-templates.md](references/scripts-templates.md) for expected scripts)

4. **Scan** task pipeline in `turbo.json`:
   - [ ] `format` task exists (no cache)
   - [ ] `lint` depends on `^format`, has `inputs` and `outputLogs: "errors-only"`
   - [ ] `typecheck` depends on `^typecheck`
   - [ ] `build` depends on `^build`, `validate`, `typecheck`, has `env` for framework vars
   - [ ] `dev` is persistent, no cache, `interruptible: true`
   - [ ] `globalEnv` includes `CI` and `NODE_ENV`

5. **Scan** dependency management:
   - [ ] Apps use `workspace:*` protocol for internal packages
   - [ ] External deps use `catalog:` protocol where possible
   - [ ] Catalogs defined in `pnpm-workspace.yaml`
   - [ ] `@your-org/*` import paths resolve

6. **Scan** bootstrap and pre-commit:
   - [ ] `scripts/bootstrap.sh` exists and is executable
   - [ ] Root `package.json` has `"bootstrap"` script
   - [ ] Bootstrap covers: install, docker (if applicable), db setup (if applicable)
   - [ ] Pre-commit captures staged files, restages after fix, validates with lint + typecheck

7. **Scan** CLAUDE.md (if exists):
   - [ ] Documents monorepo structure
   - [ ] Documents script conventions
   - [ ] Documents import conventions (`@your-org/*` paths)
   - [ ] Documents package consumption patterns

8. **Report findings** with severity:
   - **CRITICAL** - Missing non-negotiable packages, broken task pipeline, no catalogs
   - **WARNING** - Missing .prettierignore/.gitignore, no CLAUDE.md guidance, incomplete scripts
   - **INFO** - Missing optional config, style suggestions

---

## CLAUDE.md Guidance

When `/js-monorepo init` runs or when this skill is used on an existing repo, update the project's `CLAUDE.md` with monorepo-specific context. Add or update these sections:

```markdown
## Project Overview

- **Stack**: [describe apps - e.g., Next.js frontend + NestJS API]
- **Package Manager**: pnpm (workspace monorepo)
- **Build System**: Turborepo

## Repository Structure

[Include the actual monorepo structure with apps/ and packages/]

## Key Conventions

### Scripts

Standard scripts at root level (run via `pnpm <script>`):

| Script | Purpose |
|--------|---------|
| `pnpm dev` | Start all apps in dev mode |
| `pnpm build` | Build all packages (respects dependency graph) |
| `pnpm lint` | Lint all packages |
| `pnpm typecheck` | Type-check all packages |
| `pnpm check` | Full validation (format + lint + typecheck + build) |
| `pnpm fix` | Auto-fix formatting and lint issues |
| `pnpm test` | Run all tests |
| `pnpm bootstrap` | One-command setup for new developers |

### Imports

- Use `@your-org/contracts` for shared types and Zod schemas
- Use `@your-org/ui/components/ui/*` for shadcn primitives
- Use `@your-org/ui/components/patterns/*` for composed patterns
- Use `@your-org/ui/hooks/*` for shared hooks
- Use `@/` for app-internal absolute imports

### Packages

| Package | Purpose |
|---------|---------|
| `@your-org/contracts` | Shared types, Zod schemas, interfaces (domain-organized) |
| `@your-org/ui` | React components, hooks, patterns (fine-grained exports) |

### Adding Dependencies

- Internal packages: `"@your-org/contracts": "workspace:*"` in package.json
- External packages: Use `catalog:` protocol (versions defined in pnpm-workspace.yaml)
```

## Checklist

### For `/js-monorepo init`
- [ ] All root config files created (including .prettierignore, .gitignore)
- [ ] `contracts` and `ui` packages created with standardized scripts
- [ ] Bootstrap and pre-commit scripts created
- [ ] CLAUDE.md updated with monorepo conventions
- [ ] `pnpm install` succeeds
- [ ] `pnpm check` passes

### For `/js-monorepo add-package`
- [ ] Package directory and files created
- [ ] Correct type (source vs compiled)
- [ ] Standardized scripts included (lint, typecheck, validate, build/dev)
- [ ] tsconfig extends root
- [ ] Uses `catalog:` for external deps
- [ ] Consuming apps wired up
- [ ] Build passes

### For `/js-monorepo review`
- [ ] All config files scanned (including .prettierignore, .gitignore)
- [ ] Non-negotiable packages verified with standardized scripts
- [ ] Task pipeline validated (env, inputs, outputLogs)
- [ ] Dependency management checked (catalogs, workspace protocol)
- [ ] Pre-commit strategy confirmed
- [ ] CLAUDE.md has monorepo guidance (if exists)
- [ ] Report generated with severity levels

## Related Skills

- **`/react-ui`** - React component creation, extraction, patterns, review. Use for UI concerns (shadcn primitives, forms, themes).
- **`/nextjs-data`** - Next.js App Router data layer. Use for page creation, query layers, and SSR hydration.

---

## Reference Files

- [references/config-templates.md](references/config-templates.md) - Root config file templates (turbo, tsconfig, eslint, prettier, etc.)
- [references/scripts-templates.md](references/scripts-templates.md) - Scripts, package.json, pre-commit, and bootstrap templates
- [references/package-patterns.md](references/package-patterns.md) - Package structure, standardized scripts, and export patterns
- [references/shadcn-setup.md](references/shadcn-setup.md) - shadcn/ui initialization, components.json, and monorepo wiring
