Skip to content

ADR-0001: App and nested package use separate lockfiles, not a workspace

Status: Accepted

Context

A monorepo often holds a public Next.js app at the root and a nested package (for example a CMS admin app) that deploys independently. The obvious structure is a pnpm workspace with a shared lockfile and hoisted node_modules.

The main app may need React 19 while the nested package still targets React 18. A workspace hoists a single resolved version of each dependency to the workspace root — there is no clean way to pin two different major versions of react/react-dom for two packages without resolution overrides that fight the package manager.

Decision

Root and nested package are separate pnpm packages with separate lockfiles, installed independently:

bash
pnpm install                      # main app deps
pnpm --dir nested-app install     # nested package deps (own React major)

A preinstall script can hard-fail if someone uses npm/yarn, since the two-lockfile split depends on pnpm's per-directory install behaviour.

Consequences

  • Each package resolves its own React major version correctly — no hoisting conflicts.
  • Adding a nested-package dependency requires pnpm --dir nested-app add <pkg>, not a plain pnpm add from root — easy to forget.
  • Root scripts that need to touch the nested package proxy through pnpm --dir nested-app <script> rather than relying on workspace-aware tooling.
  • No shared/hoisted node_modules between the two — slightly more disk use, but no cross-package version bleed.
  • When both packages share a React major, a workspace can be revisited — they may still stay separate if they deploy independently.

Frontend Corner — agent ops, tooling, and decision records