This guide will help you migrate your existing Create React App (Webpack) project to Vite for faster development and optimized builds.
- ⚡ Lightning Fast - Instant server start and HMR
- 🔧 Modern Tooling - Built on native ES modules
- 📦 Optimized Builds - Smaller bundle sizes with Rollup
- 🎯 Better DX - Simpler configuration and faster feedback
npm install vite @vitejs/plugin-react --save-devCreate a vite.config.js file in your project root:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
open: true
},
build: {
outDir: 'build',
sourcemap: true
}
});Move public/index.html to the project root and update it:
Before (public/index.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>After (index.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>Rename src/index.tsx to src/main.tsx (or keep it as index.tsx and update the script tag in index.html):
src/main.tsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);Replace all REACT_APP_ prefixed environment variables with VITE_ prefix:
Before (.env):
REACT_APP_API_URL=https://api.example.com
REACT_APP_ENV=production
After (.env):
VITE_API_URL=https://api.example.com
VITE_ENV=production
Update code references:
// Before
const apiUrl = process.env.REACT_APP_API_URL;
// After
const apiUrl = import.meta.env.VITE_API_URL;Replace %PUBLIC_URL% with absolute paths:
Before:
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<img src={process.env.PUBLIC_URL + '/logo.png'} />After:
<link rel="icon" href="/favicon.ico" />
<img src="/logo.png" />Update tsconfig.json to include Vite types:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}Create tsconfig.node.json for Vite config:
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}Create src/vite-env.d.ts:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_ENV: string;
// Add other env variables here
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}While the Catalyst CLI will handle this automatically, you can update your package.json scripts:
{
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}
}Run the Catalyst CLI commands to verify everything works:
# Validate the project
catalyst serve
# Build for production
catalyst deploySolution: Vite uses native ES modules. Ensure all imports use file extensions or are properly configured in vite.config.js:
export default defineConfig({
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js']
}
});Solution: Vite handles CSS differently. Import CSS files directly:
import './App.css'; // This works in ViteSolution: Use Vite's asset import or the React plugin's SVG support:
// As URL
import logoUrl from './logo.svg';
<img src={logoUrl} />
// As React component (with @vitejs/plugin-react)
import { ReactComponent as Logo } from './logo.svg?react';
<Logo />Solution: Remember to:
- Prefix with
VITE_instead ofREACT_APP_ - Use
import.meta.envinstead ofprocess.env - Restart the dev server after changing .env files
Solution: Configure the output directory in vite.config.js:
export default defineConfig({
build: {
outDir: 'build' // or 'dist'
}
});If you need to rollback to Webpack:
- Remove or rename
vite.config.js - The plugin will automatically detect and use Webpack
- Revert environment variable changes
- Move
index.htmlback topublic/directory
After migration, you should see:
- Dev server start: ~10-50x faster
- HMR updates: Near-instant
- Build time: 20-50% faster
- Bundle size: 10-30% smaller
- Review Vite documentation for advanced features
- Optimize your build with code splitting
- Configure PWA support
- Set up environment-specific builds
- Check the Build Tool Detection documentation
- Review Vite's troubleshooting guide
- Open an issue on the plugin repository