How to Upgrade Create React App to Vite
This article aims to explain on how to transition your project from Create React App (CRA) to Vite. I've been working with React since 2019, and setting up react project with CRA is as simple as openning up tabs in Google Chrome. However over time I experienced:
- Slow project startup
- Slow Hot Module Replacement (HMR)
- Slow package installation
- No support for path aliases
To overcome these dev frustrations, what could be done? The simple answer was moving away from CRA and adopting Vite. When I did this:
- Instant developement server startup
- Lighting fast Hot Module Replacement (HMR)
- Faster package installation
- Now I can use path aliases
💡One primary reason for this change is that CRA will no longer
receive major updates and is deprecated by the React team in 2023.
Prerequisites
Before starting the conversion from Create React App (CRA) to Vite, We need to make sure of the following crucial requirements:
-
Node.js and npm:
Ensure you have Node.js and npm installed on your system, preferably version 14.x or higher, as Vite requires Node.js 14.18+. I am using Node.js version 20.7.0. You can verify your installations by running:
node -v npm -v
-
Basic Understanding of Vite: Before starting transition to Vite, make yourself familar with Vite Guide. You can also make a new vite project to understand the differences in project structure between vite and CRA.
-
Backup Your Project: Before making any significant changes, create a backup of your current CRA project to prevent any data loss. You can do this by copying the entire project directory to a safe location or use a version control system like
.git
. -
Install Vite: You will need to install Vite and its dependencies in your project. This can be done through npm or yarn once you have started upgrading to Vite.
-
Understanding of Your Project Structure: Have a good understanding of your current CRA project structure, including the configuration files, entry points, and where static assets are located. This knowledge is crucial for correctly configuring Vite. Once these prerequisites are in place, you are good to go with the steps to upgrade your CRA project to Vite.
Steps to Upgrade to Vite
1. Set up Vite
First, set up a new Vite project within your existing CRA project. Start by following these steps:
-
Install Vite:
Navigate to your CRA project directory and install Vite along with the necessary vite plugins according to your project.
npm install vite @vitejs/plugin-react
-
Update package.json Scripts
Since Vite will handle the build and development processes, react-scripts are no longer needed. Remove it from your project by running:
npm uninstall react-scripts
Update the scripts in your package.json to use Vite instead of the CRA scripts. Replace the existing scripts section with:
"scripts": { "start": "PORT=3000 NODE_ENV=development vite", "start-secure": "NODE_ENV=development && HTTPS=true vite", "build": "tsc && vite build", "preview": "vite preview" }
If you've setup ESLint,
"format": "npx prettier --write .", "lint": "eslint '*/**/*.{js,ts,tsx}' --quiet --fix"
2. Configure Vite
Create a vite.config.mts file in the root of your project and configure Vite for your React setup. In order to remain as close to create react app as possible I have set the build directory to build folder instead of dist and also set the development server port to 3000:
import react from "@vitejs/plugin-react";
import path from "path";
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"), // Create an alias "@" to refer to the "./src" directory
},
},
build: {
outDir: "./build", // Specify the output directory for the production build, matching CRA's default output directory
},
server: {
port: 3000, // Specify the port on which the development server will run
},
})
3. Update index.html
In Vite, the entry HTML file should be placed in the root directory. Move your CRA public/index.html to the root of the project and update the script reference:
- Move public/index.html to the project root.
- Modify the
<script>
tag to point to the Vite entry:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Meta Tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1, user-scalable=no"
/>
<!-- Favicon -->
<link rel="shortcut icon" href="/favicon.svg" />
<!-- General Description -->
<meta name="description" content="My Vite App Description" />
<title>My Vite App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
4. Adjust Project Strucuture
Ensure that your index.ts
or index.tsx
file is in the src directory and rename it to main.tsx
to match the script reference in index.html.
5. Update Imports
I used path aliases to keep import statements cleaner and more maintainable. This is done above in vite.config.mts . For example, you can import components like this:
import MyComponent from '@/components/MyComponent';
6. Migrate Static Assets
Vite handles static assets differently than CRA. Move all your static assets from the public folder to the src/assets folder and update the import paths in your components. For example, if you have an image in public/images/logo.png, move it to src/assets/images/logo.png and update the import in your component:
import logo from './assets/images/logo.png'
7. Install Necessary Plugins
Vite has a plugin system similar to CRA's webpack configuration. Install any necessary Vite plugins to handle features your project needs, such as environment variables, CSS preprocessing, or other custom functionalities.
8. Typescript Configuration
In order to use TypeScript, you'll need to configure tsconfig.json
and tsconfig.node.json
:
- tsconfig.json: Create a tsconfig.json file in the root of your project with the following configuration:
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"jsx": "react-jsx"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
- tsconfig.node.json: Create a tsconfig.node.json file for Vite-specific TypeScript settings:
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "bundler",
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true},
"include": ["vite.config.ts"]
}
You can read in detail about these configuration using this link: https://www.typescriptlang.org/tsconfig/
9. Remove react-env.d.ts and Add vite-env.d.ts
Replace react-env.d.ts
with vite-env.d.ts
to ensure the correct TypeScript types are used for Vite:
- Remove react-env.d.ts: Delete the react-env.d.ts file from your project.
- Add vite-env.d.ts: Create a new file named vite-env.d.ts in the src directory with the following content:
/// <reference types="vite/client" />
10. Test and Debug
Start the Vite development server to ensure everything is working correctly:
npm run start
11. Build for Production
In order to build the project for production use:
npm run build
12. Test the Build Output
To run production build locally, use serve
:
npx serve -s build