The 'do not start a second dev server' line made me laugh because it's so obviously scar tissue. Every rule in this file is a story.
Index
Feed
Maintained by fern.dev · updated Aug 3, 2026
Server components by default, one blessed data-fetching pattern, and hard rules about 'use client'. This file exists because every one of those rules was violated by an agent first.
- `src/app/` — routes. Route groups: `(shop)`, `(account)`, `(admin)`.
- `src/components/` — shared UI. `src/components/ui/` is shadcn-generated: do not hand-edit, regenerate.
- `src/lib/` — server utilities, DB (Drizzle), auth. `src/lib/api/` — the ONLY place that talks to external services.
- `src/emails/` — react-email templates. Preview with `pnpm email:dev`, never test by sending.- Dev: `pnpm dev` (assume it is already running on :3000 — do NOT start a second one)
- Typecheck: `pnpm typecheck` — run after every batch of edits, it is fast
- Test: `pnpm test` (vitest) ; single file: `pnpm test src/lib/cart.test.ts`
- Lint+format: `pnpm check` (biome). Fix what it reports; do not disable rules.
- Install: `pnpm install --frozen-lockfile`. Never regenerate the lockfile to fix an error.CLAUDE.md
# CLAUDE.md — storefront
Next.js 15 (App Router) + TypeScript strict + Tailwind. pnpm ONLY.
## Map
- `src/app/` — routes. Route groups: `(shop)`, `(account)`, `(admin)`.
- `src/components/` — shared UI. `src/components/ui/` is shadcn-generated: do not hand-edit, regenerate.
- `src/lib/` — server utilities, DB (Drizzle), auth. `src/lib/api/` — the ONLY place that talks to external services.
- `src/emails/` — react-email templates. Preview with `pnpm email:dev`, never test by sending.
## Commands
- Dev: `pnpm dev` (assume it is already running on :3000 — do NOT start a second one)
- Typecheck: `pnpm typecheck` — run after every batch of edits, it is fast
- Test: `pnpm test` (vitest) ; single file: `pnpm test src/lib/cart.test.ts`
- Lint+format: `pnpm check` (biome). Fix what it reports; do not disable rules.
- Install: `pnpm install --frozen-lockfile`. Never regenerate the lockfile to fix an error.
## Server/client rules
- Components are Server Components by default. Add `'use client'` ONLY for state, effects, or event handlers — and put the directive in the smallest leaf component that needs it, not the page.
- Data fetching happens in Server Components or Route Handlers via `src/lib/api`. No fetch calls inside client components; no new SWR/react-query — we removed them on purpose.
- Mutations are Server Actions in `actions.ts` next to the route. Validate input with zod at the top of every action. Return `{ ok, error }` objects; never throw across the boundary.
- Never import from `src/lib/db` in a file with `'use client'`. The lint rule will catch it; do not work around the lint rule.
## Testing
- Pure logic in `src/lib`: vitest, colocated `*.test.ts`.
- Server Actions: test the zod schema + happy path + one auth-failure path.
- Do not write E2E tests unless asked. Do not delete or `.skip` existing tests — if one blocks you, stop and report it.
## Prohibited
- `next.config.ts`, `middleware.ts`, and anything under `drizzle/migrations/` are human-only files.
- No new dependencies without asking. No `any` — use `unknown` and narrow.
- Do not run `pnpm build` to 'verify' — it takes 6 minutes and CI does it. Typecheck is the local gate.
## Done means
1. `pnpm typecheck` and `pnpm check` clean.
2. Tests for changed logic pass; no test was weakened or skipped.
3. New client components justified in one line in the PR description ("why client: ...").
Added 'assume dev server is running' — agents kept spawning second dev servers and then debugging the port conflict they created.
Jul 16, 2026Big rewrite for Next 15. Server Action error-object convention added; removed the old getServerSideProps section.
May 31, 2026Banned pnpm build as a verification step — 6-minute builds were eating whole sessions.
May 3, 2026Running this config?
Sign in to add your report — every count here is backed by a named account.
- Components are Server Components by default. Add `'use client'` ONLY for state, effects, or event handlers — and put the directive in the smallest leaf component that needs it, not the page.
- Data fetching happens in Server Components or Route Handlers via `src/lib/api`. No fetch calls inside client components; no new SWR/react-query — we removed them on purpose.
- Mutations are Server Actions in `actions.ts` next to the route. Validate input with zod at the top of every action. Return `{ ok, error }` objects; never throw across the boundary.
- Never import from `src/lib/db` in a file with `'use client'`. The lint rule will catch it; do not work around the lint rule.- Pure logic in `src/lib`: vitest, colocated `*.test.ts`.
- Server Actions: test the zod schema + happy path + one auth-failure path.
- Do not write E2E tests unless asked. Do not delete or `.skip` existing tests — if one blocks you, stop and report it.- `next.config.ts`, `middleware.ts`, and anything under `drizzle/migrations/` are human-only files.
- No new dependencies without asking. No `any` — use `unknown` and narrow.
- Do not run `pnpm build` to 'verify' — it takes 6 minutes and CI does it. Typecheck is the local gate.1. `pnpm typecheck` and `pnpm check` clean.
2. Tests for changed logic pass; no test was weakened or skipped.
3. New client components justified in one line in the PR description ("why client: ...").Strong evidence gets promoted into the record above.
Sign in to join the discussion, vote, and verify fixes.
Related records
We adopted this minus the biome parts (still on eslint+prettier). One adaptation: our typecheck is slow (8k files), so 'after every batch of edits' became 'before declaring done' — otherwise the agent spent a third of the session waiting on tsc.