next build compiles your entire application for production, and its output tells you a lot about how your routes will actually behave once deployed. This lesson covers reading that output and understanding next start.
What next build Actually Does
Running next build compiles and optimizes every route, generates static HTML for eligible pages, bundles and minifies client-side JavaScript, and produces a route-by-route summary describing exactly how each page will be rendered in production (Static, SSG, ISR, or Dynamic). This is meaningfully different from next dev, which prioritizes fast iteration and helpful error messages over final output optimization.
Reviewing this summary after every significant change is one of the most reliable ways to confirm a route is being rendered the way you intended, without deploying first to find out.
npm run build
# Example summarized output:
# Route (app) Size First Load JS
# ┌ ○ / 142 B 89.3 kB
# ├ ● /blog/[slug] 156 B 92.1 kB
# └ ƒ /dashboard 201 B 94.8 kB
#
# ○ Static
# ● SSG (generateStaticParams)
# ƒ Dynamic (server-rendered on request)
This legend tells you exactly which strategy Next.js chose for each route — invaluable for confirming your assumptions before deploying.
next build vs. next dev vs. next start
next dev // development server, fast refresh, unoptimized output
next build // compiles and optimizes a production build
next start // serves the build produced by "next build"
next dev is for local development only; never use it in production.
next build must run successfully before next start can serve anything.
next build's output includes a per-route rendering strategy summary, worth reviewing regularly.
Build failures (type errors, lint errors) should be caught here, before deployment, not after.
Build Output Symbols Cheat Sheet
What each build summary symbol means.
Symbol
Meaning
○ (Static)
Pre-rendered as static HTML at build time
● (SSG)
Pre-rendered for specific params via generateStaticParams
ƒ (Dynamic)
Server-rendered on each request
First Load JS
JavaScript needed for a route's first visit
Understanding First Load JS
The "First Load JS" column reported by next build estimates how much JavaScript a visitor's browser needs to download for that specific route's first visit, including shared framework code. Watching this number over time — and investigating sudden increases — is a lightweight way to catch bundle size regressions without running a full bundle analysis every time.
Build-Time Type and Lint Checks
By default, next build runs TypeScript type checking and ESLint, failing the build if either reports errors — catching real bugs before they ever reach production, rather than relying solely on manual testing.
TypeScript errors fail the build unless explicitly ignored via configuration (not recommended).
ESLint errors behave the same way, though warnings alone don't fail the build.
Running these checks locally before pushing avoids surprise CI failures.
Common Mistakes
Deploying based only on next dev behavior without ever running a real production build locally.
Ignoring the build's route summary, missing that a route unexpectedly became dynamic.
Disabling type checking or linting in the build config just to make errors "go away" without fixing them.
Not tracking First Load JS over time, missing gradual bundle size regressions.
Key Takeaways
next build compiles and optimizes the app, producing a route-by-route rendering strategy summary.
next dev is for development only; next start serves the output of next build in production.
The build summary's symbols (○, ●, ƒ) tell you exactly how each route will render.
Type checking and linting run as part of the build, catching errors before deployment.
Tracking "First Load JS" over time helps catch bundle size regressions early.
Pro Tip
Run npm run build locally before every significant pull request, not just in CI — reviewing the route summary directly in your terminal, right after making changes, is the fastest feedback loop for confirming your rendering strategy assumptions are correct.
You now understand production builds. Next, learn how to containerize a Next.js app with Docker for portable, self-hosted deployments.