ZTS Docs

Monorepo layout

How the Zero To Shipped pnpm + Turborepo workspace is organized.

Zero To Shipped is a pnpm workspace orchestrated with Turborepo. Application code lives under apps/, shared libraries under packages/, and root scripts delegate to the right package.

Top-level layout

zerotoshipped/
├── apps/
│   ├── web/          # Next.js app (port 3000) — UI, API routes, MCP/REST handlers
│   ├── mobile/       # Expo React Native app (@zts/mobile)
│   └── extension/    # WXT browser extension (@zts/extension)
├── packages/
│   ├── trpc/         # Shared tRPC router, procedures, React client helpers
│   ├── auth/         # Better Auth config, session policy, API keys
│   ├── db/           # Prisma schema, migrations, client
│   ├── env/          # Zod-validated environment variables
│   ├── shared/       # Shared types, payment plans, utilities
│   ├── email/        # Email transports and templates
│   ├── sdk/          # TypeScript SDK generated from OpenAPI (integrations)
│   └── cli/          # `zts` CLI for REST from the terminal
├── turbo.json
├── pnpm-workspace.yaml
└── package.json      # Root scripts (dev, build, db:*)

Apps

AppPackagePurpose
WebwebPrimary product: App Router UI, /api/trpc, /api/rest, /api/mcp, auth
Mobile@zts/mobileExpo app using @zts/trpc and Better Auth Expo plugin
Extension@zts/extensionChrome extension sharing session + tRPC with the web app

Packages

PackageImportRole
@zts/trpc@zts/trpc/server/api/rootSingle API surface for web, mobile, extension, REST, and MCP
@zts/auth@zts/auth, @zts/auth/clientBetter Auth server + client
@zts/db@zts/dbPrisma client and extensions
@zts/env@zts/env, @zts/env/clientServer and client env validation
@zts/shared@zts/shared/...Cross-app config and types
@zts/email@zts/emailOutbound email
@zts/sdk@zts/sdkREST client from OpenAPI (see Public API)
@zts/clizts binaryTerminal access to REST (see Public API)

Common commands

From the repository root (with .env at the root — loaded via scripts/with-root-env.mjs for web):

pnpm install
pnpm dev              # web on :3000 (turbo --filter=web)
pnpm dev:mobile       # Expo dev server
pnpm dev:extension    # WXT extension dev build
pnpm build            # all workspace builds (turbo)
pnpm db:migrate       # Prisma migrate (packages/db)
pnpm db:studio
pnpm typecheck

Filter a single app or package:

pnpm --filter web run build
pnpm --filter @zts/mobile run ios
pnpm --filter @zts/trpc run typecheck

Where the API lives

  • tRPC procedures and router: packages/trpc/src/
  • Next.js route handlers (wire-up only): apps/web/src/app/api/
    • trpc/[trpc]/route.ts/api/trpc
    • rest/[...path]/route.ts/api/rest
    • openapi.json/route.ts/api/openapi.json
    • [transport]/route.ts/api/mcp

First-party clients (web RSC, mobile, extension) call tRPC. Integrations, scripts, and agents use REST, SDK, CLI, or MCP as described in Public API.

Turborepo

turbo.json defines dev, build, typecheck, and test with shared globalEnv so cached tasks see the same env keys as production builds. Root pnpm dev runs turbo dev --filter=web; mobile and extension use dedicated root scripts because they are long-running dev processes outside that filter.

On this page