Vite dependency-optimization crash (tested)

Vite's dev server pre-bundles your node_modules dependencies on startup ("dependency optimization") so the browser gets fast, cacheable ESM chunks. If any dependency it scans has invalid JavaScript syntax, this isn't a per-page error — we measured it crashing the entire Node process, taking the dev server down completely. We reproduced the crash, confirmed the server stays dead until restarted, and measured the config fix that turns it into a recoverable, per-module error instead.

1. The crash: one broken dependency kills the whole server

We created a minimal package under node_modules/broken-dep with a syntax error, imported it from main.js, and started vite:

// node_modules/broken-dep/index.js
export function x() {
  return (((broken
}
$ vite --port 8963
  VITE v8.3.2  ready in 149 ms
  ‣  Local:   http://127.0.0.1:8963/
file:///.../node_modules/vite/dist/node/chunks/node.js:7581
    const wrapper = new Error(summary);
                    ^
Error: Transform failed with 1 error:
[PARSE_ERROR] Expected `,` or `)` but found `}`
   │ node_modules/broken-dep/index.js:3:1
    at transformWithOxc (...)
    at extractExportsData (...)
    at async prepareRolldownOptimizerRun (...)

Node.js v24.21.0

We then checked the homepage with curl: connection refused. ps aux confirmed the node process was gone entirely — this is an uncaught exception during the dependency scan, and Node's default behaviour for an uncaught exception is to terminate the process. There is no dev server left to serve any page, not just the one that imports the broken package.

2. Why this is different from "Failed to resolve import"

A missing dependency (a typo'd package name, or one that isn't installed) does not crash the server — Vite returns a normal per-request 500 with Failed to resolve import "X" from "Y". Does the file exist? and keeps running (see Vite: Failed to resolve import for that case). The crash in this guide is specifically about a dependency that exists and gets scanned, but fails to parse during the pre-bundling step — a corrupted install, a package built for a newer JS syntax than your toolchain expects, or (realistically) a local file:/link: dependency you're actively editing and briefly left in a broken state.

3. The fix: optimizeDeps.exclude

Excluding the offending package from pre-bundling in vite.config.js stops Vite from parsing it during the startup scan:

export default {
  optimizeDeps: { exclude: ["broken-dep"] }
}

We restarted with this config: VITE ready, and the homepage request succeeded (HTTP 200) — the server stayed alive this time. Requesting the broken module directly now gets a scoped, non-fatal error logged to the terminal instead of a crash:

14:19:00 [vite] (client) Pre-transform error: Failed to parse source for import analysis
because the content contains invalid JS syntax.
  Plugin: vite:import-analysis
  File: /tmp/.../node_modules/broken-dep/index.js?v=642cbf24:1:0

ps confirmed the Node process was still running after this request. The page using that specific import still won't work — the dependency is genuinely broken — but every other page on the site keeps working, and you don't have to restart the whole dev server to keep iterating.

4. General dependency-optimization troubleshooting checklist

SymptomLikely causeFix
Dev server exits immediately on startup, stack trace mentions the optimizer/transform stepA scanned dependency has invalid syntaxFind the package named in the stack trace; add it to optimizeDeps.exclude, reinstall it, or pin a working version
Browser console: "Outdated Optimize Dep" / 504A new dependency was discovered mid-session after the page already loaded, and Vite had to re-run the scanReload the page once; Vite's own client auto-retries this in practice
Stale or wrong pre-bundled output after editing a local/linked packageThe optimizer cache in node_modules/.vite didn't notice the changeDelete node_modules/.vite and restart, or run vite --force
One specific package always triggers slow re-optimizationVite didn't detect it as a dependency upfront (common for deep/dynamic imports)Add it to optimizeDeps.include so it's scanned eagerly on startup

Related: for an import Vite can't find on disk at all, see Vite: Failed to resolve import.

Frequently asked questions

Why did my whole Vite dev server crash instead of just one page breaking?

Dependency pre-bundling happens once at server startup, scanning all of node_modules up front. We measured that a syntax error in any scanned package throws an uncaught exception at that point, and Node's default behaviour for an uncaught exception is to exit the whole process - there's no server left, not just a broken page.

Does excluding the broken package from optimizeDeps actually fix the code, or just the crash?

Just the crash. We measured that with optimizeDeps.exclude, the server stays alive and every other page works, but requesting the excluded package's own broken module still fails with a Pre-transform error - the underlying syntax error in that dependency still needs fixing or replacing.

What does '504 (Outdated Optimize Dep)' mean and is it related to this crash?

It's a different, much more common and non-fatal issue: Vite discovers a new dependency after the dev server already started, has to re-run the optimizer, and a request made against the old pre-bundle version briefly 404s/504s. A page reload resolves it. It does not crash the process, unlike the syntax-error case in this guide.

Why does this happen with a local/linked package but not a normal npm install?

Normal npm-published packages are built/transpiled before publishing, so they're far less likely to contain syntax your toolchain can't parse. A package you're actively editing via npm link or a file: dependency can easily be saved mid-edit with a syntax error, which is the realistic way most developers hit this crash.

Is this specific to Vite's new Rolldown/Oxc-based optimizer, or did esbuild do the same thing?

We only measured this on Vite 8.3.2's Rolldown/Oxc toolchain (the default as of this version). esbuild, the optimizer in older Vite versions, also throws on invalid syntax during pre-bundling - the underlying crash mechanism (an uncaught exception killing the Node process) is a Node.js behaviour, not specific to either bundler.

Written with AI assistance. Measured on 2026-10-03 with Vite 8.3.2 (Rolldown + Oxc, the native-toolchain optimizer that replaced esbuild) and Node.js v24.21.0 on Linux, using a minimal vanilla-JS project with a hand-crafted broken package under node_modules/. Server logs below are copy-pasted verbatim; process liveness was confirmed with ps between requests. PlainHeaders is our extension; Node.js and Vite are free.