Understanding esbuild vs Rollup
Speed vs sophistication, mostly.
Why Vite uses esbuild for dev and Rollup for prod, what each does best, and when to pick which for a standalone library build.
esbuild — speed.
esbuild (Evan Wallace, 2020) is written in Go, parallelised, and 10-100× faster than the JavaScript-implemented alternatives. For dev servers (where rebuild time directly determines edit-refresh latency), this matters enormously. esbuild is also a bundler in its own right — for libraries and apps that don't need the most aggressive optimisation, it can replace Webpack/Rollup outright at much faster build times.
Rollup — sophistication.
Rollup (Rich Harris, 2015) is the bundler the JavaScript ecosystem standardised on for libraries. Its tree-shaking is famously thorough, its plugin ecosystem mature, its output formats (ESM, CJS, UMD, IIFE) all first-class. Slower than esbuild — JavaScript implementation, less parallelism — but produces marginally smaller bundles, and the plugin ecosystem is wider. Vite uses Rollup for production builds for exactly these reasons.
Why Vite uses both.
Dev: esbuild's speed wins; small differences in output don't matter (everything is HMR'd on demand). Prod: Rollup's optimisation wins; milliseconds of build time don't matter when the build runs once before deploy. The split is the right one for the trade-offs at each stage. Other tools (Parcel, Webpack) make different splits; Vite's choice has become the de-facto standard for the last few years.
A worked config.
A standalone esbuild library build: import { build } from "esbuild";
await build({
entryPoints: ["src/index.ts"],
bundle: true,
format: "esm",
outfile: "dist/index.js",
sourcemap: true,
external: ["react"],
}); Bundle src/index.ts, mark react as external (the consumer provides it), emit ESM with source map. Runs in <100 ms on most projects. Equivalent Rollup config is structurally similar but takes 2-10× longer to run; the tree-shaking may produce a slightly smaller output.
Library bundle in two tools
src/index.ts → ESM library
Same input, similar output, very different runtime.
esbuild ~80ms ; Rollup ~600ms
= esbuild for speed, Rollup for tree-shaking
The migration story.
Most projects don't need to choose — Vite/Next.js/Astro picks for you. Standalone library authors who want to ship esm+cjs+types still tend to reach for tsup (a wrapper around esbuild with sensible defaults) or unbuild (Vue ecosystem's wrapper around Rollup). The raw tools are for unusual builds; the wrappers cover 90 % of cases.
Webpack is still alive.
Webpack still dominates legacy projects (large enterprise codebases, older frameworks). It's slower than esbuild/Vite, has a much larger plugin ecosystem, and handles edge cases (federation, complex code splitting, unusual module formats) that the newer tools can struggle with. Greenfield projects rarely pick Webpack now; brownfield projects often keep it because migrating is more work than it saves.