Quick Answer

Webpack bundles everything up front, so dev start time grows with project size. Vite serves source files as native ES modules and transforms them on demand, so start time is roughly constant. For production both bundle.

Why bundlers exist at all

Browsers historically had no module system. A project with 500 files meant 500 script tags in the right order, or a build step combining them into one.

Bundlers also do things browsers cannot: transform TypeScript and JSX into JavaScript, resolve node_modules imports, tree-shake unused code, split bundles by route, and handle CSS and image imports.

Webpack solved this comprehensively and became the standard. Its cost is configuration and speed — a large project can take a minute or more to start the dev server, and that delay is paid every time you restart.

The thing that changed is that browsers now support ES modules natively. A browser can follow import statements itself, which makes bundling optional during development.

How Vite uses that

In development, Vite does almost no bundling. It starts a server immediately and serves your files as native modules. When the browser requests App.jsx, Vite transforms that one file and returns it.

The consequences:

  • Cold start is roughly constant regardless of project size, because nothing is built up front.
  • Updates are near-instant. Changing one file means re-transforming one file, not rebuilding a bundle.
  • Hot module replacement stays fast as the project grows, which is where Webpack degrades most noticeably.

Dependencies are handled differently — Vite pre-bundles node_modules once with esbuild, because a library split across hundreds of small files would mean hundreds of requests. That pre-bundle is cached, so it happens on first run and after dependency changes.

For production, Vite does bundle, using Rollup. Native modules are excellent for development and still not ideal for shipping, where request count and long-term caching matter.

Configuration

A meaningful difference in practice.

// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
})

That is a complete React setup. TypeScript, JSX, CSS, images and environment variables work with no further configuration.

The equivalent Webpack configuration involves entry and output, loaders for each file type, plugins for HTML and CSS extraction, and dev server settings — commonly a hundred lines or more, and historically a genuine barrier for beginners.

Webpack's defence is that the configuration exists because it handles cases Vite's defaults do not. For an unusual build pipeline, that flexibility is the reason to use it.

When Webpack is still right

Being fair to it, since "Webpack is obsolete" is a common overstatement.

  • An existing project. A working Webpack build is not worth migrating for its own sake. The gain is developer experience, not user-facing.
  • Module Federation for micro-frontends is a Webpack feature with no direct equivalent.
  • Unusual requirements. Its loader and plugin ecosystem is enormous, and for a genuinely non-standard pipeline there may be a Webpack plugin and no Vite one.
  • Supporting very old browsers. Vite's dev server assumes native ES module support; production builds can target older browsers but the story is simpler with Webpack.

For a new project, Vite is the sensible default. Framework starters — React, Vue and Svelte — now use it by default, which is itself a strong signal.

Practical notes

  • Start with a template: npm create vite@latest and choose your framework. It is faster than configuring anything by hand.
  • Environment variables must be prefixed with VITE_ to be exposed to client code. This is deliberate — it stops server secrets leaking into the bundle by accident, and it is the first thing that confuses people migrating.
  • Development and production differ. Dev is unbundled, production is Rollup. Test the production build before deploying; "works in dev, breaks in build" is nearly always an import or environment assumption.
  • Bundle analysis still matters. Fast builds do not mean small bundles — check what you ship, since bundle size drives Core Web Vitals.

Frequently Asked Questions

Why is Vite's dev server so much faster to start? It does not bundle in development. It serves source files as native ES modules and transforms each on request, so start time barely grows with project size.
Does Vite bundle for production? Yes, using Rollup. Native modules suit development but production still benefits from bundling for fewer requests and better long-term caching.
Should I migrate an existing Webpack project? Not for its own sake. The benefit is developer experience rather than anything users see. Migrate when the slow feedback loop is genuinely costing time.
Why are my environment variables undefined in Vite? Only variables prefixed with VITE_ are exposed to client code. This is deliberate, so server-side secrets are not accidentally bundled into the browser.
Is Webpack dead? No. It remains widely deployed, and features such as Module Federation have no direct Vite equivalent. Vite is the better default for new projects.