Vite Configuration for a React App
Vite has become the dominant build tool for modern React, Vue, and Svelte applications because it solves the two most painful aspects of traditional bundler-based development: slow startup times and slow hot module replacement. Where webpack rebuilds and re-bundles the entire dependency graph on startup, Vite serves source files directly using native ES modules during development and only transforms changed modules when they're requested. A cold start that takes 30 seconds in webpack takes under a second in Vite. This configuration covers the four most commonly needed Vite customizations. The plugins: [react()] line is required for JSX transformation and React Fast Refresh (which preserves component state during hot reloads). Without this plugin, JSX syntax causes a parse error and hot reloads lose component state on every save. Path alias resolution with resolve.alias: the @ alias maps to the src directory, enabling clean imports like import Button from '@/components/Button' instead of '../../../components/Button'. This alias must be configured in two places: vite.config.ts (so Vite's bundler resolves the path correctly) and tsconfig.json's paths option (so TypeScript's type checker resolves the same paths). They must match exactly — a mismatch causes TypeScript to report import errors that Vite itself doesn't care about. The development proxy is one of Vite's most practical features: any request to the Vite dev server that starts with /api is forwarded to http://localhost:8000. The browser sees both the frontend and the API as being on the same origin (localhost:3000), so CORS headers are not needed during development. changeOrigin: true rewrites the Host header to match the target server. The rewrite function strips the /api prefix before forwarding. Build optimization with manualChunks: by default, Vite bundles everything into one JavaScript file. With manualChunks: { vendor: ['react', 'react-dom'] }, the react and react-dom libraries are split into a separate vendor.js chunk. Since React's version changes infrequently, this chunk gets a long cache lifetime in browsers. Only the main application chunk needs to be re-downloaded when your application code changes. Real-world customizations: adding import.meta.env support for environment variables, configuring separate chunks for different parts of a large application (reducing initial bundle size), enabling Progressive Web App support with the vite-plugin-pwa plugin, and integrating Storybook with the same Vite configuration. Tips: use vite build --analyze to generate a visual bundle analysis report showing which packages contribute most to your bundle size. This helps identify which packages are candidates for code-splitting or replacement with smaller alternatives.
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@components': path.resolve(__dirname, './src/components'),
},
},
server: {
port: 3000,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/api/, ''),
},
},
},
build: {
rollupOptions: {
output: {
manualChunks: { vendor: ['react', 'react-dom'] },
},
},
},
});FAQ
- How do I set up path aliases in Vite?
- Configure the alias in resolve.alias in vite.config.ts and add matching paths in tsconfig.json. Both must match for TypeScript to resolve types and Vite to bundle correctly.
- What does the Vite dev proxy do?
- The proxy forwards requests from the Vite dev server to a separate backend server. This avoids CORS issues during development by making the browser think both frontend and API are on the same origin.
- Why split vendor chunks in the build?
- Separating vendor libraries (React, Lodash, etc.) into a separate chunk means that when only your application code changes, users' browsers can use the cached vendor bundle without re-downloading it.
Related Examples
TypeScript's strict mode is the single highest-leverage configuration option for...
Prettier Configuration FilePrettier is an opinionated code formatter with a deliberate design philosophy: i...
Format a tsconfig.json FileTypeScript projects live and die by their tsconfig.json. A misindented block, an...