Bonjegs has three independently deployable React + Vite apps (customer, admin, rider) and one shared Node + Express + Prisma backend. They share types, a few utility packages, and almost nothing else. Each app deploys on its own schedule.
I used npm workspaces. Not Turborepo, not Nx, not pnpm — just plain workspaces. The reason: the team is small (currently me), the toolchain churn cost of the heavier monorepo tools was not worth the marginal speed.
What lives where
apps/customer,apps/admin,apps/rider— each a Vite + React + TypeScript app.apps/api— Node + Express + Prisma + Socket.IO.packages/types— TypeScript types shared between API and apps.packages/utils— small pure utilities (formatters, validators).
The discipline: nothing in packages/ imports from apps/. Ever. That single rule keeps the dependency graph clean.
