---
title: "Vite vs Webpack"
slug: "vite-vs-webpack"
category: "comparisons"
tags: ["comparisons", "vite", "webpack", "bundler", "build-tools", "esm", "frontend"]
status: "stable"
last_updated: 2026-05-14
summary: "Use Vite for new projects; keep Webpack for existing apps with custom loaders or plugins that Vite cannot replicate."
related: ["[[comparisons/swc-vs-babel]]", "[[comparisons/jest-vs-vitest]]", "[[comparisons/eslint-vs-biome]]", "[[frontend/index]]", "[[comparisons/nextjs-vs-astro]]", "[[comparisons/yarn-vs-pnpm]]", "[[coding/general-principles]]"]
---

## 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 [[comparisons/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-vite` generates 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.ts` is 10 to 20 lines for most projects. Webpack configs for equivalent functionality run to 100+ lines.

```ts
// 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 `ModuleFederationPlugin` is 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.js` with `vite.config.ts`. Map aliases, define constants, and environment variable handling.
- Replace `webpack-dev-server` scripts with `vite` in `package.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`; use `rollup-plugin-visualizer` instead.
- 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-federation` against your specific sharing patterns. If it works, migrate. If not, stay on Webpack.

## Related

- [[comparisons/swc-vs-babel]]
- [[comparisons/jest-vs-vitest]]
- [[comparisons/eslint-vs-biome]]
- [[frontend/index]]
- [[comparisons/nextjs-vs-astro]]
- [[comparisons/yarn-vs-pnpm]]
- [[coding/general-principles]]
