Migrating from Create React App
Create React App (CRA) was, for years, the default way to start a new React project. It is now deprecated and effectively unmaintained — it has not kept pace with modern React features, its underlying tooling (Webpack 4-era configuration) has fallen behind, and the React team itself no longer recommends it for new projects. Next.js is one of the most common migration targets, since it covers what CRA left out — routing, data fetching, SSR/SSG, image and font optimization — as first-class, built-in features.
Why teams migrate
Create React App | Next.js |
|---|---|
Client-only rendering; every visitor downloads and runs the full JS bundle before seeing content | Server Components and SSR/SSG render meaningful HTML before JavaScript even loads |
No built-in routing — requires React Router as a separate dependency and convention | File-based routing built into the framework |
No built-in data-fetching story — components fetch in | Server Components fetch data directly; caching and revalidation are built in |
Manual |
|
Unmaintained tooling, security advisories with no fixes forthcoming | Actively developed, with regular releases and security patches |
The general shape of a migration
Install Next.js and its peer dependencies alongside the existing React app.
Create an
app/directory and move your top-level<App />markup intoapp/layout.tsxandapp/page.tsx.Convert React Router routes into the file-based
app/folder structure — each route becomes a folder with apage.tsx.Replace manual
<title>/<meta>tag management (whether hand-written or via a library like React Helmet) with the built-in Metadata API.Move environment variables from
REACT_APP_*naming toNEXT_PUBLIC_*for anything that needs to reach the browser.Swap
import.meta.env/process.env.REACT_APP_*references and any CRA-specific build scripts for the Next.js equivalents.
Install Next.js into an existing project
npm install next@latest react@latest react-dom@latest
app/layout.tsx — replaces index.html + the App shell
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}app/page.tsx — replaces the CRA App component's default route
export default function HomePage() {
return <h1>Hello from Next.js</h1>
}