# Next.js

React interfaces with server rendering, routes and application logic.

React · Next.js · PostgreSQL · Drizzle

[Complete guide (Markdown)](/stacks/typescript-next-node/guide.md) · [Structured record (JSON)](/stacks/typescript-next-node/record.json)

Original source review: 2026-10-10. Core guidance rechecked: 2026-10-13. [Check scope](/research-freshness.json). Dependency combinations and setup need project-specific qualification.

## Use cases

- Authenticated web products

- Server-rendered React interfaces

- Browser applications with owned APIs and relational data

## Choose it when

- Shared TypeScript contracts and React UI are useful

- Server rendering or a web-facing backend is required

- Team accepts explicit server/client and cache boundaries

## Consider another path when

- Only static editorial content is required

- Existing API already owns all backend responsibilities and SSR is unnecessary

- Native mobile or desktop UI is the deliverable

## Working practices

- Keep database imports and secrets in server-only modules. Treat Server Actions and route handlers as authenticated entry points.

- Validate external input with schemas and authorize access close to the data. A page redirect is not an access-control boundary.

- Commit reviewed SQL migrations. Generate the Better Auth schema into Drizzle's migration path.

- Test async Server Components through browser journeys. Exercise logged-out and two-tenant cases, including cached pages.

## Tools by job

### runtime and dependency management: Node LTS + npm lockfile

LTS production policy and reproducible dependency install

Pin resolved runtime/dependencies; latest is a scaffold-time lookup, not a CI dependency strategy

- [https://nodejs.org/en/about/previous-releases](https://nodejs.org/en/about/previous-releases)

- [https://nextjs.org/docs/app/getting-started/installation](https://nextjs.org/docs/app/getting-started/installation)

### application framework: Next.js App Router + React + strict TypeScript

Full-stack React with version-matched agent documentation

TanStack Start official homepage labelled RC at review; web UI is not native UI; framework does not supply business correctness

- [https://nextjs.org/docs/app/getting-started/installation](https://nextjs.org/docs/app/getting-started/installation)

- [https://nextjs.org/docs/app/guides/ai-agents](https://nextjs.org/docs/app/guides/ai-agents)

- [https://vite.dev/guide/](https://vite.dev/guide/)

- [https://tanstack.com/start/latest](https://tanstack.com/start/latest)

- [https://docs.astro.build/en/guides/typescript/](https://docs.astro.build/en/guides/typescript/)

### project instructions: README navigation + generated version-matched agent guidance

Keep repository instructions and installed framework documentation discoverable

Honor existing instruction ownership. Optional README-only policy: scaffold with --no-agents-md and set agentRules:false before next dev; neither is required by this stack.

- [https://nextjs.org/docs/app/api-reference/cli/create-next-app](https://nextjs.org/docs/app/api-reference/cli/create-next-app)

- [https://nextjs.org/docs/app/api-reference/config/next-config-js/agentRules](https://nextjs.org/docs/app/api-reference/config/next-config-js/agentRules)

- [https://nextjs.org/docs/app/guides/ai-agents](https://nextjs.org/docs/app/guides/ai-agents)

### Agent runtime inspection: Next.js development MCP endpoint with real browser inspection

Combine version-matched framework context, compilation errors, routes and runtime logs with the actual rendered application.

Development only. Inspect the installed Next.js and next-devtools-mcp versions before configuring tools. Some runtime inspection requires an open browser session; Turbopack compilation tools have their own constraints. Framework tools do not replace authorization tests or real browser verification. Do not install optional skills or enable automatic upgrades merely to read this reference.

- [https://nextjs.org/docs/app/guides/mcp](https://nextjs.org/docs/app/guides/mcp)

- [https://nextjs.org/docs/app/guides/ai-agents](https://nextjs.org/docs/app/guides/ai-agents)

### validation: Zod

Runtime schemas with inferred TypeScript types

Validate requests/environment/external results; shape checks do not establish permission or truth

- [https://zod.dev/](https://zod.dev/)

### database and migrations: PostgreSQL + Drizzle + reviewed SQL migrations

Typed schema with inspectable SQL history

Configure schema paths and target environment; apply migration once; rehearse fresh DB and forward compatibility

- [https://orm.drizzle.team/docs/get-started-postgresql](https://orm.drizzle.team/docs/get-started-postgresql)

- [https://orm.drizzle.team/docs/migrations](https://orm.drizzle.team/docs/migrations)

### identity: Better Auth + Drizzle PostgreSQL adapter

Integrated session/provider support without designing password/session primitives

Auth schema generate then Drizzle migrations; direct Better Auth migrate is Kysely-only; configure origin/secrets/recovery; authorize near data

- [https://better-auth.com/docs/installation](https://better-auth.com/docs/installation)

- [https://better-auth.com/docs/integrations/next](https://better-auth.com/docs/integrations/next)

- [https://nextjs.org/docs/app/guides/authentication](https://nextjs.org/docs/app/guides/authentication)

### background work: Inngest durable workflows when required

Checkpointed steps, retries and waits

Idempotent effects and authorized approvals required; use outbox for DB/event consistency; avoid beta durable endpoints as default

- [https://www.inngest.com/docs/durable-execution](https://www.inngest.com/docs/durable-execution)

- [https://www.inngest.com/docs/durable-execution/quick-start](https://www.inngest.com/docs/durable-execution/quick-start)

- [https://www.inngest.com/docs/durable-execution/concepts](https://www.inngest.com/docs/durable-execution/concepts)

### Static typing: TypeScript strict

Independent deterministic checks for generated edits

Next build does not run lint; never ignore build/type errors to satisfy a check

- [https://nextjs.org/docs/app/getting-started/installation](https://nextjs.org/docs/app/getting-started/installation)

- [https://nextjs.org/docs/app/api-reference/cli/next](https://nextjs.org/docs/app/api-reference/cli/next)

### Linting: ESLint

Independent deterministic checks for generated edits

Next build does not run lint; never ignore build/type errors to satisfy a check

- [https://nextjs.org/docs/app/getting-started/installation](https://nextjs.org/docs/app/getting-started/installation)

- [https://nextjs.org/docs/app/api-reference/cli/next](https://nextjs.org/docs/app/api-reference/cli/next)

### Domain tests: Vitest

Run isolated domain behavior checks with a configured test environment

Install/configure Vitest and DOM environment for UI tests. Next async Server Components require browser/integration coverage instead.

- [https://vitest.dev/guide/](https://vitest.dev/guide/)

### Component tests: React Testing Library

Test rendered components through user-visible DOM behavior

Install @testing-library/react and its @testing-library/dom peer; configure the test runner/DOM environment. This is a component utility library, not a test runner.

- [https://testing-library.com/docs/react-testing-library/intro/](https://testing-library.com/docs/react-testing-library/intro/)

### Browser tests: Playwright

Exercise critical journeys in actual browser engines

Install @playwright/test and matching browsers; configure an isolated test server/data and test session expiry, routing and authorization failures.

- [https://playwright.dev/docs/intro](https://playwright.dev/docs/intro)

### deploy: Project-selected Node or Docker host

Documented full Next feature support with Node/Docker

Adapters vary; verify chosen host, secrets, DB connections, sessions, migrations and restore; Cloudflare needs separate compatibility review

- [https://nextjs.org/docs/app/getting-started/deploying](https://nextjs.org/docs/app/getting-started/deploying)

### Server state cache: TanStack Query for client-owned remote state

Queries, mutations and invalidation support interactive API screens

Install @tanstack/react-query and provide QueryClient. Define tenant-aware keys, staleTime/retry policy and clear session data on sign-out; in Next prefer server loading until a client cache has a job.

- [https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults](https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults)

### Forms: React Hook Form for complex client forms

Separates client form state and validation from page components

Install react-hook-form only where needed; wire existing runtime schemas deliberately. Render accessible labels/errors; validate and authorize submissions on the server.

- [https://github.com/react-hook-form/react-hook-form](https://github.com/react-hook-form/react-hook-form)

### Styling: Tailwind CSS when utility styling fits the project

Reusable styling without a runtime component dependency

For Vite install tailwindcss and @tailwindcss/vite, add the plugin and CSS import. Use the framework-specific installation path for Next; retain established styles when present.

- [https://tailwindcss.com/docs/installation/using-vite](https://tailwindcss.com/docs/installation/using-vite)

### Accessible UI primitives: Radix Primitives for complex controls

Provides focus and keyboard behavior for common interaction patterns

Install only used components. Authors still supply names, contrast and meaningful composition; verify keyboard and assistive-technology behavior.

- [https://www.radix-ui.com/primitives/docs/overview/accessibility](https://www.radix-ui.com/primitives/docs/overview/accessibility)

### Accessibility checks: axe-core through Playwright + manual keyboard review

Automated audits identify common accessibility defects in real pages

Install @axe-core/playwright; scan representative states and use a screen reader/keyboard. Passing automated rules is not complete accessibility evidence.

- [https://playwright.dev/docs/accessibility-testing](https://playwright.dev/docs/accessibility-testing)

### Transactional email: Nodemailer with project-selected SMTP provider

SMTP transport avoids coupling email templates to a hosting vendor

Install nodemailer; configure server-only transport, verified sender and TLS. Test locally, queue required delivery, handle ambiguous results and bounces; SMTP acceptance is not inbox delivery. Verify the resolved Nodemailer release supports the pinned Node runtime and preserves TLS certificate validation.

- [https://github.com/nodemailer/nodemailer](https://github.com/nodemailer/nodemailer)

### Uploads and object storage: AWS SDK for JavaScript v3 S3 client

Object storage separates durable files from ephemeral application disks

Install @aws-sdk/client-s3; authorize object keys, restrict size/type and configure lifecycle. Keep credentials server-side; add presigner only for direct uploads and validate provider compatibility.

- [https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html)

### Live server updates: EventSource for one-way server events

Browser-standard streaming suits status/progress feeds

Backend owns authenticated stream and event IDs. Test reconnect, replay and proxy buffering; EventSource is one-way and its constructor offers no arbitrary authorization-header option. Confirm long-lived connection support on host.

- [https://html.spec.whatwg.org/multipage/server-sent-events.html](https://html.spec.whatwg.org/multipage/server-sent-events.html)

Build with the stack’s strengths

## Architecture and developer workflow.

A Next application contains server rendering and browser interactivity with an explicit trust boundary. Recommendation: preserve an existing backend's domain ownership during UI adoption; for a new owned backend use server-only data access. Node/Docker and alternative adapters require separate runtime checks.

Version scope: Documentation reviewed 11 October 2026: current Next.js App Router docs label 16.4.0. Pin the installed Next, React, Node and database packages; distinguish cacheComponents:true from the previous caching model. This profile does not qualify a lockfile or hosting adapter. · Reviewed 2026-10-11

### Architecture boundaries

- Server Components load server-owned data; Client Components own interaction and browser APIs. Keep the client boundary near interactive leaves and pass minimal serializable DTOs.

- Recommendation: one domain writer and migration owner per responsibility. Existing REST/GraphQL services remain authoritative during coexistence; a new server-only DAL can own validation, authorization and transactions after transfer.

- Choose server, browser and CDN caches deliberately. Session-dependent output, invalidation and multiple instances require independent policies; adding a framework cache does not migrate a shared session or queue.

- Recommendation: durable jobs and realtime run behind explicit service contracts when required. A render, Server Action or browser promise is not an execution backlog.

### Tools and feedback

- Start in the external source checkout. Read README and inspect package.json, lockfile, next.config, current API ownership, schema and runtime. Record whether Cache Components are enabled before selecting examples.

- For an existing npm project run npm ci; use its scripts. With Next installed, npx next typegen then npx tsc --noEmit checks generated route types and TypeScript. Run the configured ESLint/Biome command separately; the build is not a substitute for lint.

- Run npm run dev for iteration and npm run build for production compilation; use npm run start only if its script runs the selected production server. Configure Playwright's isolated backend/data first, then npx playwright test for mixed-version journeys.

- Recommendation: deploy the same built artifact to all instances, record build/deployment identifiers, cache coordination, migrations, secrets and adapter support. Reproduce cold/warm loads, sign-out, old-tab actions and rollback on a staging topology.

### Translations to avoid

- Marking the root tree use client brings imported dependencies into the browser bundle and broadens the secret/exposure surface.

- Passing whole ORM records to Client Components exposes fields unrelated to presentation; enforce authorization and DTO filtering on the server.

- UI-hidden buttons or Proxy redirects cannot replace authorization at the mutation/data boundary.

- Copying pre-16 cache defaults into a Cache Components app silently changes freshness behavior; identify the installed model.

- Treating an old browser build as gone after deployment ignores existing tabs, prefetched payloads and action identifiers.

[nextjs.org →](https://nextjs.org/docs/app/getting-started/server-and-client-components)
[nextjs.org →](https://nextjs.org/docs/app/guides/data-security)
[nextjs.org →](https://nextjs.org/docs/app/guides/authentication)
[nextjs.org →](https://nextjs.org/docs/app/getting-started/caching)
[nextjs.org →](https://nextjs.org/docs/app/guides/caching-without-cache-components)
[nextjs.org →](https://nextjs.org/docs/app/guides/self-hosting)
[nextjs.org →](https://nextjs.org/docs/app/getting-started/installation)
[nextjs.org →](https://nextjs.org/docs/app/api-reference/cli/next)
[www.inngest.com →](https://www.inngest.com/docs/durable-execution)

For an existing application

## Keep the contracts while you change the stack.

These are documented options and proposed checks. Inspect the actual source application before adopting a transition.

Data and schema

### Inspect the source

Existing REST/GraphQL behavior, DTOs, authorization, transactions and one schema owner.

### During coexistence

Recommendation: Adopt server-rendered routes that call the old API; keep its writer and migration authority. Compare read-only fixtures without replaying real side effects.

### Target design

Recommendation: Retain the API permanently if appropriate, or transfer a bounded domain to a server-only DAL with minimal DTOs after mixed-version checks.

### Rollback

Route the cohort back while old-compatible schema remains; reconcile writes before any writer reversal.

### Benefits and prerequisites

**Server loading can reduce client waterfalls; an owned DAL centralizes authorization.**
Requires: Server-reachable API or reviewed database ownership; measurable user journeys.
Tradeoffs: A new domain writer requires schema/transaction review; framework adoption alone changes neither.

### Checks before transfer

- Old and new UI decode identical success/error/empty fixtures.

- Forged resource IDs remain denied on both mutation paths.

- An acknowledged write is readable through the old interface.

[nextjs.org →](https://nextjs.org/docs/app/guides/data-security)
[nextjs.org →](https://nextjs.org/docs/app/getting-started/server-and-client-components)

Identity and authorization

### Inspect the source

Existing session issuer, cookie/token format, expiry, revocation, tenant membership and CSRF behavior.

### During coexistence

Recommendation: Retain the issuer behind an adapter and authorize data/mutations in both implementations; inventory origin/domain/cookie differences before sharing.

### Target design

Recommendation: Use an explicitly selected issuer and server-side authorization boundary; transfer session contracts or require a controlled sign-in when compatibility cannot be preserved.

### Rollback

Restore old routes/issuer acceptance only while its keys and session semantics remain supported; do not resurrect revoked sessions.

### Benefits and prerequisites

**One identity authority can support gradual UI/backend replacement.**
Requires: Validated issuer integration and old/new expiry/revocation fixtures.
Tradeoffs: Session sharing is format/security work; sign-in continuity is not guaranteed by using cookies.

### Checks before transfer

- Revoked and expired sessions fail in old/new paths.

- Cross-tenant direct action requests are denied.

- Sign-out clears browser remote-state caches and back navigation reveals no protected data.

[nextjs.org →](https://nextjs.org/docs/app/guides/authentication)
[nextjs.org →](https://nextjs.org/docs/app/guides/data-security)

Caching and shared state

### Inspect the source

Actual enabled caching model, personalized response policy, keys, freshness, invalidation and shared-instance behavior.

### During coexistence

Recommendation: Keep the prior policy while converting one route/data category; separate old/new cache namespaces and observe stale/account-crossing outcomes.

### Target design

Recommendation: Choose Cache Components or version-matched previous-model APIs explicitly; keep user-specific data outside shared public entries and coordinate shared invalidation when deployed across instances.

### Rollback

Disable the new cache path and purge its namespace; keep source data unchanged and retain old invalidation until transfer completes.

### Benefits and prerequisites

**Repeated eligible work can be reused without refetching each time.**
Requires: A documented freshness tolerance, safe keys and working invalidation.
Tradeoffs: Coordination/storage adds operations; freshness and cost gains require measurement.

### Checks before transfer

- A write refreshes affected reads through every serving instance.

- Account A cannot read cached output for account B.

- Cold, warm and forced-refresh responses agree with the selected policy.

[nextjs.org →](https://nextjs.org/docs/app/getting-started/caching)
[nextjs.org →](https://nextjs.org/docs/app/guides/caching-without-cache-components)
[nextjs.org →](https://nextjs.org/docs/app/guides/self-hosting)

Jobs and schedules

### Inspect the source

Existing job producer/consumer payloads, ready/scheduled/retry/failed/in-flight states and external-effect idempotency.

### During coexistence

Recommendation: Keep existing workers; move a named job type behind a versioned event contract. Reconcile backlog and retain one consumer owner per item.

### Target design

Recommendation: Use selected durable execution such as Inngest for required workflows; a transactional outbox is a proposed design when domain commit and event submission are separate systems.

### Rollback

Stop new producers for the transferred type, account for active runs and resume old workers with compatible payloads; reconcile irreversible effects first.

### Benefits and prerequisites

**Checkpointed completed steps allow retry/resume without starting every step again.**
Requires: Selected service/SDK integration, stable step IDs, replay-safe external effects and delivery reconciliation.
Tradeoffs: Operating a workflow service adds dependency/cost; checkpoints do not supply business exactly-once effects.

### Checks before transfer

- Crash after an external effect but before step acknowledgement; retry causes one intended business effect.

- Domain commit with event-send failure is eventually reconciled.

- Old scheduled/retry work is drained or deliberately transformed.

[www.inngest.com →](https://www.inngest.com/docs/durable-execution)

Delivery and recovery

### Inspect the source

Current hosting/runtime, static assets, open-tab state, prefetched payloads and Server Function compatibility.

### During coexistence

Recommendation: Keep old assets and compatible API routes; promote one built artifact per deployment and rehearse an old tab against the new deployment.

### Target design

Recommendation: Use version-matched deploymentId support and infrastructure routing as needed; same-build instances share required action keys and cache coordination.

### Rollback

Restore the prior artifact and routing while compatible assets/data remain; do not claim traffic rollback reverses schema or external effects.

### Benefits and prerequisites

**Explicit rollout handling reduces missing-chunk/navigation mismatches.**
Requires: A qualified host, retained assets and tested old-client behavior.
Tradeoffs: Hard navigation can lose component state; same encryption key does not make old action IDs compatible.

### Checks before transfer

- Open an old tab, deploy, navigate and submit an old form; observe success or a controlled update path.

- Preserved drafts survive any required full reload.

- All instances serve matching build/deployment identifiers.

[nextjs.org →](https://nextjs.org/docs/app/guides/self-hosting)

[Read the migration workflow →](/rewrite/guide.md)

## Setup

- Start in an external source repository parent in a local development workspace with runtime, identity, database and host requirements documented.

- Run npx create-next-app@latest my-app --ts --eslint --app --src-dir --use-npm; review prompts; enter my-app; record resolved versions. Add --no-agents-md only for a repository that explicitly opts out of generated agent files.

- Preserve generated agent guidance and put purpose, commands, environment names and installed-documentation navigation in README. For an explicit README-only repository policy, set agentRules:false before next dev.

- Confirm strict TypeScript. Install npm install zod drizzle-orm pg better-auth server-only and npm install -D drizzle-kit @types/pg dotenv; add inngest only for required durable work.

- Configure server-only database/auth modules and Drizzle PostgreSQL schema/config, development DATABASE_URL, auth secret/base URL and Next route/client integration.

- Run npx auth@latest generate; include generated schema in Drizzle paths; run npx drizzle-kit generate; review SQL; apply npx drizzle-kit migrate only to verified development DB.

- Install npm install -D vitest @vitejs/plugin-react jsdom @testing-library/react @testing-library/dom vite-tsconfig-paths @playwright/test; configure unit/UI environments and production Playwright webServer; run npx playwright install.

- Implement invalid-input, tenant ownership, session and critical browser tests. Register durable workflow endpoint/worker only if used; exercise retries and duplicate events.

- Rehearse migrations on fresh test DB, run checks, configure chosen host and single migration job; inspect production session/browser behavior and rollback compatibility.

## Verification

Run these in the configured application; they are instructions, not recorded passes.

```
npm ci
npx next typegen
npx tsc --noEmit
npx eslint .
npx vitest run
npm run build
npx playwright test
```

## Open questions

- Does the product require server-rendered routes, client-owned state, or both?

- Which identity providers, account recovery and SSO requirements must be supported?

- Which host, database connection budget and migration/restore process will own production?

- Which workflows need retries, email, object storage or persistent realtime connections?

## Sources

- [Node.js release policy](https://nodejs.org/en/about/previous-releases)

- [Next.js installation](https://nextjs.org/docs/app/getting-started/installation)

- [create-next-app CLI](https://nextjs.org/docs/app/api-reference/cli/create-next-app)

- [Next.js agentRules](https://nextjs.org/docs/app/api-reference/config/next-config-js/agentRules)

- [Next.js AI coding agents](https://nextjs.org/docs/app/guides/ai-agents)

- [Next.js CLI](https://nextjs.org/docs/app/api-reference/cli/next)

- [Next.js deployment](https://nextjs.org/docs/app/getting-started/deploying)

- [Vite getting started](https://vite.dev/guide/)

- [TanStack Start](https://tanstack.com/start/latest)

- [Astro TypeScript](https://docs.astro.build/en/guides/typescript/)

- [Zod](https://zod.dev/)

- [Drizzle PostgreSQL](https://orm.drizzle.team/docs/get-started-postgresql)

- [Drizzle migrations](https://orm.drizzle.team/docs/migrations)

- [Better Auth installation](https://better-auth.com/docs/installation)

- [Better Auth Next.js integration](https://better-auth.com/docs/integrations/next)

- [Next.js authentication](https://nextjs.org/docs/app/guides/authentication)

- [Inngest durable execution](https://www.inngest.com/docs/durable-execution)

- [Inngest quickstart](https://www.inngest.com/docs/durable-execution/quick-start)

- [Inngest concepts](https://www.inngest.com/docs/durable-execution/concepts)

- [Next.js Vitest](https://nextjs.org/docs/app/guides/testing/vitest)

- [Next.js Playwright](https://nextjs.org/docs/app/guides/testing/playwright)

- [TanStack Query important defaults](https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults)

- [React Hook Form repository](https://github.com/react-hook-form/react-hook-form)

- [Tailwind Vite installation](https://tailwindcss.com/docs/installation/using-vite)

- [Radix accessibility](https://www.radix-ui.com/primitives/docs/overview/accessibility)

- [Playwright accessibility testing](https://playwright.dev/docs/accessibility-testing)

- [Nodemailer maintainer repository](https://github.com/nodemailer/nodemailer)

- [AWS JavaScript S3 examples](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html)

- [HTML EventSource standard](https://html.spec.whatwg.org/multipage/server-sent-events.html)

- [Vitest guide](https://vitest.dev/guide/)

- [Playwright installation](https://playwright.dev/docs/intro)

- [React Testing Library](https://testing-library.com/docs/react-testing-library/intro/)

- [Next.js development MCP and runtime tools](https://nextjs.org/docs/app/guides/mcp)

---

Canonical page: https://stack.menu/stacks/typescript-next-node/
