cra-to-next-migration
CRA to Next.js Migration Guide
Comprehensive migration guide for converting Create React App projects to Next.js, covering routing, data fetching, components, styling, and deployment. Contains 148 rules across 17 categories, prioritized by migration impact. After a successful migration the application should work the same as it did before the migration.
When to Apply
Reference these guidelines when:
- Migrating an existing CRA application to Next.js
- Converting React Router routes to file-based routing
- Adopting Server Components in a client-heavy app
- Moving from client-side rendering to SSR/SSG
- Updating environment variables for Next.js
- Optimizing images and fonts with Next.js built-ins
Version Policy
Use Next.js 16.x or later. Do NOT use Next.js 14.x or 15.x.
Before starting migration, check the current latest version:
npm info next version
Use the latest version in your package.json with a caret for minor/patch updates. The minimum supported version for this migration guide is ^16.0.0.
Rule Categories by Priority
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Project Setup | CRITICAL | setup- |
6 |
| 2 | Dependencies | CRITICAL | deps- |
1 |
| 3 | Routing | CRITICAL | routing- |
17 |
| 4 | Data Fetching | CRITICAL | data- |
11 |
| 5 | Components | HIGH | components- |
9 |
| 6 | Environment Variables | HIGH | env- |
6 |
| 7 | Styling | HIGH | styling- |
12 |
| 8 | Public Assets | MEDIUM | assets- |
5 |
| 9 | Images | MEDIUM | images- |
8 |
| 10 | Fonts | MEDIUM | fonts- |
6 |
| 11 | SEO & Metadata | MEDIUM | seo- |
9 |
| 12 | API Routes | MEDIUM | api- |
9 |
| 13 | State Management | MEDIUM | state- |
8 |
| 14 | Integrations | MEDIUM | integrations- |
1 |
| 15 | Testing | LOW | testing- |
9 |
| 16 | Build & Deploy | LOW | build- |
7 |
| 17 | Common Gotchas | HIGH | gotchas- |
24 |
Quick Reference
1. Project Setup (CRITICAL)
setup-initial-structure- Convert CRA folder structure to Next.js App Routersetup-package-json- Update dependencies and scriptssetup-next-config- Create and configure next.config.jssetup-typescript- Migrate TypeScript configurationsetup-eslint- Update ESLint for Next.jssetup-gitignore- Update .gitignore for Next.js
2. Dependencies (CRITICAL)
deps-react19-compatibility- Upgrade dependencies for React 19 compatibility
3. Routing (CRITICAL)
routing-basic-pages- Convert components to file-based routesrouting-dynamic-routes- Use [param] syntax for dynamic segmentsrouting-catch-all-routes- Use [...slug] for catch-all routesrouting-optional-catch-all- Use [[...slug]] for optional catch-allrouting-route-groups- Use (group) folders for organizationrouting-parallel-routes- Use @slot for parallel routesrouting-intercepting-routes- Use (..) for intercepting routesrouting-link-component- Replace react-router Link with next/linkrouting-programmatic-navigation- Replace useNavigate with useRouterrouting-use-params- Replace useParams with Next.js paramsrouting-use-search-params- Replace useSearchParams properlyrouting-nested-layouts- Convert nested routes to layoutsrouting-loading-states- Add loading.tsx for suspenserouting-error-boundaries- Add error.tsx for error handlingrouting-not-found- Add not-found.tsx for 404 pagesrouting-hash-based- Handle hash-based routing for client-only appsrouting-protected-routes- Implement protected route patterns
4. Data Fetching (CRITICAL)
data-useeffect-to-rsc- Convert useEffect fetches to Server Componentsdata-useeffect-to-ssr- Convert useEffect to getServerSidePropsdata-useeffect-to-ssg- Convert useEffect to getStaticPropsdata-client-fetch- Keep client fetches with proper patternsdata-server-actions- Use Server Actions for mutationsdata-revalidation- Configure data revalidation strategiesdata-streaming- Use Suspense for streaming datadata-parallel-fetching- Fetch data in parallel on serverdata-sequential-fetching- Handle sequential data dependenciesdata-caching- Configure fetch caching behaviordata-client-library-init- Initialize client-only libraries in useEffect
5. Components (HIGH)
components-use-client- Add 'use client' directive for client componentscomponents-server-default- Understand server components are defaultcomponents-boundary-placement- Place client boundaries strategicallycomponents-composition- Use composition to minimize client JScomponents-interleaving- Interleave server and client componentscomponents-props-serialization- Ensure props are serializablecomponents-children-pattern- Pass server components as childrencomponents-context-providers- Handle Context providers properlycomponents-third-party- Wrap third-party client components
6. Environment Variables (HIGH)
env-prefix-change- Change REACTAPP to NEXTPUBLICenv-server-only- Use non-prefixed vars for server-onlyenv-runtime-config- Use runtime configuration when neededenv-local-files- Understand .env file loading orderenv-build-time- Understand build-time vs runtime env varsenv-validation- Validate required environment variables
7. Styling (HIGH)
styling-global-css- Move global CSS to app/layout.tsxstyling-css-modules- CSS Modules work with minor changesstyling-sass- Configure Sass supportstyling-tailwind- Configure Tailwind CSSstyling-css-in-js- Handle CSS-in-JS librariesstyling-styled-components- Configure styled-components for SSRstyling-emotion- Configure Emotion for SSRstyling-component-styles- Import component styles properlystyling-postcss- Configure PostCSSstyling-scss-global-syntax- Use :global only in CSS Modulesstyling-css-import-order- Control CSS import order in layoutsstyling-dark-mode-hydration- Handle dark mode without hydration mismatch
8. Public Assets (MEDIUM)
assets-public-folder- Public folder works the same wayassets-static-imports- Use static imports for assetsassets-absolute-urls- Reference assets without public prefixassets-favicon- Place favicon in app directoryassets-manifest- Configure web app manifest
9. Images (MEDIUM)
images-next-image- Replace img with next/imageimages-required-dimensions- Provide width and heightimages-fill-prop- Use fill for responsive imagesimages-priority- Use priority for LCP imagesimages-placeholder- Configure blur placeholdersimages-remote-patterns- Configure remote image domainsimages-loader- Configure custom image loadersimages-optimization- Understand automatic optimization
10. Fonts (MEDIUM)
fonts-next-font- Use next/font for optimizationfonts-google-fonts- Load Google Fonts properlyfonts-local-fonts- Load local font filesfonts-variable-fonts- Configure variable fontsfonts-font-display- Configure font-display strategyfonts-preload- Understand automatic font preloading
11. SEO & Metadata (MEDIUM)
seo-metadata-api- Use Metadata API instead of react-helmetseo-dynamic-metadata- Generate dynamic metadataseo-opengraph- Configure Open Graph metadataseo-twitter-cards- Configure Twitter Card metadataseo-json-ld- Add structured data (JSON-LD)seo-canonical- Set canonical URLsseo-robots- Configure robots meta tagsseo-sitemap- Generate sitemap.xmlseo-head-component- Migrate from next/head to Metadata
12. API Routes (MEDIUM)
api-route-handlers- Create Route Handlers in app/apiapi-http-methods- Export named functions for HTTP methodsapi-request-body- Parse request body properlyapi-query-params- Access query parametersapi-headers-cookies- Access headers and cookiesapi-response-types- Return proper response typesapi-middleware- Implement middleware patternsapi-cors- Configure CORS properlyapi-rate-limiting- Implement rate limiting
13. State Management (MEDIUM)
state-context-client- Context requires 'use client'state-zustand- Zustand works with hydration carestate-redux- Configure Redux with Next.jsstate-jotai- Configure Jotai properlystate-recoil- Configure Recoil properlystate-url-state- Use URL for shareable statestate-server-state- Minimize client state with RSCstate-persistence- Handle state persistence
14. Integrations (MEDIUM)
integrations-sentry- Migrate Sentry error monitoring
15. Testing (LOW)
testing-jest-config- Update Jest configurationtesting-react-testing-library- RTL works the sametesting-server-components- Test Server Componentstesting-client-components- Test Client Componentstesting-async-components- Test async componentstesting-mocking- Mock Next.js modulestesting-e2e-cypress- Configure Cypress for Next.jstesting-e2e-playwright- Configure Playwright for Next.jstesting-api-routes- Test API Route Handlers
16. Build & Deployment (LOW)
build-scripts- Update build scriptsbuild-output- Understand build outputbuild-standalone- Configure standalone outputbuild-static-export- Configure static exportbuild-bundle-analysis- Analyze bundle sizebuild-vercel- Deploy to Vercelbuild-docker- Configure Docker deployment
17. Common Gotchas (HIGH)
gotchas-window-undefined- Handle window/document in SSRgotchas-hydration-mismatch- Fix hydration mismatchesgotchas-use-effect-timing- Understand useEffect in Next.jsgotchas-router-ready- Check router.isReady for query paramsgotchas-dynamic-imports- Use next/dynamic properlygotchas-api-routes-edge- Edge vs Node.js runtimegotchas-middleware- Middleware runs on edgegotchas-static-generation- Static vs dynamic renderinggotchas-redirect- Handle redirects properlygotchas-headers- Set response headersgotchas-cookies- Handle cookies in RSCgotchas-turbopack- Handle Turbopack compatibility issuesgotchas-empty-modules- Fix empty module exports for isolatedModulesgotchas-nullish-coalescing- Fix nullish coalescing runtime errorsgotchas-react19-class-components- Fix React 19 class component this bindinggotchas-react19-ref-prop- Handle React 19 ref prop changesgotchas-websocket-optional-deps- Handle WebSocket native dependency bundlinggotchas-auth-race-conditions- Guard against auth/API race conditionsgotchas-auth-state-gating- Wait for auth state before checking rolesgotchas-configuration-idempotency- Ensure configuration idempotency with useRefgotchas-hydration-nested-interactive- Avoid nested interactive elementsgotchas-router-push-timing- Never call router.push during rendergotchas-infinite-rerender- Prevent infinite re-render loopsgotchas-provider-hierarchy- Configure provider hierarchy correctly
Pre-Migration Checklist
Before starting migration, scan the codebase for patterns that need special handling:
# Check for WebSocket libraries (needs webpack fallback config)
grep -E "(socket\.io|\"ws\")" package.json
# Check for SCSS :export syntax (may need --webpack flag)
grep -r ":export" --include="*.scss" src/
# Check for SVG ReactComponent imports (needs SVGR config)
grep -r "ReactComponent" --include="*.ts" --include="*.tsx" src/
# List all REACT_APP_ environment variables
grep -roh "REACT_APP_[A-Z_]*" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" src/ | sort -u
# Check for Redux extraReducers using object notation (must convert to builder pattern for RTK v2)
grep -r "extraReducers:" --include="*.js" --include="*.jsx" --include="*.ts" --include="*.tsx" src/
# Check for /app/ paths that need updating if using (app) route group
grep -rE "(href|to|push|replace|redirect).*['\"]\/app\/" --include="*.js" --include="*.jsx" --include="*.ts" --include="*.tsx" src/
Scan Results to Rule Mapping:
| Scan Result | Rules to Read |
|---|---|
| socket.io or ws in package.json | gotchas-websocket-optional-deps, setup-next-config |
:export in SCSS files |
gotchas-turbopack |
ReactComponent SVG imports |
assets-static-imports |
REACT_APP_ variables found |
env-prefix-change |
extraReducers: found |
state-redux (RTK v2 builder callback required) |
/app/ paths in navigation |
routing-route-groups (update paths for route groups) |
How to Use
Read individual rule files for detailed explanations and code examples:
rules/setup-initial-structure.md
rules/routing-basic-pages.md
rules/data-useeffect-to-rsc.md
Each rule file contains:
- Brief explanation of the migration step
- CRA "before" code example
- Next.js "after" code example
- Additional context and gotchas
Migration Order
For best results, migrate in this order:
- Setup - Initialize Next.js project structure
- Routing - Convert React Router to file-based routing
- Environment Variables - Update env var prefixes
- Components - Add 'use client' directives where needed
- Data Fetching - Convert useEffect to server patterns
- Styling - Move global CSS, configure CSS-in-JS
- Images & Fonts - Adopt Next.js optimizations
- SEO - Migrate to Metadata API
- API Routes - Create Route Handlers
- Testing - Update test configuration
Post-Migration Verification Checklist
After migration, verify the application works correctly:
Core Functionality:
-
npm run devstarts Next.js dev server without errors -
npm run buildcompletes successfully -
npm startruns the production build - Main application renders correctly
- All routes are accessible
Client-Side Features:
- localStorage/sessionStorage persistence works
- Dark mode or theme toggles work and persist
- Client-side interactivity (forms, buttons, modals) works
- Browser back/forward navigation works correctly
Routing (if applicable):
- Hash-based routing works (e.g.,
#room=abc,key=xyz) - Query parameters are read correctly
- Dynamic routes render with correct params
- 404 pages show for invalid routes
Real-Time Features (if applicable):
- WebSocket connections establish successfully
- Real-time collaboration or updates work
- Reconnection after disconnect works
Integrations (if applicable):
- Error monitoring (Sentry) captures errors
- Analytics tracking fires correctly
- Third-party auth (OAuth, Firebase) works
- File uploads work
PWA (if applicable):
- Service worker registers (production build)
- App is installable
- Offline functionality works as expected
Performance:
- No hydration mismatch warnings in console
- Images load and are optimized
- Fonts load without FOUT/FOIT issues
- No unexpected console errors or warnings