0.1 · difficulty 1/4 · 12 min read
Why We Need Vite
Start from traditional dev server bottlenecks, then learn why Vite avoids bundling in dev and why Vite 8 uses Rolldown to align the dev/build mental model.
Why Traditional Dev Servers Got Slow
In the Webpack era, a dev server usually started from an entry file, recursively resolved every import, bundled the dependency graph, and only then gave the browser something executable. That is fine for small apps. Once a project grows from 100 modules to 10,000 modules, cold start can stretch into tens of seconds.
The slowdown is not just "more files". The deeper issue is that dev startup performs too much work before the browser can run anything:
- Parse every module.
- Resolve and rewrite every import.
- Run loaders and plugins.
- Generate bundle code, sourcemaps, and runtime wrappers.
- Send the result to the browser.
When you edit one component, HMR also has to update state inside the bundler's full graph. Even if the final update touches one component, the toolchain is still maintaining a bundle-oriented world.
Native Browser ESM Changed The Entry Model
Modern browsers support:
<script type="module" src="/src/main.tsx"></script>The browser can request modules by itself. It sees import "./App.tsx" and requests /src/App.tsx. It sees import react from "react" and requests the dependency entry Vite prepared.
Vite's key choice is: do not bundle the whole app before dev starts. The dev server transforms a module only when the browser requests it:
browser requests /src/App.tsx
-> Vite finds the source file
-> Vite runs an on-demand transform
-> Vite returns browser-executable ESMAdding 1,000 page files that no one visits does not significantly slow cold start, because Vite does not process them upfront.
Dependency Pre-Bundling Handles Request Storms
"Do not bundle source" does not mean "do no preprocessing". Dependencies in node_modules often have different problems:
- CommonJS packages must be converted to ESM.
- A package may contain many deep internal imports.
- Conditional exports can be expensive to resolve repeatedly.
Vite preprocesses dependencies into the .vite/deps cache. Source code stays on-demand; dependencies are normalized into browser-friendly ESM entries. This split keeps both cold start and first page load under control.
The Vite 8 Mental Model
The classic early-Vite explanation was "fast per-file transforms in dev, Rollup for production build". That explains why Vite felt fast, but it also describes a structural problem: dev and build were backed by different engines, so plugin hooks, resolution details, sourcemaps, and output behavior could diverge.
Vite 8's direction is to align the model around Rolldown:
| Stage | Vite 8 focus | Mental model |
|---|---|---|
| dev | On-demand source transforms, fast HMR, dependency preprocessing | Vite processes what the browser asks for |
| build | Full static analysis, tree-shaking, chunk generation, asset hashing | Vite produces deployable, cacheable assets |
| plugins | Vite hooks plus Rollup/Rolldown-style hooks | dev/build behavior should converge around one plugin story |
That is why this guide spends so much time on Rolldown. It is not only "a faster build implementation"; it is part of making Vite's development and production models easier to reason about together.
Fast Dev Does Not Make Build Unimportant
Skipping source bundling in dev improves feedback speed. Production build still needs bundling because production needs:
- Fewer chunks and fewer network round trips.
- Dead-code removal.
- Hashed filenames for long-term caching.
- CSS extraction, image handling, and manifest generation.
- Route-level splitting based on dynamic import boundaries.
The right mental model is not "Vite does not bundle". It is:
Vite avoids upfront source bundling in dev, then uses the full build pipeline for production assets.
When You Feel The Difference
Vite's advantage becomes obvious in these situations:
- Large applications: cold start is no longer tightly tied to total source size.
- Frequent UI edits: HMR updates only the relevant modules.
- Plugin development:
resolveId,load, andtransformcan be tested quickly in a dev server. - Monorepos: source packages can participate in dev without being published or prebuilt first.
If you only inspect a three-file demo, the difference may feel small. Vite's value shows up when the project, team, and feedback loop all get larger.
What To Remember After This Lesson
Do not reduce Vite to "it starts fast". The more accurate takeaway is:
- Vite changes the dev feedback loop from "process all source first" to "process source when the browser requests it".
- Dependency pre-bundling makes npm packages easier for the browser to consume; it is not upfront compilation of your app source.
- Production build is still a full engineering problem: chunks, caching, minification, manifests, and deploy paths still matter.
- Vite 8's Rolldown path reduces the old "works in dev, fails in build" split caused by different engines.
Every later chapter can be checked against these statements. Is a config, plugin, or optimization shortening dev feedback, improving production output, or reducing mismatch between the two?
Self-check
- Why can Vite avoid bundling the whole source tree before dev starts?
- What problems do on-demand source transforms and dependency pre-bundling solve separately?
- Why does production build still need a full bundling pipeline?
- Which dev/build inconsistencies does the Vite 8 + Rolldown path try to reduce?