Migrating from Create React App(CRA) to NextJS (Pages Router)
Tags: webdev, nextjs, createreactapp, react
Published: 2024-05-11 07:09:15



## This blog post talks about the migration process from Create React App (CRA) to Next.js

## Understanding CRA
Create React App (CRA) is a tool that helps set up a modern React development environment with minimal configuration. It provides a preconfigured environment with a development server, bundling, linting, and other useful features, making it easy to get started with React projects quickly.

## Understanding Next.js
Next.js is a React framework that enables server-side rendering, static site generation, file-based routing, and more out-of-the-box. It provides a robust foundation for building production-ready React applications with enhanced performance, SEO, and developer experience.

## Comparison
| Feature | Next.js | Create React App |
| --- | --- | --- |
| Server-Side Rendering | Built-in support | Not supported out of the box |
| Static Site Generation | Built-in support | Not supported out of the box |
| File-based Routing | Yes | No (requires a routing library like React Router) |
| Code Splitting | Automatic | Requires additional configuration |
| Production Build | Optimized for performance | Basic production build |
| Deployment | Supports various hosting platforms | Requires additional configuration for deployment |
| Developer Experience | Enhanced with features like Fast Refresh | Basic Features |

## Why Switch to Next.js?
- **Better Performance**: Next.js provides server-side rendering and static site generation out of the box, which can significantly improve the performance and SEO of your web applications.
- **Simplified Routing**: Next.js uses a file-based routing system, which makes it easier to reason about your application's structure and removes the need for complex routing setups.
- **Enhanced Developer Experience**: Next.js offers features like Fast Refresh, which improves the development experience by providing near-instant updates to your application without losing state.
- **Optimized for Production**: Next.js builds are optimized for production, with features like automatic code splitting and bundling, ensuring better performance and smaller bundle sizes.
- **Ecosystem and Community**: Next.js has a thriving ecosystem and a large community, providing access to a wide range of third-party libraries, tools, and resources.
- **Future-Proof**: Next.js is actively maintained and continuously updated, ensuring that your applications remain compatible with the latest React features and best practices.

## Prerequisites:
- An existing CRA project
- Basic understanding of React and JavaScript
- Node installed on your system

Are you looking to take your React application to the next level? If you've been using Create React App (CRA) and are interested in exploring the powerful features of Next.js, this blog post will guide you through the migration process step-by-step. Next.js offers server-side rendering, static site generation, file-based routing, and more, allowing you to build high-performance, SEO-friendly, and scalable web applications.

Let's get started!

### Step 1: Start the development server
1. Open your CRA project in your preferred code editor.
2. In the terminal, navigate to your project directory.
3. Run the following command to start the development server:
```
npm start
```
(Note: use the package manager you have set up on your project already...)

This will ensure that your CRA application is running correctly before we begin the migration process.

### Step 2: Uninstall the development script
1. Open your `package.json` file.
2. Remove the `react-scripts` dependency from the `dependencies` section.
3. Remove the following scripts from the `scripts` section:
```
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
```

### Step 3: Install Next.js
```
npm install next@latest
```

### Create the Next.js Configuration File:
Next.js provides a configuration file where you can customize various settings for your application. Create a new file called `next.config.js` in the root directory of your project with the following content:

```js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
}

module.exports =  {
  nextConfig,
}
```

Or

```js
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // Outputs a Single-Page Application (SPA).
  distDir: './dist', // Changes the build output directory to `./dist/`.
}
export default nextConfig
```

You should note that:
- If you want to enable React's strict mode and use the default Next.js behavior (server-rendered application with client-side hydration), you would use the first snippet.
- If you want to generate a static Single-Page Application (SPA) and change the output directory for the built files, you would use the second snippet. The configuration sets up Next.js to generate a Single-Page Application (SPA) and changes the build output directory to `./dist/`. You can modify these settings based on your preferences.

The decision should be based on whether you need a server-rendered application or a fully client-side rendered SPA, and whether you want to change the output directory for the built files.

### Step 4: Update Typescript Config File (optional)
If you're using TypeScript, update your `tsconfig.json` file to make it compatible with Next.js:

```json
{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"]
}
```

Note: If you're not using TypeScript, you can skip this step. And Remember you can always add typescript to your Next.js project by just adding a new file with `.ts`, `.tsx` file extension, and it will be installed automatically.

### Step 4: Remove React Router
If you were using React Router in your CRA project, you'll need to remove it since Next.js has built-in file-based routing. Simply uninstall the `react-router-dom` package:

```
npm uninstall react-router-dom
```

### Step 5: Create the Root Directory (Pages)
Next.js uses a file-based routing system, where each file in the `pages` directory represents a route in your application. Create a new directory called `pages` in the root of your project, and add an `index.js` or `index.tsx` file inside it. This file will serve as the entry point for your application. Also add this `_app.jsx` file if you are using JavaScript or `_app.tsx` for TypeScript.

_app.jsx
```jsx
export default function App({ Component, pageProps }) {
 return (
      <Component {...pageProps} />
  );
}
```

_app.tsx
```tsx
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
 return (
      <Component {...pageProps} />
  );
}
```

For styles, I'll be using Tailwind CSS with Next.js (if you set it up already in CRA you can skip this step as it already works the same way). If you want to set up Tailwind CSS with Next.js, follow the official guide: https://tailwindcss.com/docs/guides/nextjs

Note: If you want to use regular CSS with Next.js, you can import CSS files directly into your components with CSS modules or create a global CSS file in the `styles` directory and import it in your `_app.tsx`/`_app.jsx` file.

### Step 6: Update Image Imports
Next.js handles static image imports differently from CRA. Use these steps to update your image imports.

1. Convert absolute import paths for images imported from `/public` into relative imports:
```js
// Before
import logo from '/logo.png'
// After
import logo from '../public/logo.png'
```

2. Pass the `image.src` property instead of the whole image object to your `<img>` tag:
```jsx
// Before
<img src={logo} />

// After
<img src={logo.src} />
```

Alternatively, you can reference the public path/URL for the image file based on the filename. For example, `public/logo.png` will serve the image at `/logo.png` for your application, which would be the `src` value.

The benefit of using the Next.js `Image` component is that it automatically optimizes images for performance, including lazy loading and resizing images on the fly. This can lead to significant improvements in page load times and overall user experience.

### Step 7: Migrate the Environment Variables
Next.js has an inbuilt support for `.env` environment variables similar to CRA. The major difference is the prefix used to expose environment variables on the client side. Change all environment variables with the `REACT_APP_` prefix to `NEXT_PUBLIC_`.

### Step 8: Update Scripts in package.json
You should now be able to run your application to test if you've successfully migrated to Next.js. Before that, you need to update your scripts in your `package.json` with Next.js related commands, and add `.next`, next-env.d.ts, and dist to your .gitignore file:

package.json
```json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}
```

.gitignore
```
.next
next-env.d.ts
dist
```

Now run you can start the development server using your command (I'm using)`npm run dev`, and open `http://localhost:3000`. You should see your application now running on Next.js.

### Clean Up:
Finally, you can clean up your codebase from Create React App-related files:
- Delete `public/index.html`
- Delete the `reportWebVitals` setup

Congratulations! You've successfully migrated your Create React App project to Next.js. With this migration, you can now take advantage of Next.js's powerful features, such as server-side rendering, static site generation, file-based routing, and more, enabling you to build high-performance, SEO-friendly, and scalable web applications.