Overview
Use Vite for all new frontend projects. It starts in milliseconds via native ES modules, replaces the dev-server bundling step with on-demand transforms, and produces optimized Rollup bundles for production. Use Webpack when an existing app depends on custom loaders, the ModuleFederationPlugin, or a Webpack plugin that has no Vite equivalent. See swc-vs-babel for the transform layer decision.
When Vite wins
Vite is the default for new projects in 2026.
- Dev server speed: Vite does not bundle the application at startup. It serves native ES modules and transforms individual files on request. Cold start on a 500-component React app takes under 300 ms; Webpack’s cold start on the same app typically takes 15 to 30 seconds.
- HMR: Vite’s Hot Module Replacement updates only the changed module and its direct dependents. React component edits appear in the browser in under 100 ms.
- Framework support:
create-vitegenerates starters for React, Vue, Svelte, Solid, Lit, and Preact. Next.js does not use Vite directly, but Astro and SvelteKit are Vite-based. - Plugin ecosystem: Rollup plugins work in Vite’s production build. Vite-specific plugins exist for PWA, SSR, federation (via
@originjs/vite-plugin-federation), and image optimization. - Production builds: Vite builds with Rollup, producing well-tree-shaken output with code-splitting, lazy routes, and asset fingerprinting.
- Config simplicity:
vite.config.tsis 10 to 20 lines for most projects. Webpack configs for equivalent functionality run to 100+ lines.
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
build: { target: "es2020" },
});When Webpack wins
Webpack is the right choice when the project depends on capabilities it uniquely provides.
- Module Federation: Webpack’s
ModuleFederationPluginis the standard implementation of runtime module sharing between independently deployed applications (microfrontends). Vite has a community federation plugin but it is not at parity. - Custom loaders: if the build pipeline requires non-standard loaders (MDX with custom remark plugins, custom asset processors, or legacy format ingestion), and a Webpack loader exists for them without a Vite plugin equivalent, staying on Webpack avoids rewriting transforms.
- Very large legacy applications: apps with 5000+ modules, deeply entangled Webpack configs, and no time budget for migration. Webpack’s build is slower but known to work.
- Persistent caching: Webpack 5’s filesystem cache is mature and effective for slow CI builds. Vite’s build-time caching is improving but Webpack has the edge on large incremental builds.
Trade-offs at a glance
| Dimension | Vite | Webpack 5 |
|---|---|---|
| Dev server cold start | Under 300 ms (no bundling) | 15 to 60 seconds (bundles everything) |
| HMR speed | Near-instant (module-level) | Seconds (depends on config) |
| Production bundler | Rollup | Webpack |
| Config complexity | Low (20 lines typical) | High (100+ lines typical) |
| Module Federation | Community plugin (partial parity) | First-class via ModuleFederationPlugin |
| Plugin ecosystem | Rollup plugins + Vite plugins | Huge; loaders and plugins for every use case |
| Custom loaders | Vite plugin API | Loader API (more established) |
| TypeScript | Native via esbuild | ts-loader or babel-loader |
| Tree shaking | Good (Rollup) | Good (Webpack 5 with optimization.usedExports) |
| CSS modules | Native | Via css-loader |
| SSR | First-class (ssrLoadModule API) | Possible; more configuration |
Migration cost
Webpack to Vite migration is moderate for standard apps and high for custom-loader-heavy apps.
- Replace
webpack.config.jswithvite.config.ts. Map aliases, define constants, and environment variable handling. - Replace
webpack-dev-serverscripts withviteinpackage.json. - Custom Webpack loaders need Vite plugin equivalents. Most common loaders (CSS, image, SVG) have Vite plugins; exotic loaders may require writing a Vite plugin.
- Remove
webpack-bundle-analyzer; userollup-plugin-visualizerinstead. - Effort: one to three engineer-days for a medium project with standard loaders. Budget a week for large apps with custom loader pipelines.
Recommendation
- New React, Vue, or Svelte project: Vite.
- New Astro or SvelteKit project: Vite is already the bundler; no choice needed.
- Existing Webpack app, standard loaders: migrate on the next major refactor. The HMR speed improvement is significant for developer experience.
- Existing app using Module Federation for microfrontends: evaluate
@originjs/vite-plugin-federationagainst your specific sharing patterns. If it works, migrate. If not, stay on Webpack.