React + Vite Best Practices
Comprehensive performance optimization guide for React applications built with Vite. Contains 40+ rules across 8 categories, prioritized by impact to guide code generation and refactoring.
When to Apply
Reference these guidelines when:
- Configuring Vite for React projects
- Implementing code splitting and lazy loading
- Optimizing build output and bundle size
- Setting up development environment
- Reviewing code for performance issues
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|----------|----------|--------|--------|
| 1 | Build Optimization | CRITICAL | build- |
| 2 | Code Splitting | CRITICAL | split- |
| 3 | Development Performance | HIGH | dev- |
| 4 | Asset Handling | HIGH | asset- |
| 5 | Environment Config | MEDIUM | env- |
| 6 | HMR Optimization | MEDIUM | hmr- |
| 7 | Bundle Analysis | LOW-MEDIUM | bundle- |
| 8 | Advanced Patterns | LOW | advanced- |
Quick Reference
1. Build Optimization (CRITICAL)
build-manual-chunks- Configure manual chunks for vendor separationbuild-minify-terser- Use Terser for production minificationbuild-target-modern- Target modern browsers for smaller bundlesbuild-sourcemap-production- Configure sourcemaps appropriatelybuild-output-structure- Organize output directory structurebuild-chunk-size-limit- Set appropriate chunk size warnings
2. Code Splitting (CRITICAL)
split-route-lazy- Use React.lazy() for route-based splittingsplit-suspense-boundaries- Wrap lazy components with Suspensesplit-dynamic-imports- Use dynamic imports for heavy componentssplit-preload-critical- Preload critical chunks on interactionsplit-named-chunks- Use named chunks for better cachingsplit-vendor-separation- Separate vendor from application code
3. Development Performance (HIGH)
dev-dependency-prebundling- Configure dependency pre-bundlingdev-exclude-large-deps- Exclude large deps from optimizationdev-warmup-frequent- Warmup frequently used modulesdev-server-config- Optimize dev server configurationdev-hmr-overlay- Configure HMR error overlay
4. Asset Handling (HIGH)
asset-inline-limit- Set appropriate asset inline limitasset-public-dir- Configure public directory correctlyasset-import-syntax- Use correct asset import syntaxasset-svg-components- Handle SVGs as React componentsasset-image-optimization- Optimize image loadingasset-font-loading- Optimize font loading strategy
5. Environment Configuration (MEDIUM)
env-vite-prefix- Use VITE_ prefix for client variablesenv-type-definitions- Type environment variablesenv-mode-specific- Use mode-specific env filesenv-sensitive-data- Never expose sensitive dataenv-build-time- Understand build-time replacement
6. HMR Optimization (MEDIUM)
hmr-fast-refresh- Ensure Fast Refresh works correctlyhmr-preserve-state- Preserve component state during HMRhmr-boundary-setup- Set up proper HMR boundarieshmr-custom-handlers- Implement custom HMR handlers
7. Bundle Analysis (LOW-MEDIUM)
bundle-visualizer- Use rollup-plugin-visualizerbundle-analyze-deps- Analyze dependency sizesbundle-tree-shaking- Ensure proper tree shakingbundle-dead-code- Eliminate dead codebundle-css-splitting- Configure CSS code splitting
8. Advanced Patterns (LOW)
advanced-ssr-config- Configure for SSR if neededadvanced-library-mode- Build as libraryadvanced-multi-page- Multi-page application setupadvanced-worker-threads- Web Worker integrationadvanced-wasm- WebAssembly integration
Essential Configurations
Recommended vite.config.ts
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'),
},
},
build: {
target: 'esnext',
minify: 'terser',
sourcemap: false,
chunkSizeWarningLimit: 500,
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
router: ['react-router-dom'],
},
},
},
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
},
optimizeDeps: {
include: ['react', 'react-dom'],
},
server: {
port: 3000,
open: true,
hmr: {
overlay: true,
},
},
})
Route-Based Code Splitting
import { lazy, Suspense } from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
// Lazy load route components
const Home = lazy(() => import('./pages/Home'))
const Dashboard = lazy(() => import('./pages/Dashboard'))
const Settings = lazy(() => import('./pages/Settings'))
// Named chunks for better debugging
const Profile = lazy(() =>
import(/* webpackChunkName: "profile" */ './pages/Profile')
)
function App() {
return (
<BrowserRouter>
<Suspense fallback={<LoadingSpinner />}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
<Route path="/profile" element={<Profile />} />
</Routes>
</Suspense>
</BrowserRouter>
)
}
Environment Variables
// src/vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
readonly VITE_ENABLE_ANALYTICS: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
// Usage
const apiUrl = import.meta.env.VITE_API_URL
const isDev = import.meta.env.DEV
const isProd = import.meta.env.PROD
How to Use
Read individual rule files for detailed explanations and code examples:
rules/build-manual-chunks.md
rules/split-route-lazy.md
rules/_sections.md
Each rule file contains:
- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references