DEV Community

Cover image for Migrating from Create React App(CRA) to NextJS (Pages Router)
Jumbo Daniel
Jumbo Daniel

Posted on

Migrating from Create React App(CRA) to NextJS (Pages Router)

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
Enter fullscreen mode Exit fullscreen mode

(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"
Enter fullscreen mode Exit fullscreen mode

Step 3: Install Next.js

npm install next@latest
Enter fullscreen mode Exit fullscreen mode

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:

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

module.exports =  {
  nextConfig,
}
Enter fullscreen mode Exit fullscreen mode

Or

/** @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
Enter fullscreen mode Exit fullscreen mode

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:

{
  "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"]
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

export default function App({ Component, pageProps }) {
 return (
      <Component {...pageProps} />
  );
}
Enter fullscreen mode Exit fullscreen mode

_app.tsx

import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
 return (
      <Component {...pageProps} />
  );
}
Enter fullscreen mode Exit fullscreen mode

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:
// Before
import logo from '/logo.png'
// After
import logo from '../public/logo.png'
Enter fullscreen mode Exit fullscreen mode
  1. Pass the image.src property instead of the whole image object to your <img> tag:
// Before
<img src={logo} />

// After
<img src={logo.src} />
Enter fullscreen mode Exit fullscreen mode

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

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}
Enter fullscreen mode Exit fullscreen mode

.gitignore

.next
next-env.d.ts
dist
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)