Brisket Local Development
Brisket is a Next.js 16 + React 19 app with Turbopack, tRPC, ConnectRPC, Clerk, Tailwind, and shadcn UI. Local development runs against a real or mocked sirloin instance.
Prerequisites
- Node 22+ (see CI:
NODE_VERSION: "22"in.github/workflows/brisket.yml). - pnpm 10.26.0 (
PNPM_VERSIONin the workflow). Install withcorepack enable && corepack prepare pnpm@10.26.0 --activate. - A running sirloin instance reachable at
SIRLOIN_URL(default: local docker stack viamake dev-up-d, or staging gRPC endpoint).
Setup
# from repo rootpnpm installcp apps/brisket/.env.example apps/brisket/.env.local# fill in secrets — see brisket-env.
pnpm --filter brisket devTODO(@marty): confirm 1Password vault item name for shared dev values.
pnpm dev runs next dev --turbopack on http://localhost:3000. The first request triggers an env-var validation pass via @t3-oss/env-nextjs; missing required vars throw a Zod aggregate error. Set SKIP_ENV_VALIDATION=1 to bypass only if you know what you’re doing.
Useful Scripts
From apps/brisket/package.json:
| Script | What it does |
|---|---|
pnpm --filter brisket dev | Turbopack dev server. |
pnpm --filter brisket build | Production build (next build --turbopack). |
pnpm --filter brisket start | Run the production build locally. |
pnpm --filter brisket preview | build && start. |
pnpm --filter brisket lint / lint:fix | ESLint (max-warnings 0). |
pnpm --filter brisket typecheck | tsc --noEmit. |
pnpm --filter brisket test | Vitest. |
pnpm --filter brisket check | lint && typecheck. |
pnpm --filter brisket format:check / format:write | Prettier. |
Architecture Cheat-Sheet
apps/brisket/src/ app/ # App Router (pages, layouts, route handlers) api/ # /api/health, /api/trpc/[trpc], /api/webhook/clerk components/ # Reusable React components (shadcn-style) features/ # Feature modules (checkout, character page, etc.) server/ api/ root.ts # tRPC appRouter trpc.ts # context, middlewares (tracing, metrics) sirloin-api.ts # ConnectRPC clients for SirloinService + BillingService grpc-headers.ts # Header builders / call-option helpers routers/*.ts # tRPC routers hooks/ # Custom hooks lib/ # logger, posthog, helper-functions, metrics trpc/ # client setup styles/ # Tailwind globals middleware.ts # Clerk middleware + open-redirect guard env.js # @t3-oss/env-nextjs schema stage.js # BRISKET_STAGE resolutionpkg/ # Shared packages, including generated proto clients (pkg/sirloin/v5/*)Tailwind + shadcn
- Tailwind v3, configured per-app (
tailwind.config.*). Utility class lookup is fastest in editors with the Tailwind IntelliSense extension. - shadcn UI components live in
src/components/ui/and are vendored — edit them in place. Re-running the shadcn CLI overwrites the local copy, so prefer manual edits and PR review. - Radix primitives are imported individually (
@radix-ui/react-*) and composed into shadcn wrappers. - Framer Motion for animations; Jotai for client state. Avoid mixing global state for things tRPC + React Query already cache.
Turbopack Quirks
next dev --turbopack and next build --turbopack are both enabled. Things that bit us:
- Some webpack-only plugins (legacy
next.config.jsentries) silently no-op under Turbopack. Verify behavior in dev and build. - Hot reload occasionally drops a state slice on heavy edits; full reload (
Rin the terminal) fixes it. - After dependency bumps, clear
.next/:rm -rf apps/brisket/.nextbefore re-running dev to avoid stale module graphs. - Source maps in dev are eager — large files can add a perceptible compile delay on first hit.
Auth in Dev
@clerk/nextjs requires NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY + CLERK_SECRET_KEY to be from the same Clerk instance. The dev Clerk app accepts arbitrary email magic links for sign-in. The webhook (/api/webhook/clerk) only matters if you need to test PostHog account_created / logged_in capture; otherwise skip.
For local middleware testing, public routes are: /sign-in, /sign-up, /waitlist, /api/health, /api/webhook/clerk, /forgot-password, /verification, /.well-known. Everything else triggers auth.protect().
Mocking the Backend
Brisket has no built-in mock layer. Three viable strategies:
- Run sirloin locally —
make dev-up-dfrom the repo root brings up the Docker stack including sirloin and round. Inside the compose network brisket talks to sirloin atSIRLOIN_URL=http://sirloin:50051(gRPC; seedocker-compose.yml). When running brisket outside Docker against the compose stack, setSIRLOIN_URL=http://localhost:50051. - Point at staging sirloin — set
SIRLOIN_URL=https://sirloin-staging.<host>and use staging Clerk/Chargebee credentials. Lowest friction; do not run destructive flows against staging. - Stub at the tRPC layer — for unit tests,
apps/brisket/src/server/api/tests/shows the pattern (mock the Connect client returned bygetSirloinApi/getBillingApi). For UI work, mock the React Query layer using@tanstack/react-query’s testing helpers.
Strapi (FAQ) and Intercom soft-fail when their env vars are absent. Chargebee/Stripe/Turnstile widgets render in degraded modes when their public keys are blank — fine for non-checkout work but checkout flows need real keys.
Conventions (from apps/brisket/CLAUDE.md)
- Filename: kebab-case for files, PascalCase for component exports.
- Component structure:
Component.tsx+ colocatedComponent.test.tsx+Component.stories.tsx(where applicable). - Tests run with Vitest; UI with Testing Library.
- ESLint and Prettier are non-negotiable; run
pnpm checkbefore pushing.
Common Pitfalls
- Editing a
NEXT_PUBLIC_*value requires a dev-server restart; values are baked at startup. - Importing
~/envin a client component is fine — the t3 client schema is the safe surface. Importing server-only fields in client code fails the build. - React 19 + pnpm overrides: do not bump React without checking the
pnpm.overridesinpackage.json. - Turbopack dev cannot use the
next/scriptpreload hints the way webpack did — verify third-party scripts (Chargebee, Cloudflare) load correctly after changes.
Anchors
- Env:
brisket-env· API:brisket-api· Errors:brisket-errors· Runbook:brisket-runbook· On-Call:brisket-oncall. - Standards:
standards/auth-model,standards/security-model. Operations:operations/testing-strategy.