Skip to content
Mert Yılmaz
CVTürkçeContact
All posts

How to migrate from Create React App to Vite

Published

Short answer

Install vite and @vitejs/plugin-react, move index.html from public/ to the project root and load your entry file with a module script, rename files that contain JSX to .jsx, change REACT_APP_ environment variables to VITE_, and replace the react-scripts commands with vite. When I migrated a production app at SubmitApp, build performance improved about 3 times.

1. Swap the dependencies

Remove react-scripts and add Vite with its React plugin.

npm uninstall react-scripts
npm install -D vite @vitejs/plugin-react

2. Move index.html to the project root

Create React App injects your bundle for you. Vite does not, so index.html lives in the project root and points at your entry file explicitly. Remove every %PUBLIC_URL% placeholder, because files in public/ are served from the site root.

<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>

3. Add vite.config.js

Enable the React plugin. If your deployment expects the old build folder, set outDir to build, because Vite defaults to dist.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  server: { port: 3000 },
  build: { outDir: "build" },
});

4. Rename files that contain JSX

Vite only parses JSX in files ending in .jsx or .tsx. Rename every .js file that contains JSX, including src/index.js and src/App.js, and update the imports and the script tag in index.html.

5. Change environment variables

Vite only exposes variables that start with VITE_, and reads them from import.meta.env instead of process.env.

  • Rename REACT_APP_API_URL to VITE_API_URL in your .env files.
  • Replace process.env.REACT_APP_API_URL with import.meta.env.VITE_API_URL in code.
  • Replace process.env.NODE_ENV checks with import.meta.env.MODE, or import.meta.env.DEV and import.meta.env.PROD.

6. Update the scripts and check what else breaks

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview"
}
  • Absolute imports set through jsconfig.json baseUrl need a resolve.alias entry in vite.config.js.
  • SVGs imported as React components need the vite-plugin-svgr plugin.
  • Jest tests need to move to Vitest, which uses almost the same API.

Run npm run build and npm run preview, then click through your main routes. Most failures at this stage are a missed environment variable or a file still named .js that contains JSX.

Questions

Does Vite need the .jsx extension?
Yes. By default Vite only transforms JSX in files ending in .jsx or .tsx, so rename .js files that contain JSX.
What replaces process.env in Vite?
import.meta.env. Only variables that start with VITE_ are exposed to client code.
What replaces Jest when moving from Create React App?
Vitest. It reads your Vite config and has an API very close to Jest, so most tests need few changes.
Will the build folder change?
Yes, Vite writes to dist by default. Set build.outDir to build in vite.config.js if your hosting expects the old folder.

I do this kind of work

Written by Mert Yılmaz, freelance fullstack developer.