Vite Setup for Web Projects: Configuration, Plugins, Optimization
Developing a large React app with Webpack means constant slowdowns: cold start of the dev server takes up to a minute, and HMR rebuilds half the modules when you change one component. Teams lose hours daily waiting. Vite solves this radically—it uses the browser's native ES modules in dev mode and Rollup for production. Cold start: 0.3–0.5 seconds instead of 30–60, HMR updates only the changed file, no neighbor rebuilds. We, engineers with 5+ years in build tools, can configure Vite for your project in 1–2 days.
Why Vite is faster than Webpack?
Vite uses two key mechanisms. In development, the browser requests files as separate ES modules—Vite transforms them on the fly via esbuild, which is tens of times faster than Webpack bundler (Vite documentation). Hot Module Replacement (HMR) works pointwise: when a file changes, Vite sends only that module to the browser, not an entire chunk. Webpack rebuilds the whole dependency graph. In production, Vite delegates bundling to Rollup, which is more efficient at tree-shaking and code-splitting. In one of our projects, migrating from Webpack to Vite reduced build time from 45 seconds to 3 seconds, and the first chunk size dropped by 60%. As a result, the client saved $2,400 per year on hosting, and the team saved $3,000 per month in build waiting time.
| Parameter | Webpack 5 | Vite + Rollup |
|---|---|---|
| Cold start dev | 30-60 s | 0.3-0.5 s |
| HMR (single file) | chunk update (5-10 s) | module update (50-200 ms) |
| Production build | 60-120 s | 15-30 s |
| First chunk size (lazy) | ~200 KB | ~50 KB |
These numbers aren't theory—they're real measurements from a project with 500+ React components.
How to configure Vite for your project?
What's included in a turnkey Vite setup
| Component | What we do |
|---|---|
| Configuration of vite.config.ts | Setup for React/Vue/Svelte, TypeScript, CSS/PostCSS |
| Path aliases | Sync with tsconfig, convenient imports @/components |
| Proxy for API | Proxying to backend (REST, WebSocket) |
| Environment variables | .env.dev/.prod, strict typing via ImportMetaEnv |
| Code splitting | manualChunks for vendor libraries, lazy loading via React.lazy |
| Production optimization | minify (esbuild), sourcemaps, Tree-Shaking |
| Plugins (SVGR, PWA, legacy) | Connected as needed |
Details on Vite plugins
We only connect necessary plugins: @vitejs/plugin-react-swc for fast compilation, vite-plugin-svgr for SVG handling, vite-plugin-pwa for progressive web apps. All plugins are configured individually.Timeline: from a few hours to 1 day for a new project, up to 2 days for migration from Webpack. Over 30 successful projects are the best quality guarantee. Get a consultation from a Vite engineer.
How we set up Vite: process
- Audit current project (stack, dependencies, configs).
- Create an aggressive profile: identify LCP, CLS, INP growth points.
- Configure vite.config.ts: basic settings, aliases, proxy.
- Connect plugins: @vitejs/plugin-react-swc, svgr, vite-plugin-checker, VitePWA.
- Set up code splitting: split vendor chunks, async page loading.
- Production optimization: minification, tree-shaking, bundle analysis via rollup-plugin-visualizer.
- Test build: check TTFB, LCP, bundle size.
- Deploy: integrate with Vercel, Cloudflare Pages, or your hosting.
Example of a full config
import { defineConfig, loadEnv } from 'vite' import react from '@vitejs/plugin-react-swc' import path from 'path' export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd(), '') return { plugins: [react()], resolve: { alias: { '@': path.resolve(__dirname, './src'), }, }, server: { port: 3000, proxy: { '/api': { target: env.VITE_API_URL ?? 'http://localhost:8000', changeOrigin: true, rewrite: (p) => p.replace(/^\/api/, ''), }, }, }, build: { rollupOptions: { output: { manualChunks: { 'vendor-react': ['react', 'react-dom'], }, }, }, }, } }) How to set up code splitting?
Code splitting is one of the most effective ways to reduce bundle size. Vite uses Rollup for manual splitting: in the config build.rollupOptions.output.manualChunks group libraries. For a React project, separate vendor-react (react, react-dom), vendor-router (react-router-dom), vendor-query (@tanstack/react-query). Then on page load, the browser only downloads needed chunks—users get content faster.
export default defineConfig({ build: { rollupOptions: { output: { manualChunks: { 'vendor-react': ['react', 'react-dom'], 'vendor-router': ['react-router-dom'], 'vendor-query': ['@tanstack/react-query'], }, chunkFileNames: 'assets/js/[name]-[hash].js', }, }, }, }) Additionally, use React.lazy() for async page loading. One of our cases: on a site with 50+ pages, we managed to reduce the initial bundle from 800 KB to 150 KB—by lazy loading the admin panel.
Common issues when setting up Vite
- Hydration mismatch with SSR: solved by syncing client/server in Next.js or Nuxt.
- Errors with aliases: mandatory sync between tsconfig and vite.config.
- Proxy not working for WebSocket: need to set
ws: trueand target with ws:// protocol.
All these issues we resolve within the setup.
Cost and timeline
Timeline: from 1 day to 2 days depending on project complexity. Cost is calculated individually after audit. Contact us—we will analyze your project and propose an optimal Vite configuration. Order Vite setup and speed up development 10x.







