9.1 · difficulty 2/4 · 12 min read
React + Vite 8
A deep dive into @vitejs/plugin-react v6 — how OXC Refresh replaces Babel, how to integrate React Compiler, and the current state of the React ecosystem in Vite 8.
Vite 8.1Stable
@vitejs/plugin-react v6: The OXC Era
@vitejs/plugin-react v6, bundled with Vite 8, is a major upgrade to React integration:
| Dimension | v5 (Vite 7 era) | v6 (Vite 8 era) |
|---|---|---|
| Fast Refresh impl | Babel + babel-plugin-react-refresh | OXC (Rust) |
| Babel dependency | ✅ Required | ❌ Optional |
| Startup speed | Baseline | Noticeably faster |
| JSX transform | Babel | OXC |
| React Compiler | Manual configuration | reactCompilerOptions |
The configuration syntax is unchanged:
ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
export default defineConfig({
plugins: [react()],
// ↑ Identical syntax for both v5 and v6
})How OXC Refresh Works
OXC (Oxidation Compiler) implements the AST transforms required by React Fast Refresh in Rust:
- Detect React components: Scans the file for function declarations and expressions, identifying which ones are React components (capitalized name, returns JSX)
- Inject HMR code: Appends
import.meta.hot.accept()and component registration at the end of each component file - Handle hooks: Tracks hook calls to ensure Fast Refresh rules are satisfied
This entire process runs in Rust — no Babel process to spawn, no AST serialization or deserialization.
Recommended TypeScript Configuration
json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "react-jsx",
"strict": true,
"noEmit": true
}
}Integrating React Compiler (Vite 8)
React Compiler (formerly React Forget) is an automatic memoization compiler introduced in React 19. To enable it in Vite 8:
ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
export default defineConfig({
plugins: [
react({
// Enable React Compiler
babel: {
plugins: [
[
"babel-plugin-react-compiler",
{
target: "19", // React 19
},
],
],
},
}),
],
})Common Configuration Scenarios
Path Aliases
ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import { resolve } from "node:path"
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": resolve("src"),
"@components": resolve("src/components"),
"@utils": resolve("src/utils"),
},
},
})TypeScript Types for Environment Variables
ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string
readonly VITE_APP_TITLE: string
}
interface ImportMeta {
readonly env: ImportMetaEnv
}Self-check
- After
@vitejs/plugin-reactv6 replaced Babel with OXC, which part of the development workflow becomes faster? - If your project needs certain Babel plugins (e.g., the styled-components
babel-plugin), can you still use v6? How would you configure it? - What does
"moduleResolution": "Bundler"mean intsconfig.json? How does it differ from"Node16"? - What problem does React Compiler solve? Why does it need Babel instead of OXC?
ts
// Configure a complete React + TypeScript + Vite 8 project with:
// 1. Path alias: @ → src/
// 2. Global CSS variables injected via CSS Modules or PostCSS
// 3. Environment variable: VITE_API_BASE_URL
// 4. Production build config: sourcemap disabled, vendor chunk splitting
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
import { resolve } from "node:path"
export default defineConfig(({ command }) => ({
plugins: [react()],
// TODO: complete configuration
}))