Codemod Docs
Hey, if you're here it means you want to migrate from Next to TanStack. You might be thinking: why use this when you can just tell an AI agent to migrate everything? That can work too, but outputs can vary run to run. This codemod is deterministic: it does what it says, nothing less, nothing more.
Before running this codemod, create a separate git branch from your original project so you can safely roll back if needed.
I assumes you've already followed TanStack's official migration guide and installed/removed the necessary libraries: Migrate from Next.js. It migrates the core routing and API surface, but a 1-to-1 migration isn't possible because the frameworks have different mental models.
Please don't be discouraged this codemod is designed to keep migration as smooth as possible. It adds TODOs only where manual follow-up is necessary because behavior is framework-specific and cannot be rewritten safely in a generic way.
Default Behavior
By default, this codemod runs the full built-in migration set. You can opt out of any migration or run only a subset using next-to-start.codemod.json.
Default migration set:
next-imagenext-linknext-server-functionsmanual-migration-todosnext-use-clientroute-file-structureroute-groupsapi-routes
What It Does NOT Change
- It does not fully migrate app-wide routing/runtime behavior in one shot.
- It does not automatically migrate all
next/navigation,next/cache, andnext/headersusage. - It does not rewrite every UI pattern that uses
Linksemantics. - It does not rewrite
next/og(ImageResponse) or other framework-specific runtime APIs. - It does not migrate styling/design-system code.
Some patterns are intentionally left for manual migration because they are context-sensitive:
- Files using
useLinkStatusfromnext/link - MDX component-map patterns (
useMDXComponents,MDXComponents,mdx/types)
These are skipped to avoid generating invalid Link behavior.
Manual Work You Still Need
- Review every codemod diff before applying.
- Manually migrate remaining
next/navigationhooks/functions based on each file's runtime context. - Manually migrate
next/cacheandnext/headerscall sites where needed. - For skipped files (
useLinkStatus, MDX component maps), migrate link behavior manually. - Verify route behavior for dynamic segments, route groups, loaders, and pending/error boundaries.
- Run typecheck/tests and fix runtime-level differences (TanStack Start uses different conventions for loaders, actions, and caching).
Notes
- Migration enable/disable behavior is controlled via
next-to-start.codemod.json(or workflow params/env overrides where applicable). - Confidence-first workflow:
- Start with a small migration set via
enabledMigrations(or keep default full set if your codebase is small). - Run in
--dry-runand review the diff. - Apply only the migrations you want, one by one if needed, and inspect each diff.
- Review and apply.
- Expand the migration set incrementally.
- Re-run in
--dry-run, review diffs, then apply.
- Start with a small migration set via
Project Config File (Recommended)
Create next-to-start.codemod.json in your project root and the codemod will read it automatically.
json
Use this file to keep runs deterministic and avoid passing env vars every time. You can delete the file after migration if you want.
Supported config keys:
appDirectory: where your Next app router entries live. Default:"app".routesDirectory: where TanStack route files should be written.enabledMigrations: allow-list of migration IDs to run.disabledMigrations: deny-list of migration IDs to skip.migrations: per-ID boolean map (highest priority inside config).
How To Run
Recommended path (most users):
- Create
next-to-start.codemod.jsonin your project root. - Run JSSG directly:
sh
Why this is recommended:
- simpler command
- no workflow boilerplate required
- config file keeps behavior reproducible
Workflow Run (Optional)
Use workflow mode only if you already use Codemod workflows or need to pass params from workflow orchestration.
Step 1: create a Codemod workflow file (using Codemod's official workflow format).
Step 2: add a JSSG step that runs ./scripts/codemod.ts with language tsx.
Step 3: run workflow:
sh
Supported workflow params for this codemod (options.params):
routesDirectoryroutes_directory
Route Directory Resolution
When file-structure migration is enabled, route entry files are moved/renamed (page.tsx -> index.tsx, layout.tsx -> _layout.tsx or __root.tsx, etc.).
Resolution order for routes directory:
next-to-start.codemod.jsonroutesDirectory- Workflow params (
options.params.routesDirectory/routes_directory) - Env (
CODEMOD_ROUTES_DIRECTORY, fallbackROUTES_DIRECTORY) vite.config.*tanstackStart({ router: { routesDirectory: '...' } })- Default:
routes
If your project expects routes to stay in app but none of the above are set, codemod defaults to routes and you may end up with both:
- existing
app/support files (_components,_ui, docs, helpers) - new
routes/route-entry files
Migration Toggles
Available migration IDs:
next-imagenext-linknext-server-functionsmanual-migration-todosnext-use-clientroute-file-structureroute-groupsapi-routes
Examples:
json
json
Notes:
enabledMigrationssets a baseline allow-list.disabledMigrationsremoves IDs from that list.migrationsbooleans are applied last and can force-enable/force-disable specific IDs.
Project Description
This project is a deterministic codemod for Next.js -> TanStack migration. It is intentionally biased toward safe, incremental changes and leaves ambiguous or high-risk rewrites for manual follow-up.
Credits
- Official Codemod platform and team: codemod.com
- Thanks to X: @alex__bit for helping out on issues