Why Vite is fast: native ES modules in development
Vite starts a dev server in moments because it does not bundle your app first. How native ES modules, pre-bundled dependencies and hot module replacement make that work.
On a large project, the classic bundler workflow goes like this: run the dev command, wait while the whole application is bundled, and only then see the first page. Every change triggers a smaller version of the same wait. As the codebase grows, so does the pause.
Vite removes most of that waiting with one idea: do not bundle during development.
How the dev server works
Your code is served as native ES modules. Browsers can load import statements on their own. Vite serves each source file on request and transforms it on the way out. A page that needs twelve modules gets twelve modules. The other two thousand are never touched until you navigate to them.
Dependencies are pre-bundled once. Packages in node_modules rarely change, and some consist of hundreds of small files. Vite bundles each dependency into a single file the first time with esbuild, a very fast bundler written in Go, and caches the result.
Updates replace one module. With Hot Module Replacement, saving a file swaps that module in the running page. The update takes about the same time in a project of fifty files or five thousand, and component state is usually preserved.
Startup time therefore no longer depends on the size of the app.
Production is still bundled
Hundreds of separate requests are fine on localhost and slow over a real network. For production, Vite bundles the app with tree shaking, code splitting and minification. It has long used Rollup for this and is moving to Rolldown, a Rust based bundler from the same team.
Because development and production work differently, check the real build before a release:
npm run build
npm run preview
Getting started
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install
npm run dev
Configuration stays small.
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
proxy: { "/api": "http://localhost:8080" },
},
});
TypeScript, JSX, CSS modules, PostCSS and static assets work without extra setup. Environment files are built in as well. See environment variables in Node.js and Vite.
Where it fits
| Use | Verdict |
|---|---|
| Single page apps in React, Vue, Svelte or Solid | The default choice today |
| Component libraries | Good, using library mode |
| Full stack frameworks | Many are built on Vite, including SvelteKit, Nuxt and Astro |
| Next.js projects | Not applicable. Next.js ships its own bundler |
Things to know
- The first load of a very large app can lag, because the browser requests many modules. Later loads are cached.
- Old browsers need a plugin. The default build targets modern browsers.
@vitejs/plugin-legacyadds support for older ones. - Some old packages need help. CommonJS-only dependencies occasionally need an entry in the dependency optimization settings.
Our take
For a new frontend project that is not tied to a framework with its own tooling, Vite is where we start. The config is short, the feedback loop is fast, and the plugin ecosystem covers what real projects need. A fast loop is not a luxury: it changes how often developers try things, and that shows in the product.