JSTAcademy
0 XP
Dashboard
Crash Courses
The Build Pipeline: From Source to Bundle
14 min
Masters+150 XP
Crash Courses · Masters

The Build Pipeline: From Source to Bundle

Understand what npm run build actually does and what Vercel/Netlify receives.
14 min read+150 XP on completionCert: Ship It Crash Course
Tap any word in the text below to start reading from there.

The Build Pipeline: From Source to Bundle

What Actually Happens When You Run npm run build

Most developers run npm run dev, build features, then hand it to Vercel and hope for the best. Understanding what the build step actually does makes you 10x better at debugging production issues.

---

The Full Pipeline

Source code (.tsx, .ts, .css)
        ↓
TypeScript compiler (tsc) — type checks, strips types
        ↓
Next.js compiler (SWC) — transforms JSX, handles imports
        ↓
Bundler (webpack/turbopack) — resolves deps, code splits
        ↓
Minifier — removes whitespace, shortens variable names
        ↓
Output: .next/ directory
        ↓
Vercel deployment (CDN + edge network)

---

Reading Build Output

Run npm run build and read what it tells you:

Route (app)                    Size    First Load JS
┌ ○ /                          4.2 kB      112 kB
├ ○ /about                     1.1 kB      109 kB
├ ● /courses/[id]              8.7 kB      147 kB
└ ƒ /api/tts                   0 B         0 B

○ Static  ● Dynamic  ƒ Serverless Function
  • ○ Static — pre-rendered HTML at build time, served from CDN, fastest possible
  • ● Dynamic — rendered on each request (uses fetch with no cache, cookies, or headers)
  • ƒ Serverless Function — your API routes, run on-demand

First Load JS is the critical number. Under 130 kB is good. Over 300 kB needs investigation.

---

Environment Variables: Build vs Runtime

This is the #1 source of production bugs for new developers.

# .env.local (never commit this)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co   # ← bundled into client JS
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhb...              # ← bundled into client JS
SUPABASE_SERVICE_KEY=eyJhb...                       # ← SERVER ONLY, never exposed
OPENAI_API_KEY=sk-...                               # ← SERVER ONLY, never exposed

Rule: NEXT_PUBLIC_ = visible to everyone in the browser. Never put secrets there.

---

Vercel's Build System

When you push to GitHub, Vercel:

  1. Clones your repo
  2. Runs npm install (uses package-lock.json for exact versions)
  3. Runs your build command (default: npm run build)
  4. Deploys .next/ to its global CDN
  5. Spins up serverless functions for API routes

Critical: Vercel builds in a clean environment. It has no access to your .env.local. Environment variables must be added in the Vercel dashboard under Settings → Environment Variables.

---

Common Build Failures and Fixes

TypeScript errors blocking build:

# Check locally first — never push blindly
npx tsc --noEmit

Missing environment variables:

Error: NEXT_PUBLIC_SUPABASE_URL is not defined

Add the variable to Vercel dashboard, then redeploy.

Module not found:

npm install   # install missing dep
# Commit package.json + package-lock.json

Build succeeds locally, fails on Vercel:

  • You have a file import that works on macOS (case-insensitive) but fails on Linux (case-sensitive): import Button from './button' → should be './Button'
  • You're using a Node.js API in a component that runs at the edge

---

The next.config.js Production Checklist

const nextConfig = {
  // Images from external domains must be explicitly allowed
  images: {
    remotePatterns: [{ hostname: 'your-supabase-project.supabase.co' }],
  },
  // Redirects — handled at CDN level, zero latency
  async redirects() {
    return [
      { source: '/old-path', destination: '/new-path', permanent: true },
    ]
  },
}
0%