What is ts-migrate and Why It Exists

What is ts-migrate and Why It Exists

JavaScript to TypeScript Migration

ts-migrate is Airbnb's migration tool that exists because manually converting large Java

Script codebases to TypeScript is a nightmare that makes you question your life choices.

Instead of spending months manually rewriting every file, ts-migrate brute-forces your JavaScript into compiling TypeScript.

Core Purpose and Reality Check

Airbnb built this because they had massive JavaScript codebases and converting them by hand would take until the heat death of the universe. The tool follows the "make it compile first, fix the types later" philosophy

  • because perfect is the enemy of done, and perfect TypeScript migration is a myth.

At Airbnb, they used this on massive projects and got them compiling quickly.

Does it create beautiful, type-safe TypeScript? Hell no. Does it create TypeScript that actually compiles so you can start getting some benefits while you clean up the mess? Absolutely. [Large codebases](https://github.com/microsoft/Type

Script/wiki/Performance) benefit from gradual migration approaches, and TypeScript adoption statistics show the language's growing popularity in enterprise environments.

How This Thing Actually Works

Plugin Architecture

Plugin-Based Architecture: ts-migrate uses a modular plugin system that you can customize.

The default setup assumes you're using React, which is great if you are and annoying if you're not. The plugins handle PropTypes conversion and other React-specific patterns pretty well.

Codemod Foundation:

Under the hood, it's using codemods (code modification scripts) to systematically transform your JavaScript.

It extracts type information from PropTypes (if you have them), handles [imports/exports](https://developer.mozilla.org/en-US/Web/Java

Script/Reference/Statements/import), and adds type annotations wherever it can figure them out.

The approach is similar to other AST transformation tools like jscodeshift.

"Smart" Type Inference:

The tool tries to infer types from your existing code patterns and Prop

Types definitions. When it can't figure something out (which is often), it falls back to any types aliased as $TSFixMe. This is by design

  • it's better to have compiling code with any types than broken code.

Current Status and Compatibility

The latest version is 0.1.35, published 3 years ago in November 2022.

The package gets decent usage but isn't actively maintained anymore

  • last real update was years ago. Works fine with React 17/18, untested with React 19 beta.

The tool generates TypeScript that compiles immediately but creates a mess you'll spend weeks cleaning up. This trade-off

  • speed vs. quality
  • makes it perfect for teams that need to get TypeScript benefits now while accepting they'll be fixing types for months afterward.

Similar migration strategies are discussed in the TypeScript handbook and migration guides.

ts-migrate gets you compiling Type

Script in 2 hours, but you'll spend 6 months explaining to your team why everything is typed as any.

Installation and Getting Started (And What Actually Breaks)

npm install ts-migrate

Installation - The Easy Part

Install it like any other npm package. If you can't figure this out, TypeScript migration is the least of your problems:

Using npm:

npm install --save-dev ts-migrate

Using yarn:

yarn add --dev ts-migrate

Direct execution (if you're feeling brave):

npx ts-migrate <folder>

The Nuclear Option - Full Migration

Terminal Command

⚠️ Fair warning: This will touch every JavaScript file in your project. Run this on a clean branch or you'll hate yourself:

npx -p ts-migrate -c \"ts-migrate-full <folder>\"

This command will bulldoze through your project and:

  1. Initialize a tsconfig.json file
  2. Rename .js/.jsx files to .ts/.tsx (yes, all of them)
  3. Apply codemods to make TypeScript stop screaming
  4. Commit changes at each step (so you can rollback when it breaks)

Pro tip: The automatic commits are actually useful because you'll definitely want to rollback some of this mess.

Platform Gotchas That Will Ruin Your Day

Windows users: The file renaming step occasionally fails with permission errors when files are open in your IDE. Close everything and pray.

M1 Macs: Sometimes have issues with the dependency tree during migration - if npm fails mysteriously, try using Node 16 with rosetta.

Docker builds: Need updating to handle .ts/.tsx files if they weren't already. Your build times will increase 2-3x initially because TypeScript is slower than Babel.

Webpack configuration: ts-migrate assumes standard module resolution. Custom webpack aliases will break everything. Prepare to update your Jest config too - ts-migrate changes file extensions but doesn't fix test setup.

Individual Command Usage

For more granular control, ts-migrate provides four distinct commands that can be run independently:

Initialize TypeScript configuration:

npx ts-migrate -- init <folder>

Rename JavaScript files to TypeScript:

npx ts-migrate -- rename <folder>

Apply migration codemods:

npx ts-migrate -- migrate <folder>

Re-run ignore comments for new errors:

npx ts-migrate -- reignore <folder>

Partial Migrations with --sources Flag

For large projects, you can migrate specific directories or files using the --sources flag, which accepts glob patterns:

## Migrate specific components
npx ts-migrate-full /path/to/project --sources \"src/components/**/*\"

## Include ambient types for better results  
npx ts-migrate-full /path/to/project \
  --sources \"src/components/**/*\" \
  --sources \"node_modules/**/*.d.ts\"

This approach is particularly useful for teams that want to migrate incrementally or test the tool on smaller sections before full project conversion.

What to Expect After the Tool Destroys Your Pristine JavaScript

TypeScript Errors

After running ts-migrate, your project will compile, but it'll look like a TypeScript horror movie. Expect hundreds of @ts-expect-error comments and any types everywhere (aliased as $TSFixMe). This is normal. You're not doing anything wrong - the tool just creates compiling garbage that you'll spend months fixing.

Common failures include: ts-migrate chokes on barrel exports (index.js files with re-exports), dies on dynamic requires, and completely ignores HOCs. If you use Redux with connect(), prepare for a world of pain. When it encounters dynamic imports or weird webpack setups, it basically gives up and dumps any types everywhere. Don't even think about using it with Vue or Angular - it's React-only in practice, despite what the docs claim.

The reality of post-migration cleanup:

  1. Day 1: Pop champagne, it compiles! Ship it to production immediately.
  2. Week 2: First production bug because any types hid a real issue. Enable stricter linting.
  3. Month 3: Junior dev asks why everything is $TSFixMe. Start writing documentation.
  4. Month 6: Still finding any types in weird places. Consider this the new normal.
  5. Year 2: Finally remove the last @ts-expect-error. Tool paid for itself months ago.

This approach lets you start getting TypeScript benefits (better IDE support, some type checking) immediately while accepting that you'll be cleaning up the mess until the next framework migration. The TypeScript compiler options can be gradually tightened as you improve your types, and ESLint TypeScript rules help maintain code quality during the transition.

Reality check: most teams never finish the cleanup. They just live with the $TSFixMe types forever and call it "TypeScript". At least it's better than the alternative: staring at a JavaScript codebase that crashes in production because someone passed a string where a number was expected. Again.

ts-migrate vs Alternative Migration Approaches

Feature

ts-migrate

Manual Migration

TypeScript Compiler

Other Tools

Automation Level

Bulldozer approach

  • touches everything

Manual file-by-file torture

Gradual with allowJs

Usually broken or abandoned

Time to Compile

Immediate (couple hours)

Weeks to months of pain

Gradual over time

Varies wildly

Initial Type Quality

Terrible

  • any types everywhere

Actually good types

Mixed quality

Tool-dependent

Project Size Support

Built for massive projects

Only feasible for small stuff

Any size

Varies

React Integration

Built-in React/PropTypes support

Manual React migration hell

No React-specific features

Usually limited

Reality Check

Fast but messy

Perfect but will take forever

Slow and confusing

Mostly garbage

Learning Curve

Minimal

  • single command

Steep TypeScript learning curve

Moderate

Tool-specific

Post-Migration Work

High

  • months of cleanup

Minimal

Moderate

Varies

Frustration Level

High initially, lower after cleanup

Extremely high throughout

Moderate

Usually extreme

Developer Satisfaction

Compiles fast, debugging slowly

Perfect types, never finished

Works great until it doesn't

Abandoned by maintainers

Frequently Asked Questions

Q

Why does my project fail to compile after running ts-migrate?

A

If your project fails to compile after running ts-migrate, something went wrong with the migration.

Check for syntax errors in the generated TypeScript files or missing dependencies. The tool is supposed to create compiling code

  • if it doesn't compile, you might have hit an edge case or bug.
Q

Is it normal for my IDE to show 500 TypeScript errors after migration?

A

Yes, but they're hidden behind @ts-expect-error comments. ts-migrate doesn't fix your type errors

  • it just silences them so your code compiles. You'll see the real errors when you start removing those comments. This is normal and expected
  • you're not doing anything wrong.
Q

Is it normal for everything to be typed as `any`?

A

Yep, that's totally normal. ts-migrate does figure out types from PropTypes, but it falls back to any (aliased as $TSFixMe) for most things it can't figure out. The tool creates a compiling foundation, not good TypeScript. Expect to spend months replacing any types with real ones.

Q

What is $TSFixMe?

A

$TSFixMe is just an alias to any: type $TSFixMe = any;. Airbnb uses this convention for simplifying the migration experience. They also have the same alias for functions: type $TSFixMeFunction = (...args: any[]) => any;. This makes it easier to identify and track areas that need type improvements.

Q

Why does ts-migrate break my imports?

A

Because it's not smart enough to handle barrel exports, dynamic imports, or webpack aliases. It assumes you use standard relative imports like a civilized person. If you have custom module resolution, expect to manually fix hundreds of import statements.

Q

How long until I stop hating this decision?

A

The initial migration takes a few hours. The follow-up work to make it actually good TypeScript? 6-18 months if you're dedicated, 3+ years if you're realistic about your team's bandwidth. Some never finish and just live with the $TSFixMe types forever. It's better than JavaScript, so there's that.

Q

Should I panic when I see 200 `any` types?

A

No, this is normal. ts-migrate is a bulldozer, not a surgeon. It creates compiling TypeScript by adding any types everywhere it can't figure out the real type. Think of it as technical debt that you'll pay off slowly over time. At least your code compiles now.

Q

Is ts-migrate framework-oriented?

A

By itself, ts-migrate is not related to any specific framework. However, the default configuration contains plugins expecting a React codebase as input. The tool hasn't been extensively tested on other frameworks, so use with non-React projects is at your own risk.

Q

What if ts-migrate breaks my code?

A

If you encounter issues, you should file an issue on GitHub. The tool automatically commits at each step when using ts-migrate-full, making it easy to rollback changes if needed.

Q

Can I customize the migration process?

A

Yes, ts-migrate uses a plugin-based architecture that allows customization. You can create custom configs with different sets of plugins for specific needs. The tool currently has two main migration configs: JavaScript → TypeScript migration and the reignore script.

Q

How does the --sources flag work?

A

The --sources flag allows you to migrate specific parts of your project by providing a relative path from your project root. It accepts glob patterns and effectively replaces your tsconfig.json's include property. You can pass multiple --sources flags to include different sections of your codebase.

Q

When should I use the reignore command?

A

Use reignore when you've made project-wide changes (TypeScript updates, library upgrades, type improvements) that introduce new compilation errors. Instead of fixing all errors manually, reignore will add any or @ts-expect-error comments to make your project compilable again.

Q

What TypeScript version is required?

A

ts-migrate was built for TypeScript 4.x. If you're on TypeScript 5.x, expect weird edge case failures that nobody has time to fix since the tool is basically in maintenance mode.

Q

How successful was ts-migrate at Airbnb?

A

According to the development team, ts-migrate was used extensively at Airbnb and helped migrate the main part of their entire codebase to TypeScript. They were able to provide much better starting points for huge applications and complete migrations that would have taken much longer manually.

Essential Resources (The Stuff You'll Actually Use)

Related Tools & Recommendations

tool
Similar content

TypeScript Overview: Catch Bugs Early with JavaScript's Type System

Microsoft's type system that catches bugs before they hit production

TypeScript
/tool/typescript/overview
100%
tool
Similar content

ESLint - Find and Fix Problems in Your JavaScript Code

The pluggable linting utility for JavaScript and JSX

/tool/eslint/overview
98%
howto
Similar content

Migrate JavaScript to TypeScript Without Losing Your Mind

A battle-tested guide for teams migrating production JavaScript codebases to TypeScript

JavaScript
/howto/migrate-javascript-project-typescript/complete-migration-guide
91%
tool
Similar content

TypeScript Migration Troubleshooting Guide: Fix Common Issues

This guide covers the shit that actually breaks during migration

TypeScript
/tool/typescript/migration-troubleshooting-guide
66%
tool
Similar content

Prisma ORM: TypeScript Client, Setup Guide, & Troubleshooting

Database ORM that generates types from your schema so you can't accidentally query fields that don't exist

Prisma
/tool/prisma/overview
59%
tool
Similar content

Turborepo Overview: Optimize Monorepo Builds & Caching

Finally, a build system that doesn't rebuild everything when you change one fucking line

Turborepo
/tool/turborepo/overview
57%
tool
Similar content

JupyterLab Extension Development Guide: Build Custom Tools

Stop wrestling with broken tools and build something that actually works for your workflow

JupyterLab
/tool/jupyter-lab/extension-development-guide
55%
tool
Similar content

React State Management: Choose the Best Solution for Your App

Redux is overkill. Context breaks everything. Local state gets messy. Here's when to use what.

React
/tool/react/state-management-decision-guide
55%
pricing
Similar content

TypeScript vs JavaScript: The True Development Cost Explained

TypeScript devs cost 30% more, builds take forever, and your junior devs will hate you for 3 months. But here's exactly when the math works in your favor.

TypeScript
/pricing/typescript-vs-javascript-development-costs/development-cost-analysis
52%
tool
Similar content

Microsoft MAI-1-Preview: Developer Debugging & Troubleshooting Guide

Why your $450M AI model keeps suggesting any types and how to work around the disappointment

Microsoft MAI-1-preview
/tool/microsoft-mai-1/developer-troubleshooting
52%
tool
Similar content

Deno Overview: Modern JavaScript & TypeScript Runtime

A secure runtime for JavaScript and TypeScript built on V8 and Rust

Deno
/tool/deno/overview
52%
tool
Similar content

Drizzle ORM Overview: The TypeScript ORM That Doesn't Suck

Discover Drizzle ORM, the TypeScript ORM that developers love for its performance and intuitive design. Learn why it's a powerful alternative to traditional ORM

Drizzle ORM
/tool/drizzle-orm/overview
48%
tool
Similar content

Node.js Overview: JavaScript on the Server & NPM Ecosystem

Run JavaScript outside the browser. No more switching languages for frontend and backend.

Node.js
/tool/node.js/overview
48%
news
Popular choice

U.S. Government Takes 10% Stake in Intel - A Rare Move for AI Chip Independence

Trump Administration Converts CHIPS Act Grants to Equity in Push to Compete with Taiwan, China

Microsoft Copilot
/news/2025-09-06/intel-government-stake
45%
tool
Similar content

GraphQL Overview: Why It Exists, Features & Tools Explained

Get exactly the data you need without 15 API calls and 90% useless JSON

GraphQL
/tool/graphql/overview
43%
tool
Similar content

Node.js ESM Migration: Upgrade CommonJS to ES Modules Safely

How to migrate from CommonJS to ESM without your production apps shitting the bed

Node.js
/tool/node.js/modern-javascript-migration
43%
tool
Similar content

Solana Web3.js Guide: Versions, Installation, & Dev Tips

Master Solana Web3.js: Understand v1.x vs v2.0, installation, and real-world development. Get practical tips for building Solana dApps and Anchor compatibility.

Solana Web3.js
/tool/solana-web3js/overview
43%
tool
Similar content

Web3.js End-of-Life: Migrating Production Legacy Apps

Web3.js reached end-of-life on March 5th, 2025. Learn what this means for your production legacy applications, potential vulnerabilities, and how to plan for mi

Web3.js
/tool/web3js/production-legacy-apps
43%
tool
Popular choice

Jaeger - Finally Figure Out Why Your Microservices Are Slow

Stop debugging distributed systems in the dark - Jaeger shows you exactly which service is wasting your time

Jaeger
/tool/jaeger/overview
43%
review
Recommended

ESLint + Prettier Setup Review - The Hard Truth About JavaScript's Golden Couple

After 7 years of dominance, the cracks are showing

ESLint
/review/eslint-prettier-setup/performance-usability-review
43%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization