Create React App to Next

July 1, 2024

Migrating a Create React App (CRA) to Next.js can greatly enhance the performance and capabilities of your application. This guide follows a step-by-step process to ensure a smooth transition.

Why Migrate from Create React App to Next.js?

Server-Side Rendering (SSR)

Next.js supports server-side rendering out of the box, which can significantly improve the performance of your application by rendering pages on the server and sending the fully rendered HTML to the client. This results in faster initial page loads and better SEO.

Static Site Generation (SSG)

With Next.js, you can pre-render pages at build time, resulting in faster load times and improved performance. Static Site Generation (SSG) is especially useful for content-heavy sites.

Automatic Code Splitting

Next.js automatically splits your code into smaller bundles, which are loaded on demand. This reduces the initial load time and improves the performance of your application.

Built-in CSS and Sass Support

Next.js provides built-in support for CSS and Sass, including CSS Modules. This simplifies the process of styling your application and ensures that styles are scoped locally by default.

File-Based Routing

Next.js uses a file-based routing system, where the file structure of your project determines the routes of your application. This makes it easier to manage and scale your application as it grows.

API Routes

Next.js allows you to create API routes within the same application, eliminating the need for a separate backend server. This simplifies the development process and reduces the complexity of your project.

Image Optimization

Next.js includes an optimized image component that automatically optimizes images for different devices and screen sizes, resulting in faster load times and improved performance.

Built-in TypeScript Support

Next.js has excellent TypeScript support out of the box, making it easier to build and maintain type-safe applications.

Setup

1. Edit .gitignore

Ensure node_modules is included in your .gitignore file to prevent committing unnecessary dependencies.

echo "node_modules" >> .gitignore

2. Install Next.js and PostCSS

Install the latest version of Next.js along with PostCSS and Autoprefixer.

npm install next@latest
npm install postcss autoprefixer

Steps

Step 1: Create Next.js Configuration File

Create a next.config.mjs file to configure your Next.js application.

/** @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

Step 2: Update tsconfig.json

Update your tsconfig.json file with the necessary configurations for Next.js.

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

Steps 3: Create Root Layout

Create a layout.tsx file in the app directory. This will serve as the root layout for your Next.js application.

import type { Metadata } from 'next'

// Import CSS files
import '../styles/globals.css';

export const metadata: Metadata = {
  title: 'React App',
  description: 'Web site created with Next.js.',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <div id="root">{children}</div>
      </body>
    </html>
  )
}

Step 4: Create postcss.config.js File

Create a postcss.config.js file to configure PostCSS.

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

Step 5: Create Entry Point Files

Create the server-side and client-side entry points in the app directory.

Server-Side Entry Point (app/[[...slug]]/page.tsx)

import '../../index.css'
import { ClientOnly } from './client'

export function generateStaticParams() {
  return [{ slug: [''] }]
}

export default function Page() {
  return <ClientOnly />
}

Client-Side Entry Point (app/[[...slug]]/client.tsx)

'use client'

import React from 'react'
import dynamic from 'next/dynamic'

const App = dynamic(() => import('../../App'), { ssr: false })

export function ClientOnly() {
  return <App />
}

Step 6: Update Static Image Imports

Ensure all static image imports are updated to relative paths.

Example Conversion:

// Old Import
import logo from '/logo.png'

// Updated Import
import logo from '../public/logo.png'

// Old Image Tag
<img src={logo} />

// Updated Image Tag
<img src={logo.src} />

Step 7: Update Environment Variables

Update your environment variables from REACT_APP_ prefix to NEXT_PUBLIC_.

sed -i 's/REACT_APP_/NEXT_PUBLIC_/g' .env

Step 8: Update Scripts in package.json

Update your package.json scripts for Next.js.

{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

Additionally, update your .gitignore to include Next.js-specific files.

echo ".next\nnext-env.d.ts\ndist" >> .gitignore

Step 9: Cleanup

Remove CRA-specific files and dependencies.

rm src/index.tsx src/index.ts src/index.jsx src/index.js public/index.html src/reportWebVitals
npm uninstall react-scripts

Automate Create React App to Next Migration

Alternatively, you can fully automate this migration for free with Second. Just connect to your GitHub account, select a repo, select the CRA to Next migration module, and then run the job. Try it now.

Migrations

Experience the future of enterprise
code maintenance today

Unlock millions of dollars in your team's potential.