Boîte à Outils Migration Framework + Langage
Dix choix pour l'ingénieur qui fait une vraie migration : JS→TS, CommonJS→ESM, React class→hooks, Express→Hono, Python 2→3, Vue 2→3. Codemod CLI + ast-grep + TypeScript / TypeScript-Go pour typecheck rapide + tsx pour exécuter TS sans build + Mypy / Ty pour typer Python + Ruff pour les fixes pyupgrade + Hono comme cible Express + agent Legacy Modernizer. Installer dans l'ordre.
What this pack solves
Real migrations — JavaScript to TypeScript, CommonJS to ESM, React class components to hooks, Express to Hono, Python 2 to Python 3, Vue 2 to Vue 3 — fail for the same reason: someone tries to do them in one giant branch. Six weeks in, the branch has 800 files changed, conflicts with every merge to main, and nobody can confidently ship it.
This pack is the AI-era version of how to actually finish one. The pattern is the same regardless of source/target: baseline → codemod → typecheck → test → ship a slice → repeat. The tools below let each step happen in minutes, not days, so the slice size can stay small enough to land before lunch.
Install in this order
- Codemod — AI-Powered Code Migration CLI (start here). The center of the rig. Scaffolds, shares, and runs large-scale code migrations as multi-step YAML workflows. First-class ast-grep support, a community registry of pre-built codemods (React class→hooks, Mocha→Jest, CommonJS→ESM, etc.), and AI-assisted authoring when no registry codemod fits.
- ast-grep — Structural Code Search and Rewrite Tool. The actual rewrite engine under most modern codemods. Pattern-match by AST shape instead of regex —
$VAR.then($CB)matches every promise-callback you want to rewrite to await, regardless of whitespace or names. Use it standalone for one-off rewrites, or as the Codemod CLI's backend. - TypeScript — JavaScript with Syntax for Types. The destination for JS→TS migrations. Install with
--noImplicitAnyoff initially, flip it on per directory as you migrate. - TypeScript Go — Native TypeScript Compiler Port in Go. Drop-in
tscreplacement, ~10× faster typecheck. Critical during migrations because you'll run typecheck after every codemod batch — a 2-minute tsc round becomes a 12-second loop, and 12 seconds is the difference between staying in flow and context-switching to Slack. - tsx — The Fastest Way to Run TypeScript in Node.js. Lets you execute
.tsfiles directly during migration without a build step. Crucial when half your codebase is JS and half is TS and you don't want to set up two parallel build pipelines. - Mypy — Optional Static Type Checker for Python. The Python equivalent of "flip on typecheck per directory." Use
--strictper module, not project-wide. Pair with apy.typedmarker so downstream consumers see your types. - Ruff — Python Linter and Formatter in One Fast CLI. For Python 2→3 migrations specifically, Ruff's
pyupgraderuleset auto-fixes most modernization patterns:print x→print(x),u"str"→"str",super(Foo, self)→super(),dict.iteritems()→dict.items(). Oneruff check --select UP --fixpass handles thousands of mechanical changes. - Ty — Astral's Fast Python Type Checker. The Rust-based alternative to Mypy from the same team that ships Ruff. Worth trialing in parallel — when feedback latency drops from 8 seconds to 200ms, you actually keep typing while it runs.
- Hono — Ultrafast Web Framework for the Edge. The destination if you're migrating off Express. API surface is close enough that handler-by-handler porting is mechanical:
req.body→await c.req.json(),res.json(x)→c.json(x), middleware signature is similar. Bonus: runs on Cloudflare/Bun/Node, so you can host the migrated routes anywhere. - Claude Code Agent: Legacy Modernizer. The catch-all for what codemods can't touch: dead config files, abandoned modules, version-sniff branches that haven't fired since IE 11. The agent reads the codebase, proposes a teardown order, and writes the PRs. Use it for the 20% that's judgment-heavy, not the 80% that's mechanical.
How they fit together
┌──────────────────────────────────┐
│ Codemod CLI (orchestrator) │
│ └─ ast-grep (rewrite engine) │
└──────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
JS → TS Python 2 → 3 Legacy archaeology
───────── ────────── ──────────────────
TypeScript Ruff (--select UP) Legacy Modernizer
TypeScript-Go Mypy / Ty (agent)
tsx (run TS)
┌──────────────┐
│ Express→Hono │
│ Hono │
└──────────────┘
│
▼
Slice ships in 1-3 PRs
The migration loop you run, per slice:
- Baseline — pick the next ~20-50 files. Snapshot test output and bundle size.
- Codemod — run Codemod CLI (or ast-grep directly) against just that slice. Inspect the diff.
- Typecheck — TypeScript-Go / Ty in watch mode. Fix the errors codemods couldn't infer.
- Test — run the existing test suite on the slice. tsx lets you do this without rebuilding.
- Ship — open the PR, merge, ship. Move to the next slice tomorrow.
If any slice takes more than 2 days, the slice is too big. Cut it.
Tradeoffs you'll hit
- Codemod CLI vs hand-written jscodeshift — Codemod CLI wraps ast-grep and a registry. Hand-rolled jscodeshift gives you full JS API control. Start with Codemod CLI; only drop to jscodeshift when the registry doesn't have your transform and ast-grep patterns can't express it.
- Mypy vs Ty — Mypy is the incumbent, more mature, slower. Ty is fast enough to keep open in your editor without lag. Run both during the migration: Mypy in CI for thoroughness, Ty locally for the inner loop.
- TypeScript-Go vs tsc — TypeScript-Go is the official Microsoft port, faster but not 100% feature-complete yet. Use it for the inner-loop typecheck during migration; keep tsc as the source of truth in CI until parity ships.
- Express→Hono vs Express→Fastify — Hono runs on edge runtimes (Cloudflare Workers, Bun, Deno) AND Node, with a near-identical handler API. Fastify is Node-only but more mature for traditional servers. Pick Hono if you're modernizing toward edge; Fastify if you're staying on Node and want the most mature option.
- Codemod-everything vs Legacy Modernizer — codemods do the 80% mechanical work in minutes. The Legacy Modernizer agent handles the 20% that needs judgment (dead code, abandoned features, conditional branches). Don't make the agent do mechanical work; don't make codemods do archaeology.
Common pitfalls
- Codemod sliced too big — "convert all 800 files to TS in one PR" guarantees the PR never lands. Migrate by directory, not by language. Each PR should be small enough to review in one sitting.
- Forgetting the typecheck loop is slow — running
tsc --noEmitafter every codemod pass is the migration step that kills your day. Install TypeScript-Go on day one. The 10× speedup is the difference between this being fun and being a chore. - Codemod registry copy-paste without reading — registry codemods are starting points, not gospel. Open the YAML, read the patterns, run on one file first, eyeball the diff before unleashing on the codebase.
- Mypy
--stricteverywhere on day one — fastest way to give up. Enable per module via[mypy-yourpackage.submodule]blocks, expand outward. - Express→Hono one-shot rewrite — port routes in groups, run both servers behind a router (Hono mounted under
/v2), cut over endpoint by endpoint. Don't flip the whole app at once. - Trusting codemods on tests — codemods will happily "migrate" a broken test suite into a still-broken test suite. Run the tests after every codemod batch. If tests were green before and red after, the codemod missed something — that's the bug you want to find right then, not in production three weeks later.
10 ressources prêtes à installer
Questions fréquentes
How big should each migration slice be?
Small enough that one PR can be reviewed in 30 minutes and shipped the same day. In practice that's usually a single directory, 20-50 files, no more than ~1000 lines of net diff. If a slice grows past that, split it. The whole point of incremental migration is that you can always stop, ship what you have, and resume tomorrow without the codebase being in a half-broken state.
Do I need Codemod CLI if I already use ast-grep directly?
Not strictly, but Codemod CLI is worth it for two reasons. First, the community registry has prebuilt codemods for the common migrations (React class→hooks, Mocha→Jest, CommonJS→ESM) you'd otherwise have to write yourself. Second, the YAML workflow format lets you sequence multiple ast-grep passes plus shell steps (run tests, format, commit) as one reproducible unit. Use ast-grep alone for one-offs, use Codemod CLI when the migration has more than 2-3 steps or you want to share the migration with teammates.
Why both Mypy and Ty for Python migrations?
Mypy is the de facto standard and has the largest plugin/stub ecosystem — that's what you want in CI as the source of truth. Ty is dramatically faster (Rust under the hood) and feels instant in an editor — that's what you want during the inner migration loop. They check the same # type: annotations, so running both costs you nothing in code changes. The split is purely about feedback latency: Mypy for correctness, Ty for speed.
How do I handle a migration where tests don't exist yet?
Add a thin characterization-test layer first, then migrate. Pick the public boundaries (HTTP routes, CLI commands, exported functions), write tests that lock in current behavior — even buggy behavior — and run those during the migration. Codemods are mechanical; they'll faithfully preserve bugs. Without characterization tests, you can't tell if a behavior change after a codemod pass is a bug the codemod introduced or a bug it preserved. Add the tests in the slice before the migration slice.
When should I use the Legacy Modernizer agent vs writing codemods?
Codemods are for transformations you can describe as a pattern: "every var x = becomes let x =," "every .then(cb) becomes await." The Legacy Modernizer agent is for decisions that need context: "this 2018 feature flag is dead, remove it," "this module is unreferenced anywhere, delete it," "this conditional path only runs on IE 11, prune it." If you can write the rule as ast-grep patterns, use a codemod. If the rule is "read the code and decide," use the agent. Mixing them up wastes both.
12 packs · 80+ ressources sélectionnées
Découvrez tous les packs curatés sur la page d'accueil
Retour à tous les packs