# Next.js Dev Takes 30 Seconds to Boot? Fix That

> Cold boots, slow Fast Refresh, crawling type-checks: the dev-loop diet that returns minutes per hour. My config inside.

Source: https://boringpush.com/blog/nextjs-dev-slow-30s-boot-hot-reload

## Coffee gets cold waiting for localhost

Start the day like this: `npm run dev`, watch 2,000 modules compile, sip coffee, check phone, sip more coffee, and — thirty-some seconds later — localhost:3000 finally answers. Then every save takes four seconds to refresh. By lunch, forty minutes gone to waiting, in slices too small to use and too big to ignore.

Thirty seconds doesn't sound like much until you multiply: fifty saves a day times four seconds is three minutes of staring, plus the cold boot, plus the broken flow state that costs twenty minutes each time it shatters. My dev loop wasn't slow. It was death by a thousand sips.

Nextjs dev slow isn't a hardware problem — any decent laptop outruns it. It's a configuration debt problem, payable in one evening.

## Where dev-loop minutes actually die

| Hog | My before | My after |
|---|---|---|
| Cold boot (`next dev`) | ~32s, 2,100 modules | ~6s Turbopack |
| Save → refresh | 3–5s (type-check inline) | <1s (types deferred) |
| Initial page compile | 8s (giant barrel imports) | ~2s (direct imports) |
| Test watch startup | 20s (whole suite) | 5s (changed-only) |
| Daily waiting total | ~45 min + 3 shattered flows | ~8 min, flows intact |

Three things the fix teaches:

1. **Type-checking in the loop is the silent killer.** `tsc` on every save feels responsible and costs seconds per keystroke-cycle — while catching nothing your editor's red squiggles missed. Move full checks to pre-push hooks and CI; the loop stays dumb and fast. Editors check continuously; loops should compile continuously. Different jobs, different tools.
2. **Barrel files poison the module graph.** One `index.js` re-exporting forty components means every save recompiles all forty — one components folder standing a single import away from everything. Direct imports (`@/components/Button` not `@/components`) collapse refresh from four seconds to under one. Barrel files are convenience for authors, tax on every saver.
3. **Cold boots punish restarts, so stop restarting.** Dev servers die from port conflicts, env changes, and Monday mornings — each death costs a full recompile. Stable setup (dotenv preloaded, ports reserved, deps warm) plus Turbopack's fast boot turned restarts from coffee breaks into blinks. Uptime is a dev-loop feature.

BoringPush gates stay pre-push, so the loop never waits on types.

The version-hell posts cover upgrade breakage. This one covers the daily grind nobody posts about because everyone's quietly enduring it.

## The dev-loop diet

One evening, three changes, measured before and after with a stopwatch (actually timed — engineers trust numbers).

**Step 1 — Switch the loop to Turbopack.**

```bash
# package.json:
"dev": "next dev --turbo"     // verify current flag for your Next major
# measured: 32s → 6s cold boot on my 2,100-module app
# caveat: one webpack-only plugin needed an equiv — check yours before committing
```

Verify plugin compatibility first, then never look back.

**Step 2 — Defer type-checking out of the hot path.**

```json tsconfig.json (scoped includes)
{ "include": ["app/**/*", "libs/**/*", "providers/**/*"],
  "exclude": ["node_modules", ".next", "data/archive"] }
// full tsc runs pre-push + CI only; editor squiggles cover the loop
```

Scoped includes stop the checker wandering into archives and generated folders (a data graveyard getting type-checked on every save — embarrassing anywhere, satisfying to fix). Pre-push hooks catch what matters before code leaves; CI catches the rest. The loop's job is speed; correctness has its own scheduled appointments.

**Step 3 — Purge barrels, warm the everyday.**

```bash
# find the hogs: count what each barrel pulls
grep -r "from '@/components'" app/ | wc -l    # count the barrel imports in your own app
# fix: direct imports everywhere (codemod in an hour), delete barrel files
# keep warm: PM2-style persistence doesn't apply locally — instead, never close the tab
```

The grep shocks into action. Codemod afternoon, refresh under a second, flow states intact since.

That's the whole promise — loops so fast the phone hotspot keeps up.

## Stopwatch numbers, before and after

| Metric | Before (measured) | After (measured) |
|---|---|---|
| Cold boot | 32s | 6s |
| Save → refresh | 3–5s | <1s |
| First page compile | 8s | ~2s |
| Daily wait total | ~45 min | ~8 min |
| Flow states shattered | ~3/day | ~0 |

Admitting the tax: Turbopack parity isn't 100% (check exotic plugins), deferred types mean red squiggles are advisory until push (discipline required), and the codemod afternoon is real work. Priced against 37 daily minutes plus flow, payback lands before Friday of the same week. Dev-loop work is the highest-ROI work there is: it multiplies every future hour, including the ones agents type.

## FAQ

### Is nextjs dev slow on Apple Silicon or just Intel dinosaurs?

Both, differently: Silicon compiles fast but throttles on sustained heat (lap + summer = slow afternoons), Intel just grinds. The three fixes help universally — Turbopack's margin is biggest where webpack was slowest, which is everywhere. Hardware upgrades help linearly; configuration fixes help multiplicatively. Fix config first, buy laptops on your normal cycle, never for dev speed alone.

### Do monorepos change the dev-speed math?

Yes, worse in every dimension: more modules, longer graphs, cross-package rebuilds. Turborepo/Vite-ecosystem caching helps (remote cache = skip rebuilds), as does scoping dev to the app you're touching (not the whole monorepo). Solo founders: stay monolith until teams force the split — monorepo speed taxes are team-scale problems wearing solo-founder clothes.

### How do agents factor into dev-loop speed?

Agents type while you wait — parallel throughput that masks loop latency (agent builds feature B during your slow refresh of feature A). But slow loops still tax agent sessions (their file-watching and test runs inherit your config). Fast loops compound with agents: quick verification keeps agent output honest in real time. Optimize the loop first; agents multiply whatever loop they inherit.

### What about Dockerized dev environments — slower?

Usually 2–5x slower file-watching (bind-mount latency, especially macOS) for questionable parity gains at solo scale. Native dev + containerized prod (build the image at deploy, develop on metal) splits the difference correctly: loop speed where you live, parity where it ships. Dockerize the artifact, not the workday. Your wrists will know the difference by Friday.

### When is dev speed "good enough" to stop tuning?

Under 10s cold boot, under 1s refresh, under 5s test-watch: diminishing returns kick in hard past these lines. Stop exactly there — further tuning trades hours for seconds only benchmarks notice. Good-enough loops free attention for product; perfect loops consume it. Tune to the threshold, then close the config files for a year.

## Keep reading

- [Next 16 Async Params Broke My Build: Fix](/blog/nextjs-16-async-params-breaking) — the upgrade that slows loops differently
- [14 to 16 Upgrade: Caching Broke Everything](/blog/nextjs-14-to-16-upgrade-cache-pain) — the corridor this loop survives
- [Router Cache Confusing You? Next.js Caching, Fixed](/blog/struggling-with-router-cache-fix) — the cache model behind refresh behavior
