DEV Community

Steve Zhang
Steve Zhang

Posted on

E2E Coverage in Next.js: Dev Mode vs Production Mode

nextcov supports collecting coverage from both next dev and next build && next start. This article explains the differences and when to use each mode.

Dev Mode

In dev mode, nextcov collects coverage directly from Next.js's webpack dev server.

How It Works

  1. Next.js dev server starts with --inspect=9230
  2. Next.js spawns a worker process on port 9231 (inspect port + 1)
  3. nextcov connects to the worker via CDP (Chrome DevTools Protocol)
  4. Coverage is collected using Profiler.startPreciseCoverage() API
  5. Source maps are inline (webpack eval) — no build artifacts needed

Running Dev Mode

# Start Next.js dev server with inspector enabled
NODE_OPTIONS='--inspect=9230' npm run dev &

# Run tests
npx playwright test
Enter fullscreen mode Exit fullscreen mode

Dev Mode Characteristics

  • No build required — start testing immediately
  • Inline source maps — webpack eval scripts contain embedded source maps
  • CDP port: cdpPort + 1 (9231) — connects to the worker process
  • Hot reload — changes are reflected without restart
  • Slower — on-demand compilation adds overhead
  • Client coverage — Playwright connects to the browser via CDP

Production Mode

In production mode, nextcov uses Node.js native V8 coverage with pre-built bundles.

How It Works

  1. Build Next.js with source maps enabled (E2E_MODE=true)
  2. Start the production server with NODE_V8_COVERAGE and --inspect
  3. nextcov connects via CDP on port 9230
  4. Coverage is collected using Node.js native V8 coverage
  5. Source maps are external (.map files) generated during build

Running Production Mode

# Build with source maps
E2E_MODE=true npm run build

# Start server with coverage enabled
NODE_V8_COVERAGE=.v8-coverage NODE_OPTIONS='--inspect=9230' npm start &

# Run tests
npx playwright test
Enter fullscreen mode Exit fullscreen mode

Production Mode Characteristics

  • Build required — must run next build first
  • External source maps — .map files in build output
  • CDP port: cdpPort (9230) — connects directly to the server
  • No hot reload — restart required for changes
  • Faster — pre-compiled bundles execute quickly
  • Client coverage — Playwright connects to the browser via CDP

Comparison

Aspect Dev Mode Production Mode
Command next dev next build && next start
Source Maps Inline (webpack eval) External (.map files)
Build Required No Yes
Hot Reload Yes No
Coverage Method CDP Profiler API Node.js native V8 coverage
CDP Port cdpPort + 1 (9231) cdpPort (9230)
Performance Slower (compilation) Faster
Recommended For Development iteration CI/CD, final coverage

Auto-Detection

nextcov automatically detects the mode — no configuration needed. Just use the same globalSetup and globalTeardown for both.

📊 Auto-detecting server mode...
  Trying dev mode (worker port 9231)...
  ✓ Dev mode detected (webpack eval scripts found)
  ✓ Server coverage collection started
Enter fullscreen mode Exit fullscreen mode

Or for production mode:

📊 Auto-detecting server mode...
  Trying dev mode (worker port 9231)...
  ⚠️ Failed to connect to CDP (dev mode): Error: connect ECONNREFUSED
  ℹ️ Production mode will be used (NODE_V8_COVERAGE + port 9230)
Enter fullscreen mode Exit fullscreen mode

Same Output, Different Paths

Both modes produce identical Istanbul-compatible output:

coverage/e2e/
├── coverage-final.json   # Merges with Vitest coverage
├── lcov.info             # For CI tools
└── index.html            # Interactive report
Enter fullscreen mode Exit fullscreen mode

This means you can:

  • Use dev mode during development for fast iteration
  • Use production mode in CI for accurate final reports
  • Merge both with Vitest coverage using nextcov merge

Summary

Use Case Mode Command
Local development Dev next dev --inspect=9230
CI/CD pipeline Production next build && next start --inspect=9230
Quick coverage check Dev No build required
Production validation Production Uses production bundle

Both modes work seamlessly with nextcov — just run your tests and coverage is collected automatically.

References


This is part 6 of a series on test coverage for modern React applications:

  1. nextcov - Collecting Test Coverage for Next.js Server Components
  2. Why Istanbul Coverage Doesn't Work with Next.js App Router
  3. V8 Coverage vs Istanbul: Performance and Accuracy
  4. V8 Coverage Limitations and How to Work Around Them
  5. How to Merge Vitest Unit, Component, and E2E Test Coverage
  6. E2E Coverage in Next.js: Dev Mode vs Production Mode (this article)

Top comments (0)