React Router v6 → v7 Migration Codemod
Automates 80%+ of the React Router v6 → v7 migration using ast-grep (jssg).
🖥 Live Playground
Try it in your browser: https://react-router-codemod.vercel.app
Paste any React Router v6 code on the left, click → Transform, and see the v7 output instantly.
Install & Run
🚀 Published Version (Quick Start)
bash
Published Package: Available on codemod registry • Basic migration transforms
🔧 Full Local Version (Advanced)
bash
Full Version Features: 7 comprehensive transforms • AST-based precision • Zero false positives • Edge case handling
What It Transforms
1. Import rewrites — react-router-dom → react-router
ts
2. RouterProvider — correctly splits to react-router/dom
ts
The official v7 upgrade guide is explicit: RouterProvider must come from react-router/dom. Every other published codemod gets this wrong.
3. Future flags — BrowserRouter + createBrowserRouter
tsx
ts
Smart merge: if some flags are already present, only the missing ones are added.
4. json() / defer() removal
ts
Two-argument json(data, { status: 404 }) is intentionally skipped — removing it would silently drop the status code.
5. fallbackElement → HydrateFallback
tsx
6. formMethod uppercase normalization
ts
tsx
7. package.json dependency update
Removes react-router-dom, adds react-router: ^7.0.0.
Real-World Testing Results
| Repository | Stars | RR Version | Files Scanned | Files Modified | False Positives |
|---|---|---|---|---|---|
| remix-run/indie-stack | ~3k | ^6.x | 35 | 5 | 0 |
| alan2207/bulletproof-react | ~28k | ^6.x | 425 | 2 | 0 |
| marmelab/react-admin | ~25k | ^6.x | 1,678 | 54 | 0 |
| novuhq/novu | ~35k | ^6.x | 6,452 | 210 | 0 |
| Total | 8,590 | 271 | 0 |
✅ Zero false positives across 8,590 files including a large production monorepo.
Test Suite
text
Run it yourself:
bash
Safety Guarantees
Every transform has three layers of protection:
- Fast early exit — string
.includes()check before any AST parsing - AST precision — imports matched by
kind: 'import_statement'node, never by line regex;formMethodpatterns anchor tonavigation.formMethodorfetcher.formMethodspecifically - Try/catch on every transform — any unexpected input returns the original source unchanged
Edge Cases Handled
| Edge case | Other codemods | This codemod |
|---|---|---|
RouterProvider import path | react-router ❌ | react-router/dom ✅ |
createBrowserRouter future flags | ❌ | ✅ |
export { X } from 'react-router-dom' re-exports | ❌ | ✅ |
import type { X } type imports | drops type ❌ | preserves type ✅ |
| Partial future flags already set | duplicates flags ❌ | adds only missing ✅ |
json(data, { status: 404 }) two-arg form | silently drops status ❌ | skipped for manual review ✅ |
formMethod already uppercase | re-transforms ❌ | idempotent ✅ |
<Form method={dynamicVar}> | changes dynamic value ❌ | unchanged ✅ |
Project Structure
text
Codemod Registry
https://codemod.com/registry/react-router-v6-to-v7
Links
License
MIT — arpit2222