← Stacks

Next.js Full-Stack

Platform: web | typescript

name: Next.js Full-Stack
platform: web
language: typescript
framework: [email protected]
ui_framework: [email protected]
styling: [email protected]
component_library: shadcn-ui
database: supabase (PostgreSQL)
orm: drizzle-orm
auth: shared-auth (@shared/auth + Supabase Auth)
realtime: supabase_realtime
payments: stripe + @stripe/stripe-js + @stripe/react-stripe-js
validation: zod@4
i18n: next-intl
package_manager: pnpm
linter: eslint (flat config v9, typescript-eslint, eslint-plugin-react, @next/eslint-plugin-next)
formatter: prettier
type_checker: tsc --noEmit (strict mode)
dead_code: knip (find unused files, exports, dependencies)
testing: vitest + @testing-library/react + @testing-library/jest-dom
pre_commit: husky + lint-staged (eslint + prettier + tsc)
state_management:
  default: "React useState + useContext (Server Components reduce need for client state)"
  when_needed: "Add ONLY when 3+ components share mutable state that can't be in Server Component or URL params"
  zustand:
    package: "zustand (3KB, zero boilerplate)"
    install: "pnpm add zustand"
    when: "Global app state (auth, theme, sidebar, notifications), persist to localStorage, devtools, team projects"
    api: "create<Store>()(set => ({...})), useStore(s => s.field) — selector prevents re-renders"
    middleware: "persist (localStorage), devtools, immer (immutable updates)"
  jotai:
    package: "jotai (8KB, atomic model)"
    install: "pnpm add jotai"
    when: "Many independent state pieces (filters, toggles), fine-grained reactivity (data grids, kanban), derived state chains"
    api: "atom(default), atom(get => derived), useAtom(myAtom) — each atom = independent re-render"
  recommendation: |
    MVP / simple → React state (useState, useContext, URL params)
    Global UI state (sidebar, theme, auth) → Zustand (one store, simpler mental model)
    Data-heavy dashboards (many filters, derived state) → Jotai (fewer re-renders, atomic)
    Both from same author (pmndrs), both TypeScript, both React 19. Can use together.
storybook:
  when_to_use: "15+ components, shared UI library (@repo/ui), team 2+ devs, need visual docs"
  skip_when: "Solo MVP, < 15 components, mostly shadcn defaults"
  setup: "npx storybook@latest init --builder vite && pnpm add -D @chromatic-com/storybook chromatic"
  key_packages:
    - "storybook@10 (component explorer, docs, testing)"
    - "@chromatic-com/storybook (visual regression addon)"
    - "chromatic (CI service — free: 5000 snapshots/month, 4 browsers in parallel)"
  chromatic_ci: "chromaui/action@latest in GitHub Actions, needs CHROMATIC_PROJECT_TOKEN secret"
  workflow: "write story → push → screenshots in Chrome/Firefox/Safari/Edge → PR badge → review pixel diffs → approve"
key_packages:
  - next
  - react
  - "@supabase/ssr"
  - "@shared/auth (shared auth)"
  - "zod (validation — import from zod/v4)"
  - "next-intl (i18n)"
  - "stripe + @stripe/stripe-js (payments)"
  - "drizzle-orm + drizzle-kit (ORM, migrations)"
  - react-hook-form
  - "shadcn (CLI) + radix-ui"
  - "react-email + resend (email) | emailmd (lightweight markdown-to-email alternative)"
  - recharts (charts)
  - tailwindcss
  - eslint + typescript-eslint + prettier (code quality)
  - knip (find unused files, exports, deps  run periodically)
  - "zustand OR jotai (client state — only when needed, see state_management)"
  - "storybook + chromatic (component docs + visual testing — for larger projects)"
deploy: vercel | cloudflare_pages (git push  auto-deploy)
deploy_cli:
  - "vercel (local preview, env vars, promote)"
  - "supabase (migrations, db reset, edge functions, secrets)"
infra: sst (sst.config.ts)  Tier 1
ci_cd: github_actions
monitoring: posthog (analytics + errors, EU hosting)
logs:
  vercel: "vercel logs --output=short 2>&1 | tail -50"
  vercel_functions: "vercel logs --output=short --scope=functions 2>&1 | tail -50"
  supabase: "supabase functions logs --scroll"
  posthog: "PostHog dashboard → Error tracking"
  local_build: "pnpm build 2>&1 | tail -50"
dev_server:
  command: "pnpm dev"
  port: 3000
  ready_url: "http://localhost:3000"
visual_testing:
  type: browser
  checks:
    - "Navigate to localhost:3000, verify page loads without console errors"
    - "Check for hydration mismatches in browser console"
    - "Verify responsive layout at mobile viewport (375px)"
architecture: app_router_rsc
monorepo:
  tool: turborepo
  when_to_use: |
    YES: 2+ apps with different auth/layout/audience (landing + app + admin), web + mobile (Expo)
    NO: single Next.js with route groups, MVP/prototype, same auth everywhere
    RULE: same auth + same deploy = route groups. Different auth + independent deploy = turborepo.
  workspace_structure: |
    apps/ (web, admin, docs, api)
    packages/ (@repo/ui, @repo/db, @repo/auth, @repo/config, @repo/email, @repo/validators)
  config_files:
    - "turbo.json (tasks: build, dev, lint, check-types)"
    - "pnpm-workspace.yaml (packages: apps/*, packages/*)"
  key_packages:
    - turbo
  reference_template: "next-forge (vercel/next-forge)"
  notes: |
    - pnpm --filter @repo/web dev — run single app
    - turbo run build — parallel builds with caching
    - Remote caching: npx turbo login && npx turbo link (free on Vercel)
    - Internal packages: use "exports" field, no build step for TS
    - Vercel: set Root Directory per app in project settings
notes: |
  - Drizzle ORM for database queries and migrations (not raw SQL)
  - Use Server Components by default
  - Zod 4 for all validation (forms, API) — import from "zod/v4"
  - Supabase SSR for auth, shared-auth for shared login
  - next-intl for i18n: messages/en.json + messages/ru.json
  - Stripe Checkout + Customer Portal for subscriptions
  - pnpm as package manager (not npm/yarn)
  - ESLint flat config (eslint.config.mjs) + Prettier
  - tsc --noEmit for type-checking (strict mode in tsconfig.json)
  - knip for dead code detection (unused exports, files, dependencies)
  - Husky + lint-staged for pre-commit (eslint, prettier, tsc --noEmit)
  - Vitest for unit/integration tests, @testing-library/react for components
  - Deploy via git push (main → production, PR → preview)
  - State management: React state by default. Zustand for global UI, Jotai for data-heavy dashboards.
  - Storybook + Chromatic: for 15+ components or shared UI library. Free 5000 snapshots/month.
  - Agent-readable (content/blog sites): add app/llms.txt/route.ts + MDX content as raw markdown API + Content-Signal header
  - If behind Cloudflare: enable Markdown for Agents in dashboard (auto content negotiation)
Sources

Related