0001 — pnpm monorepo with apps/* and packages/*
- Status: accepted
- Date: 2026-05-06
- Deciders: Derek
Context
Ark is one codebase serving N tenants across three deployable surfaces (public site, admin portal, API). The codebase will share substantial logic between surfaces (auth, permissions, CMS reads, types, config schemas). Cross-cutting changes — most notably “add organization_id to every table and propagate through every layer” — must land atomically.
We’re also optimizing for AI agents to do non-trivial work. Agents are most productive when they can see the entire system in one tree without fetching from N remotes.
Decision
A single git repository with pnpm workspaces. Layout: apps/{api,admin,site} (deployable surfaces) + packages/* (shared libraries) + supabase/migrations (CLI-managed migrations, see ADR 0012) + tenants/* (per-tenant config) + docs/.
pnpm specifically: workspaces are first-class, install is fast, --filter semantics are clean for CI partitioning, and the lockfile reliably reflects what’s installed (npm’s lockfile drift has burned us before in internalize).
Consequences
Easier:
- Schema migrations + package + app changes ship in one PR
- Agents read the whole system without cross-repo navigation
- Type changes propagate at compile time
- Single CI pipeline; one place to look for failures
- Refactors that touch every layer (renames, signature changes) are mechanical
Harder:
- CI must be smart about which packages to test on which changes (mitigated by pnpm
--filter ...) - Per-tenant private content (logos, custom themes) needs a story — it lives in
tenants/<slug>/with.gitignorefor sensitive material, or in a separate private repo per tenant - Build artifacts must be carefully scoped per app
Revisit if: install times exceed 90s on developer machines, or if the consulting agency wants to fork-and-modify ark for one of their clients (then we need a “ship a snapshot” story).
Alternatives considered
- Multi-repo with npm-published packages. Cleanest dependency boundaries, but cross-cutting changes become 5-PR coordination dances. Not viable for one engineer + AI agents.
- Yarn workspaces / npm workspaces. Both technically work; pnpm wins on speed and
--filterergonomics. Internalize uses npm; we don’t carry that forward because pnpm is strictly better for the workspace use case. - Nx / Turborepo. Good build orchestration tools; both add a layer of “magic” we don’t yet need at this scale. We can adopt Turbo later if pnpm-only build perf becomes a bottleneck.