ADR-0001: Nx monorepo, pnpm workspaces
Status: Accepted Date: ~2026-01 (estimate; predates this doc) Context owner: Owner
Context
FitKit ships at least three runtime artifacts that share types and validation:
- A NestJS API (
apps/api). - A Next.js web app (
apps/web). - A standalone Vite admin app (
apps/admin).
Plus secondary surfaces: an Astro marketing site (apps/marketing) and an Astro per-org minisite app (apps/minisites). Future surfaces planned: a native mobile app, a WhatsApp bot.
Sharing TypeScript types, Zod schemas, and the Drizzle database client across these would either require publishing internal packages (yak-shaving) or a monorepo.
Decision
Use Nx to manage a single repository, with pnpm workspaces as the package manager. Two shared libraries:
libs/shared(@fitkit/shared) — Zod schemas + TypeScript types consumed by both API and frontends.libs/db(@fitkit/db) — Drizzle ORM schema definitions +createDbClientfactory.
Path aliases in tsconfig.base.json:
@fitkit/shared→libs/shared/src/index.ts@fitkit/db→libs/db/src/index.ts
Consequences
Positive
- Shared schemas are imported, not duplicated. Changing an API response shape immediately surfaces type errors in the web client.
- Nx affected-graph powers efficient CI: only projects touched by a PR re-run.
- One pnpm lockfile, one set of tooling configs, one source of truth.
Negative
- New engineers must learn Nx (the
nx <target> <project>invocation isn’t standard npm-workspace muscle memory). - A breaking change to
libs/sharedcan ripple through every app. We mitigate via the type system — there are no untyped boundaries. - Cross-project tasks are coupled in CI; one slow project slows the whole pipeline. Mitigation:
concurrency.cancel-in-progress, per-project timeouts.
Alternatives considered
- Separate repos with published internal packages. Higher overhead, slower iteration, and the org isn’t big enough to need the isolation.
- Turborepo. Comparable feature set; Nx was chosen for its richer plugin ecosystem (NestJS, Next.js, etc.) and the affected-graph being more capable at the time.