Migrating from Create React App to Vite: A Modern Approach

Adhithi Ravichandran
4 min readFeb 20, 2025

--

Photo by Markus Spiske on Unsplash

Create React App is Deprecated — Time to Move On!

For years, Create React App (CRA) was the go-to tool for setting up React projects quickly. However, as of Feb 2025, CRA is officially sunset. The React team no longer recommends using it due to slow build times, outdated configurations, and lack of support for modern features like ES modules and native ESM-compatible dependencies.

If you are still using CRA, it’s time to migrate. I have worked with a lot of teams, and in my opinion if you have a SPA application that doesn’t need the latest nuts and bolts like React Server Components, then Vite is the best option. There are other options too for complex apps, and you can checkout my earlier blog on React is Deprecating Create React App: What’s Next for React Developers?

Vite a fast, modern build tool that offers instant hot module replacement (HMR), optimized builds, and better DX (Developer Experience).

In this guide, I walk through how to migrate your existing CRA project to Vite in just a few simple steps.

Why Choose Vite ?

Vite, developed by the Vue.js creator Evan You, has quickly become the preferred choice for modern frontend development. Here’s why:

Super-Fast Development

Vite leverages ES modules (ESM) and an optimized dependency pre-bundling process, making development incredibly fast. Unlike CRA, which processes all dependencies at runtime, Vite pre-bundles dependencies using esbuild, significantly reducing cold-start times. This means near-instant feedback when making changes.

Instant Hot Reloading

Unlike CRA, where hot module replacement (HMR) can sometimes be slow or unreliable, Vite provides truly instant updates with no page reload required. Changes are reflected in real time, making the development experience smoother and more efficient.

Optimized Builds

Vite uses Rollup as its bundler for production builds, ensuring efficient tree-shaking, code-splitting, and smaller bundle sizes. This results in faster load times for end users and better overall application performance.

Better ESM Support

CRA relies heavily on Webpack and Babel for module bundling, which can introduce unnecessary complexity and slower transpilation times. Vite natively supports ES modules (ESM) and can handle modern JavaScript without needing Babel in most cases, leading to significantly faster builds.

No More Webpack Config Hassles

Webpack configurations in CRA can be complex and difficult to customize. Vite eliminates this burden with a plugin-based system that provides sensible defaults while allowing easy customization through a simple configuration file (vite.config.js). This makes it much more developer-friendly and flexible.

Step-by-Step Guide: Migrating CRA to Vite

Here is a quick step-by-step guide to move to Vite from your basic CRA app.

Uninstall Create React App

Since we’re moving away from CRA, start by removing the CRA-specific dependencies:

npm uninstall react-scripts

or if you are using yarn

yarn remove react-scripts

Install Vite and Necessary Plugins

Vite requires its own React plugin to handle JSX and React Fast Refresh.

Run the following command:

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

Update package.json Scripts

Replace the old CRA scripts in your package.json:

"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
}

Move and Modify index.html

In CRA, the index.html file is inside public/. Vite requires it at the project root.

Move public/index.html to the root folder and update the script tag:

<script type="module" src="/src/main.jsx"></script>

Create vite.config.js

To customize your Vite setup, create a vite.config.js file in the root:

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

export default defineConfig({
plugins: [react()],
build: {
outDir: 'build', // CRA's default build output
},
});

Update Static Asset Handling

CRA automatically serves files inside public/. In Vite, reference static assets directly in public/ or import them in JavaScript.

CRA:

<img src={process.env.PUBLIC_URL + "/logo.png"} />

Vite:

<img src="/logo.png" />

Adjust Environment Variables

CRA uses REACT_APP_ prefixes for environment variables, but Vite uses VITE_.

Rename .env variables from:

REACT_APP_API_KEY=yourapikey

To:

VITE_API_KEY=yourapikey

And access them as follows:

const apiKey = import.meta.env.VITE_API_KEY;

Handle CSS and Global Styles

If your CRA project relies on index.css, import it explicitly inside main.jsx:

import './index.css';

For CSS Modules, Vite supports .module.css files out of the box:

import styles from './App.module.css';

Migrate Testing (If you have Jest tests)

If you’re using Jest, you might want to switch to Vitest, a testing framework optimized for Vite.

Install Vitest:

npm install vitest --save-dev

Update package.json test script:

"scripts": {
"test": "vitest"
}

Configure Vitest in vite.config.js

test: {
globals: true,
environment: 'jsdom',
setupFiles: './src/setupTests.js',
},

Final Steps: Run Your Vite App!

You’re now ready to start your new Vite-powered React app! Run:

npm run dev

This starts a fast development server.

Wrapping Up: Why This Migration is Worth It

Migrating from CRA to Vite is a game-changer. You will experience faster development, better build times, and modern React tooling. With CRA officially deprecated, moving to Vite ensures your React projects stay up-to-date with the latest best practices.

Alright folks, that’s a wrap! Hope you enjoyed this article!

For information on my consulting services visit: adhithiravichandran.com

To stay connected follow me @AdhithiRavi or Linkedin/adhithi

You can checkout my courses on React, Next.js and other topics here:

https://app.pluralsight.com/profile/author/adhithi-ravichandran

--

--

Adhithi Ravichandran
Adhithi Ravichandran

Written by Adhithi Ravichandran

Software Consultant, Author, Speaker, React|Next.js|React Native |GraphQL|Cypress|Playwright Dev & Indian Classical Musician

No responses yet