DEV Community

Henrique Jensen
Henrique Jensen

Posted on

Migrating from create-react-app to Vite: A Quick and Easy Guide

In recent times, React has shifted its recommendation from using create-react-app (CRA) as the starting point for new projects. Instead, it now encourages developers to use a framework for most projects. However, for smaller projects, a full-fledged framework might not be necessary. In such cases, Vite) emerges as a promising option. Vite is not a framework like Next.js or Remix, but it offers several features that make it an excellent choice for small projects, such as personal portfolios, like my portfolio. In this blog post, we will walk you through the steps to migrate from create-react-app to Vite for your next project.

Migration steps

These migration steps assume that we have a CRA project with Typescript.

  1. Removing CRA
  2. Installing Vite dependencies
  3. Moving index.html
  4. Adding vite.config.ts
  5. Adding vite-env.d.ts
  6. Adding vite scripts
  7. Fixing tsconfig.json
  8. Migrating from Jest to Vitest
  9. Extra

Step 1 - Removing CRA

The first step is to uninstall create-react-app from your project.

npm uninstall react-scripts
Enter fullscreen mode Exit fullscreen mode

Step 2 - Installing Vite dependencies

Next, install the required dependencies for Vite.

npm install vite @vitejs/plugin-react-swc vite-tsconfig-paths vite-plugin-svgr
Enter fullscreen mode Exit fullscreen mode

Note: Depending on your specific needs, you can choose a different plugin from the official Vite plugins documentation.

Step 3 - Moving index.html

create-react-app uses public/index.html as the default entry point, while Vite looks for index.html at the root level. To make the transition, move your index.html to the root directory and update the script tag accordingly.

<!-- index.html -->
<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div>

  <script type="module" src="/src/index.tsx"></script>
</body>
Enter fullscreen mode Exit fullscreen mode

Step 4 - Adding vite.config.ts

Create a vite.config.ts file at the root of your project with the following content:

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

// https://vitejs.dev/config/
export default defineConfig({
  base: '/',
  plugins: [react()]
})
Enter fullscreen mode Exit fullscreen mode

Step 5 - Adding vite-env.d.ts

Create a vite-env.d.ts file inside the src folder with the following content:

/// <reference types="vite/client" />

Enter fullscreen mode Exit fullscreen mode

Step 6 - Adding vite scripts

Replace the existing CRA scripts in package.json with Vite scripts.

 "scripts": {
    "start": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview"
}
Enter fullscreen mode Exit fullscreen mode

Step 7 - Fixing tsconfig.json

Update your tsconfig.json to its final version.

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "noFallthroughCasesInSwitch": true,
    "jsx": "react-jsx",
    "types": ["vite/client", "vite-plugin-svgr/client"]
  },
  "include": ["src"]
}
Enter fullscreen mode Exit fullscreen mode

Step 8 - Migrating from Jest to Vitest

As we are moving to Vite, another good idea is to consider migrating from Jest to Vitest as well. Here are the steps:

8.1 - Install Vitest dependencies:

npm i -D jsdom vitest @vitest/coverage-v8
Enter fullscreen mode Exit fullscreen mode

8.2 - Update vite.config.ts to include Vitest configurations:

import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react-swc'

// https://vitejs.dev/config/
export default defineConfig({
  base: '/',
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './src/setupTests.ts',
    css: true,
    reporters: ['verbose'],
    coverage: {
      reporter: ['text', 'json', 'html'],
      include: ['src/**/*'],
      exclude: [],
    }
  },
})
Enter fullscreen mode Exit fullscreen mode

8.3 - Update package.json with Vitest scripts:

  "scripts": {
    "start": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview",
    "test": "vitest",
    "test:coverage": "vitest run --coverage --watch=false"
  },
Enter fullscreen mode Exit fullscreen mode

Step 9 - Extras

If you use GitHub Actions to push your code to GitHub Pages, you'll need to update the workflow file as Vite generates a dist folder when we run npm run build.

name: GitHub Pages

on:
  push:
    branches:
      - master
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-22.04
    permissions:
      contents: write
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: "16"

      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - run: npm ci
      - run: npm run build

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        if: github.ref == 'refs/heads/master'
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dist

Enter fullscreen mode Exit fullscreen mode

With these steps, you should now have successfully migrated your create-react-app project to Vite, enjoying its benefits and optimizing your development process for smaller projects. Happy coding!

Top comments (3)

Collapse
 
mezieb profile image
Okoro chimezie bright

Well done 👍

Collapse
 
nelwhix profile image
Nelwhix • Edited

Nice article, I followed this and got an Internal URI malformed error on the browser. then on the terminal I got that I have to rename every file in my project that uses jsx to a .jsx extension and I am trying to migrate a larger codebase with tons of files. Please any help?

Collapse
 
briandesousa1 profile image
Brian De Sousa

Nice work!

If you want to keep index.html under src, you could also create the vite.config.ts under src and change the start script in step 6 to vite serve src to serve the code from an alternate directory.