THE MIGRATION LINE
INCIDENT // AIRBNB-2020MIGRATED

Airbnb converted a 6-million-line frontend monorepo to TypeScript by writing a tool that migrates a whole project in a day — and deliberately fills it with types that are wrong on purpose.

AIRBNB·2020·TYPESCRIPT / JAVASCRIPT / CODEMOD / FRONTEND·✓ Sourced — medium.com
System stress over timeBreach at T+3
~6M linesFrontend monorepo
~86%, targeting 95%Converted
50,000+ lines in one dayMigration speed
SITUATION

Six million lines, and a new official language

After a proposal, a beta period, and formal approval, TypeScript became the official language of frontend web development at Airbnb. That settles what new code looks like. It says nothing about the code that already exists.

What already existed was a frontend monorepo of roughly 6 million lines, plenty of it JavaScript, some of it partially TypeScript already, and much of it littered with @ts-ignore comments from earlier partial attempts.

COMPLICATION

Migrating file by file sounds safer than it is

The obvious approach is gradual: TypeScript is designed to let .ts and .js coexist, so convert a file, then the next, and let the project drift over. It’s the low-risk answer, and it doesn’t pause anyone’s work.

QUESTION

How do you convert a project in one shot without stopping to type it?

Airbnb chose to go all-in per project: a project is JavaScript, and then it’s TypeScript, with nothing in between. That guarantees every file in the project is in the same state.

But an all-in conversion runs straight into the reason people migrate gradually. A 50,000-line project doesn’t compile as TypeScript the moment you rename the files — it produces thousands of type errors, and fixing all of them properly is weeks of human work per project. So the real question is: how do you get a compiling TypeScript project out the other side today, without first solving every type in it?

ANSWER

Make it compile, and write down every lie you told

The answer is ts-migrate, which Airbnb built and open-sourced. It renames the files, then runs a chain of codemod plugins driven by real diagnostics from the TypeScript language server. Some plugins add explicit any types where the compiler complains; some declare missing class properties; React-specific plugins convert PropTypes into type definitions, handle defaultProps, and annotate lifecycle methods. Formatting is fixed by running prettier-eslint, and anything still failing gets an @ts-ignore comment carrying the actual diagnostic — TS2339: Property 'x' does not exist — so the reason is recorded, not erased.

Its stated goal is precise and modest: get a compiling TypeScript project with basic type coverage that does not change the application’s runtime behavior. Not a well-typed project. A compiling one, that behaves identically. Projects of over 50,000 lines were converted in a single day, and engineers were freed to spend their time improving types rather than performing the mechanical conversion.

TAKEAWAY

What the tool doesn't promise

Airbnb is direct about the limits. There’s no guarantee an automated migration ends error-free. Hooks weren’t covered, because the codebase was on an older React version at the time. The output carries plenty of $TSFixMe and suppressed errors that still need human review, and better typing of state and props remained future work. At the time of writing, about 86% of the monorepo had been converted, with 95% expected by year-end.

What they bought wasn’t type safety. It was a uniform starting line — every file in a project in the same state, on the same day, with the remaining work visible in the code itself.

A migration finishes faster when you separate “change the language” from “get the types right” — but only if you name every shortcut you took while doing it.

Source — read the original

A plain-language, AI-drafted and human-edited retelling of the article published on medium.com, reorganized and explained in our own structure and words, with original analysis in the editor's note above. The facts, numbers, and decisions belong to the original author and are not altered. For the full depth, read the source.

← All systems