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