Migrate to Vite from Create React App (CRA)

 by Robin Wieruch
 - Edit this Post

A quick migration guide to Vite from Create React App, because (apart from Next.js) Vite is the natural successor of CRA for creating a .

First, install Vite and all React related libraries (here: Vite's React Plugin) as development dependencies:

npm install vite @vitejs/plugin-react --save-dev

Second, uninstall create-react-app's dependency:

npm uninstall react-scripts

Third, adjust your package.json to use the following new scripts:

"scripts": {
"start": "vite",
"build": "vite build",
"serve": "vite preview"
},

Fourth, rename all extensions of files which are using JSX from ".js" to ".jsx", because Vite is explicit with file extensions. If you are using TypeScript, perform the same task from ".ts" to ".tsx". The following demonstrates it with the App.js file on the command line:

mv src/App.js src/App.jsx
mv src/index.js src/index.jsx

If you are not renaming all your React/JSX related files this way, essentially all files that are using angle brackets, you may get the following or a similar error:

  • The JSX syntax extension is not currently enabled
  • The esbuild loader for this file is currently set to "js" but it must be set to "jsx" to be able to parse JSX syntax. You can use "loader: { '.js': 'jsx' }" to do that.

Fifth, create a vite.config.js file in your Vite + React project's root directory:

touch vite.config.js

And add the following implementation details to it. Essentially we want to keep the same output directory for the build as we had before with create-react-app. In addition, we want to use Vite's React Plugin:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig(() => {
return {
build: {
outDir: 'build',
},
plugins: [react()],
};
});

Sixth, move the public/index.html into the project's root folder, because Vite expects it there:

mv public/index.html .

Afterward, remove all %PUBLIC_URL% occurrences in the index.html file.

- <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+ <link rel="icon" href="/favicon.ico" />
<!-- do this for all occurrences -->

Last, link the src/index.js file in your moved index.html file the following way:

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

That's it. If you have been using a create-react-app project without any further configuration (e.g. a fresh create-react-app installation), you are ready to start your new Vite based React application with npm start.

However, there may be additional steps needed which I want to outline next in case your create-react-app uses more configurations.


  • If you want to keep using ESLint in Vite as you have used it in create-react-app, follow this .
  • If you want to keep using TypeScript in Vite as you have used it in create-react-app, follow this . Optionally follow this tutorial afterward.
  • If you want to keep using react-testing-library in Vite as you have used it in create-react-app, follow this .
  • If you are using create-react-app's (CRA's) environment variables, you need to replace all REACT_APP occurrences with VITE.
  • If you are using process.env in your React project, replace it with import.meta.env.

Troubleshooting create-react-app to Vite migration ...

  • If you get ReferenceError: process is not defined from a library, check if it runs with the following workaround:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig(() => {
return {
// https://github.com/vitejs/vite/issues/1973#issuecomment-787571499
define: {
'process.env': {},
},
build: {
outDir: 'build',
},
plugins: [react()],
};
});
  • If you want to keep using SVGs in your Vite project, install vite-plugin-svgr as development dependency. Then include it in Vite's configuration file:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
export default defineConfig(() => {
return {
build: {
outDir: 'build',
},
plugins: [
react(),
// svgr options: https://react-svgr.com/docs/options/
svgr({ svgrOptions: { icon: true } }),
],
};
});
// which allows you to import SVGs as React components
// import { ReactComponent as MyIcon } from './my-icon.svg';
  • If you want to use alias imports in your Vite project, define them the following way:
import path from 'path';
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
export default defineConfig(() => {
return {
resolve: {
alias: {
'~': path.resolve(__dirname, './src'),
},
},
build: {
outDir: 'build',
},
plugins: [react()],
};
});
// which allows you to import from folders under the /src folder
// import Button from '~/components/Button';
  • If you have to support Emotion in your Vite project:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig(() => {
return {
build: {
outDir: 'build',
},
plugins: [
react({
jsxImportSource: '@emotion/react',
babel: {
plugins: ['@emotion/babel-plugin'],
},
}),
],
};
});
  • If you want to open the browser upon server start, use the following Vite config:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig(() => {
return {
server: {
open: true,
},
build: {
outDir: 'build',
},
plugins: [react()],
};
});

That's essentially it from my side. If you happen to know any other essential troubleshooting hints, let me know!

Keep reading about 

Just recently I had to use Docker for my create-react-app web application development. Here I want to give you a brief walkthrough on how to achieve it. First of all, we need a React application…

Just recently I had to use Docker for my React web application development. Here I want to give you a brief walkthrough on how to achieve it. First of all, we need a React application. Either create a…

The Road to React

Learn React by building real world applications. No setup configuration. No tooling. Plain React in 200+ pages of learning material. Learn React like 50.000+ readers.

Get it on Amazon.