2. Complete migration from Flow type to TypeScript
Date: 2025-07-08
Status
Proposed
Context
Our codebase (~550k LOC) currently uses Flow v0.142.0 (released 6 Jan 2021). It’s fast and allows the team to instantly see the changes, but the Meta decided to make it an internal tool and deprioritized community requests. This is now blocking us in several ways:
- react‑relay upgrade – Relay 13.x introduces new Flow syntax that requires Flow upgrade.
- Library support dwindling – Most actively‑maintained React packages ship first‑class TypeScript typings and drop Flow definitions entirely; community fixes land more slowly for Flow. Major engineering organisations (e.g. Pinterest) have completed large‑scale migrations from Flow to TypeScript in 2025, citing hiring advantages and richer tooling. (medium.com)
- Ecosystem momentum – Developer surveys show TypeScript adoption continuing to rise year‑over‑year, while Flow usage is now well below 1 %. (blog.jetbrains.com)
Given these pressures, remaining on Flow imposes an escalating maintenance tax and blocks vital dependency upgrades.
Alternatives Considered
1. Upgrade Flow to the latest version (v0.218 as of Jul 2025)
| Factor | Details |
|---|---|
| Implementation steps | 1. Incrementally bump Flow to v0.218.2. Run the official codemods (flow-upgrade-codemods).3. Refactor legacy syntax (exact objects, variance) and resolve newly surfaced errors.4. Add suppression comments where conversion is non‑trivial. |
| Pros | - No wholesale language switch — preserves current annotations and team familiarity.- Compiler remains faster than TypeScript for cold builds.- Minimal changes to CI, linters, and tooling pipeline. |
| Cons | - Flow’s community ecosystem has shrunk; most new libraries ship only TS types.- Upgrading buys limited time. - Type definition gaps require manual stubs or any. |
Why we did not choose this path: While technically feasible, it keeps us on an increasingly isolated toolchain and does not solve the ecosystem‑support challenges. The incremental cost of later migrating to TypeScript would be higher once more third‑party code depends on TS‑only definitions.
Decision
We will migrate the entire frontend codebase to TypeScript 5.7. Key points:
-
Migration approach
- Freeze Flow and prohibit new Flow‑typed code.
- Apply
flow-to-tscodemods in batches (≈ 10 k LOC per PR). - Enable
// @ts-nocheckat file level initially; remove flags as we raise strictness. - Treat the Relay compiler as the source of truth for generated
.d.tsartefacts; switchrelay-compilerto emit TypeScript.
-
Compiler settings (
tsconfig.json)strict,noImplicitAny,exactOptionalPropertyTypesincremental,composite,skipLibCheckto keep CI times reasonable.
-
Tooling
- Replace
eslint-plugin-flowtypewith@typescript-eslint+eslint-plugin-react. - Adoptts-nodefor scripts and vitest for unit and integration tests. - Update CI to run
pnpm type-checkin parallel with existing unit tests.
- Replace
Consequences
Benefits
- We can upgrade to the latest
react-relayand unblock relay compiler improvements. - Richer IDE support and a far larger pool of external typings.
- Recruiting and onboarding improve: TypeScript is a baseline skill for most React developers.
Drawbacks & Mitigations
| Risk | Impact | Mitigation |
|---|---|---|
| Longer compile times | Slower local feedback | There’s no simple solution, usually using Mac on ARM cpu |
| Migration bugs | Runtime regressions | Dual‑run Flow and TS CI until coverage ≥ 90 % |
Overall, the one‑off migration cost is outweighed by improved library compatibility and developer experience.