ADR-0001: Monorepo with pnpm workspaces
ADR-0001: Monorepo with pnpm workspaces
Section titled “ADR-0001: Monorepo with pnpm workspaces”Status: Accepted Date: 2026-04-20
Context
Section titled “Context”The platform will ship as a Platform Core package, multiple Business Pack packages, and one or more deployable apps. They share types, need coordinated versioning, and benefit from a single lockfile. We need a monorepo tool.
We also want strict dependency hygiene — no phantom dependencies where a package imports something it didn’t declare but that happens to be hoisted to the root node_modules.
Decision
Section titled “Decision”Use pnpm 10 workspaces as the monorepo tool. Configure hoist=false and node-linker=isolated in .npmrc so each package must declare every import it uses. No Turborepo, Nx, or Rush yet.
Consequences
Section titled “Consequences”- Single lockfile, fast installs thanks to pnpm’s content-addressable store.
- Phantom dependencies fail at import time — caught early.
- Each package must declare its own devDependencies (e.g.,
typescript), including when we’d otherwise inherit from the root. - If we grow to 3+ packages with slow cross-package builds, we layer on Turborepo. Cheap to add later.
- We’re locked into pnpm’s workspace-protocol (
workspace:*) semantics for intra-repo deps. Standard, but a switch away from pnpm is non-trivial.
Alternatives considered
Section titled “Alternatives considered”- npm workspaces: slower installs; no equivalent to pnpm’s strict isolation; no pnpm-catalog feature.
- Yarn workspaces: similar to pnpm on the surface. We’d pick pnpm over Yarn specifically for disk usage and the
hoist=falseguarantee. - Bun workspaces: fast and appealing, but tooling around Cloudflare Workers and TypeScript strict mode is less mature; we’d be early adopters on several fronts simultaneously.
- Turborepo / Nx now: premature. Our builds are seconds, not minutes. Adopt when we feel the pain.
- No monorepo (multi-repo): rejected — forces manual version coordination and makes shared-type refactors painful.