Migrating from Remix
React Router v7 is the successor to Remix v2. This guide helps you migrate your Remix v2 application to React Router v7.Prerequisites
React Router v7 requires:- Node.js: v20 or higher
- React: v18 or higher
- react-dom: v18 or higher
Overview
React Router v7 is essentially Remix v3. If you’ve enabled all Remix v2 future flags, upgrading mainly involves updating dependencies and configuration files.Step 1: Adopt Remix v2 Future Flags
Before upgrading, enable all Remix v2 future flags in your Remix application:v3_fetcherPersistv3_relativeSplatPathv3_throwAbortReasonv3_singleFetchv3_lazyRouteDiscovery
Step 2: Update Dependencies
Most shared APIs from runtime-specific packages have been consolidated intoreact-router.
Automated Update (Recommended)
Run the codemod to automatically update packages and imports:Manual Update
If you prefer manual migration:Package Name Changes
| Remix v2 Package | React Router v7 Package |
|---|---|
@remix-run/architect | @react-router/architect |
@remix-run/cloudflare | @react-router/cloudflare |
@remix-run/dev | @react-router/dev |
@remix-run/express | @react-router/express |
@remix-run/fs-routes | @react-router/fs-routes |
@remix-run/node | @react-router/node |
@remix-run/react | react-router |
@remix-run/route-config | @react-router/dev |
@remix-run/routes-option-adapter | @react-router/remix-routes-option-adapter |
@remix-run/serve | @react-router/serve |
@remix-run/server-runtime | react-router |
@remix-run/testing | react-router |
Update Import Statements
Step 3: Update Package Scripts
Update yourpackage.json scripts:
| Script | Remix v2 | React Router v7 |
|---|---|---|
dev | remix vite:dev | react-router dev |
build | remix vite:build | react-router build |
start | remix-serve build/server/index.js | react-router-serve build/server/index.js |
typecheck | tsc | react-router typegen && tsc |
Step 4: Add routes.ts File
React Router v7 uses a app/routes.ts file for route configuration.
If Using Remix v2 v3_routeConfig Flag
Update dependencies in your existing routes.ts:
filename=app/routes.ts
If NOT Using Remix v2 v3_routeConfig Flag
Create a new app/routes.ts file:
Option 1: Flat Routes (Recommended)
If you used the default “flat routes” convention:filename=app/routes.ts
Option 2: Nested Routes (v1 Convention)
If you used@remix-run/v1-route-convention:
filename=app/routes.ts
Option 3: Config-Based Routes
If you used theroutes option in Vite config:
filename=app/routes.ts
routes option from your vite.config.ts:
filename=vite.config.ts
Step 5: Add React Router Config
Create areact-router.config.ts file to replace the Vite plugin configuration:
vite.config.ts:
filename=vite.config.ts
react-router.config.ts:
filename=react-router.config.ts
Step 6: Update Vite Plugin
Change the Vite plugin import:filename=vite.config.ts
Step 7: Enable Type Safety
React Router v7 automatically generates types for route modules in a.react-router/ directory.
Update .gitignore
Add the generated types directory:
filename=.gitignore
Update tsconfig.json
filename=tsconfig.json
Step 8: Rename Entry File Components
Update component names in your entry files:app/entry.server.tsx:
filename=app/entry.server.tsx
app/entry.client.tsx:
filename=app/entry.client.tsx
Step 9: Update AppLoadContext Types
If you used a custom server, register your load context type:
filename=app/env.ts
LoaderFunctionArgs and ActionFunctionArgs augmentations:
filename=app/env.ts
filename=app/routes/my-route.tsx
Breaking Changes Summary
Package Restructuring
- All Remix packages renamed to
@react-router/* - Shared runtime APIs moved to
react-routercore package - Runtime-specific APIs (sessions, cookies) remain in platform packages
Configuration Changes
- Routes now defined in
app/routes.tsinstead of Vite config - Plugin config moved to
react-router.config.ts - Future flags removed (now default behavior)
Component Renames
RemixServer→ServerRouterRemixBrowser→HydratedRouterRemixContext→FrameworkContext(internal)
API Changes
deferremoved (use raw promises)jsondeprecated (use raw objects orResponse.json())installGlobals()removed (Node 20+ includes necessary globals)
Type System Changes
- Automatic route module type generation
Route.LoaderArgs,Route.ActionArgs, etc. for type safetyuseFetchergeneric changed:useFetcher<typeof loader>()instead ofuseFetcher<LoaderData>()
Migration Checklist
- Enable all Remix v2 future flags
- Run the codemod OR manually update dependencies
- Update package.json scripts
- Create or update
app/routes.ts - Create
react-router.config.ts - Update Vite plugin import
- Add
.react-router/to.gitignore - Update
tsconfig.json - Update entry file components
- Register
AppLoadContexttype (if using custom server) - Test your application thoroughly
- Update CI/CD pipelines if needed
Common Issues
Module Resolution Errors
If you see import errors after upgrading:- Clear
node_modulesand reinstall:rm -rf node_modules && npm install - Clear build artifacts:
rm -rf build .react-router - Restart your dev server
Type Errors After Upgrade
Run type generation explicitly:react-router typegen && tsc which generates types before checking.
Vite Build Errors
Ensure you’re using compatible Vite version (5.x or 6.x). React Router v7 supports both.Session Storage Issues
Thecrypto global from Web Crypto API is now required. Node 20+ includes this by default. If using an older Node version (not recommended), ensure crypto is available.
Next Steps
After migration:- Explore new type safety features
- Set up prerendering for static pages
- Review performance optimization guides
- Consider adopting React Server Components (experimental)