| name | migrate-js-to-modern-typescript |
| description | Migrating a JavaScript codebase to TypeScript — converting .js files to .ts, adding types to existing JS, or tightening a loosely-typed TS project toward strict mode. Covers tsconfig and allowJs strategy, incremental strict-flag ratcheting (noImplicitAny, strictNullChecks, noUncheckedIndexedAccess), typing public surfaces, replacing `any` and unsafe casts with `unknown` and narrowing, validating runtime boundaries (JSON, env, API responses), converting CommonJS to ESM and prototypes to classes, and the build/CI changes a migration needs. Trigger even when the user only says "add types", "turn on strict mode", or "convert this file to TypeScript", and especially on a mixed JS/TS repo. Distinct from general TypeScript refactoring — this is the migration act itself, performed file by file while keeping the build green. |
JavaScript to TypeScript Migration Best Practices
Guide for taking a JavaScript codebase to strict, modern TypeScript without a big-bang rewrite. Contains 42 rules across 7 categories, prioritized by impact to drive an incremental, file-by-file migration that keeps the build compiling at every step.
When to Apply
Reference these guidelines when:
- Converting a
.js codebase to .ts (whole project or one module at a time)
- Adding types to existing JavaScript via JSDoc or annotations
- Choosing a
tsconfig and allowJs strategy for a mixed JS/TS repo
- Turning on
strict mode or individual strict flags on a large codebase
- Replacing
any, as casts, and ! assertions left over from a quick conversion
- Validating external data (JSON, env, API responses) so the types you wrote are true at runtime
- Converting CommonJS to ESM, prototypes to classes, and other JS idioms to TS
- Updating the build, runner, and CI to type-check and publish TypeScript
How the Migration Flows
tsconfig & strategy → strictness ratchet → type the surfaces → kill any/casts
→ validate runtime boundaries → convert JS idioms → tooling/build/CI
Decisions at the front cascade: a wrong tsconfig or a top-down conversion order forces you to re-type modules twice, and an early any flood poisons everything downstream. Work from the front of this pipeline and from the leaves of the dependency graph inward.
Rule Categories by Priority
| Priority | Category | Impact | Prefix |
|---|
| 1 | Migration Setup & tsconfig | CRITICAL | setup- |
| 2 | Strictness Ratcheting | CRITICAL | strict- |
| 3 | Typing Public Surfaces | HIGH | surface- |
| 4 | Replacing any & Unsafe Casts | HIGH | unsafe- |
| 5 | Runtime Data Validation | MEDIUM-HIGH | runtime- |
| 6 | JS-to-TS Idiom Conversion | MEDIUM | idiom- |
| 7 | Tooling & Build Migration | LOW-MEDIUM | tooling- |
Quick Reference
1. Migration Setup & tsconfig (CRITICAL)
2. Strictness Ratcheting (CRITICAL)
3. Typing Public Surfaces (HIGH)
4. Replacing any & Unsafe Casts (HIGH)
5. Runtime Data Validation (MEDIUM-HIGH)
6. JS-to-TS Idiom Conversion (MEDIUM)
7. Tooling & Build Migration (LOW-MEDIUM)
How to Use
Read individual reference files for detailed explanations and code examples:
Related Skills
typescript-refactor — Refactoring and modernizing code that is already TypeScript
typescript-advanced-patterns — Advanced type-level patterns once the migration is done
Reference Files