Skip to main content
Next.js is a full-stack React framework built as a monorepo. Understanding its architecture helps you make better decisions about performance, bundling, and rendering.

Key packages

next

The main framework package published to npm. Contains the dev server, build pipeline, routing, and all runtime code for client and server.

create-next-app

The project scaffolding CLI. Bootstraps a new Next.js application with sensible defaults and optional templates.

@next/swc

Native Rust bindings for the SWC compiler. Handles TypeScript and JSX transpilation, minification, and code transforms — replacing Babel.

Turbopack

A Rust-based incremental bundler integrated into next dev and next build. Uses demand-driven evaluation and persistent caching for fast rebuild times.

Repository structure

The Next.js repository is a pnpm monorepo:
next.js/
├── packages/next/          # Main framework (published as "next" on npm)
│   └── src/
│       ├── build/          # Build pipeline (webpack, Turbopack, SWC)
│       ├── client/         # Client-side runtime
│       ├── server/         # Server runtime
│       └── cli/            # next dev, next build, next start entry points
├── packages/create-next-app/  # Project scaffolding CLI
├── packages/next-swc/      # Rust/SWC native bindings
├── packages/eslint-plugin-next/  # ESLint rules
├── turbopack/              # Turbopack bundler (Rust, managed as a git subtree)
├── crates/                 # Additional Rust crates for SWC transforms
├── test/                   # All test suites (e2e, development, production, unit)
└── examples/               # Example applications

Compilation pipeline

When you run next build, Next.js orchestrates several compilation stages:
1

Configuration loading

Next.js reads next.config.js (or next.config.ts), resolves jsconfig.json / tsconfig.json, and constructs the full build configuration including compiler options, environment variables, and feature flags.
2

Entry point discovery

The framework walks your app/ or pages/ directory to collect all routes, layouts, and special files (loading.tsx, error.tsx, not-found.tsx). These become Webpack or Turbopack entry points.
3

Bundling

Turbopack (default) or Webpack compiles and bundles each entry point. The SWC compiler handles TypeScript and JSX transforms. Tree-shaking, code splitting, and chunk optimization happen here.
4

Rendering

Static pages are pre-rendered at build time. Server components are analyzed to separate server-only code from client bundles. Dynamic routes emit server functions instead of static HTML.
5

Output

Compiled assets, server functions, static HTML, route manifests, and source maps are written to the .next/ directory, ready to be served by next start or deployed.

Rendering strategies

Next.js supports multiple rendering strategies that can be mixed within a single application:
Pages are rendered at build time and served as static HTML. No server required at request time. Ideal for content that doesn’t change per user.
export async function generateStaticParams() {
  const posts = await getPosts()
  return posts.map((post) => ({ slug: post.slug }))
}

export default async function Page({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug)
  return <article>{post.content}</article>
}

Client and server boundary

Next.js uses the React Server Components model to split your application into two execution environments:
  • Server components run only on the server (or at build time). They can access databases, file systems, and secrets directly. They never ship JavaScript to the browser.
  • Client components are prefixed with 'use client'. They hydrate in the browser and can use stateful hooks and browser APIs.
The boundary is determined at the component level. Server components can import client components, but client components cannot directly import server components — they can only receive them as props or children.
Request
  └── Server component (fetches data, renders HTML)
        ├── Another server component (no JS sent to browser)
        └── 'use client' boundary
              └── Client component (hydrated in browser)

Build output

After a successful build, the .next/ directory contains:
PathContents
.next/server/Server-side bundles and HTML for pre-rendered pages
.next/static/Hashed client-side JS chunks, CSS, and media
.next/cache/Incremental build cache (Turbopack persistent cache)
.next/BUILD_IDUnique identifier for the current build
.next/routes-manifest.jsonRoute metadata used by the server at runtime
The development branch is canary. All pull requests should be opened against canary, not main.

Build docs developers (and LLMs) love