Commands And Scripts

Common pnpm tasks across the monorepo.

The kit is a pnpm + Turborepo workspace. Most commands run from the repo root and Turbo dispatches them to the right package; a few live only inside the package that owns them. This page lists both.

Most-Used

Nine commands cover daily work.

CommandDoes
pnpm devStart the product app on port 3000
pnpm docs:devStart the docs site on port 3001
pnpm test:runSingle-pass unit tests with coverage gates
pnpm test:integrationPostgres-backed integration tests
pnpm test:e2ePlaywright E2E suite
pnpm db:migrate:devApply pending migrations to the dev database
pnpm setup:initAsk which features to turn on, merge apps/web/.env, then offer Postgres, migrate, and seed
pnpm setup:doctorDiagnose missing or invalid env config
pnpm formatPrettier write across the workspace

Development

CommandDoesWhere
pnpm devNext.js dev on :3000 (turbo dev --filter=@syntaxkit/web)Root
pnpm docs:devFumadocs site on :3001Root
pnpm email:devReact Email preview serverRoot
pnpm --filter @syntaxkit/<package> devSame, but explicit (rarely needed)Root

Build

CommandDoes
pnpm buildturbo build across the workspace (web + docs + packages)
pnpm --filter @syntaxkit/web buildBuild only the product app
pnpm --filter @syntaxkit/docs buildBuild only the docs site

build declares dependsOn: ["^build", "^db:generate"], so the Prisma client always regenerates first. You never need pnpm db:generate by hand before a build.

Quality

CommandDoes
pnpm lintESLint across every package
pnpm check-typesTypeScript check across every package
pnpm formatPrettier write across the workspace
pnpm format:checkPrettier check (CI-friendly; non-zero exit on drift)
pnpm docs:lint-linksVerify internal links across the docs MDX
pnpm deploy:check-build-argsDrift-check NEXT_PUBLIC_* build args across configs

lint and check-types are Turbo-cached: an unchanged graph is a no-op (FULL TURBO, done in milliseconds).

Billing

Both scripts read BILLING_PROVIDER (default stripe) from the shell and apps/web/.env and act on the active provider only. See Billing.

CommandDoes
pnpm billing:check-pricesCompare each declared catalog price with its live Stripe Price, Polar Product, or Creem product. Stripe and Polar compare amount, currency, and archived state (interval and trial for Polar). Creem compares amount, currency, and interval; Creem product prices are integer cents and the catalog amount is major units. Skips cleanly when the active provider is not configured or only placeholders are set. Exits non-zero on drift.
pnpm billing:check-prices --strictSame, and promote Stripe interval mismatches from warnings to failures (equivalent to BILLING_PRICE_SYNC_STRICT_INTERVAL=1). No effect for Polar, which has one interval per product.
pnpm billing:reconcileRe-fetch every non-terminal subscription owned by the active provider and heal drift through the canonical recency-guarded write; a subscription the provider no longer knows is marked canceled. Requires DATABASE_URL and the provider's credentials.
pnpm billing:reconcile --dry-runReport drift without writing anything.

Tests

Four tiers, each with its own command and file convention. See Testing for the full layering story.

TierCommandWhat runsFile pattern
Unit (watch)pnpm testVitest watch in every package*.test.ts(x) co-located
Unitpnpm test:runSingle Vitest run with coverage gates*.test.ts(x) co-located
Unit + coveragepnpm test:coverageSame plus per-package thresholdssame
Integrationpnpm test:integrationVitest with real Postgres (loads .env.test)*.integration.test.ts
Live Stripepnpm test:stripeVitest against Stripe test-mode; gated on RUN_STRIPE_LIVE=1*.live.test.ts
Live PolarRUN_POLAR_LIVE=1 POLAR_SERVER=sandbox pnpm --filter @syntaxkit/payments test:liveVitest against the Polar sandbox; skipped unless the sandbox token and POLAR_PRODUCT_ID_PRO_MONTHLY are setpackages/payments/src/polar/*.live.test.ts
E2Epnpm test:e2ePlaywright + Chromiumapps/web/e2e/*.spec.ts
E2E (UI mode)pnpm test:e2e:uiPlaywright UI for time-travel debuggingsame

test:integration, test:stripe, and test:e2e set cache: false. They hit live infra (Postgres, Stripe, Polar, or Creem, Chromium), so every invocation actually runs. The .next-test build they run against is the cached test:e2e:build task, so an unchanged app skips next build. There is no root test:polar script; the Polar live test runs through the payments package's test:live task with the env vars above.

Database

Every db:* task lives in packages/database and is proxied at the root, so pnpm db:<task> works from anywhere. See Database for the workflows.

CommandDoes
pnpm db:generateGenerate the typed Prisma client
pnpm db:migrate:devCreate and apply a dev migration (destructive on drift, dev only)
pnpm db:migrate:deployApply migrations non-interactively (production-safe)
pnpm db:migrate:statusCheck whether the DB matches prisma/migrations/
pnpm db:pushPush schema changes without a migration (prototype only)
pnpm db:test:pushdb:push against the test database (.env.test)
pnpm db:studioOpen Prisma Studio
pnpm db:seedRun the seed dispatcher (defaults to bootstrap mode)
pnpm db:seed:bootstrapEmpty DB; first sign-up creates the personal org
pnpm db:seed:demoSample orgs and an admin (admin@demo.syntaxkit.com / password123)
pnpm db:seed:testTest fixtures (4 deterministic users for Playwright)
pnpm db:resetDrop, recreate, and migrate (no seed)
pnpm db:reset:demoDrop, recreate, migrate, seed demo data
pnpm db:validateValidate the Prisma schema

Setup, Tooling, And Deploy

CommandDoes
pnpm setup:initInteractive first-run setup. Merges apps/web/.env, runs the doctor, then optionally starts Postgres, applies migrations, and loads demo seed. No flags. Does not reset the database. Named setup:init because pnpm setup is pnpm's own command.
pnpm setup:doctorDiagnose env file, optional integrations (including the active billing provider and whether live subscriptions belong to it), and DB reachability
pnpm setup:testTypecheck and unit-test pnpm setup:init. Runs on pre-push.
pnpm auth:generateRegenerate auth.generated.prisma from Better Auth config
pnpm admin:bootstrap --email <email>Promote a user to platform admin (one-shot, only when no admin exists)
pnpm deploy:check-build-argsDrift-check NEXT_PUBLIC_* across Dockerfile, compose, fly.toml, render.yaml, and the GHA workflow
pnpm cleanRemove all node_modules, .next, .turbo, dist, coverage, .source (full reset)
pnpm --filter @syntaxkit/docs diagrams:buildRe-render Mermaid diagrams to SVG

Per-Package Tasks

Anything you run from the root also runs inside its package: the root scripts just proxy via pnpm --filter or turbo.

Every package follows the same pattern:

Command (run inside a package)Does
pnpm testVitest watch mode
pnpm test:runVitest single run
pnpm test:coverageVitest run with coverage gates
pnpm linteslint .
pnpm check-typestsc --noEmit (tsc -b for shared and api, which emit declarations)

Plus the per-package extras:

PackageExtra commands
apps/webdev, build, start, test:live, test:e2e, test:e2e:ui
apps/docsdev, build, start, lint:links, diagrams:build
packages/apitest:integration, test:live
packages/authtest:integration
packages/databaseevery db:* (canonical home; root proxies here)
packages/emailpreview (React Email preview server)
packages/paymentstest:live

packages/i18n, ui, typescript-config, and eslint-config only define lint and check-types, no tests yet.

Turbo Caching

lint, check-types, build, test:run, and test:coverage are cached. The cache key includes the dependency graph plus each task's env allowlist, so a Stripe, Polar, or Creem credential change busts only the live-test cache, not the build cache. Tasks that hit live infra (dev, test, every db:*, test:integration, test:live, test:e2e) set cache: false and re-run every time. See Working With The Codebase for the full pipeline.

Where To Go Next

On this page