---
title: "TypeScript vs Flow"
slug: "typescript-vs-flow"
category: "comparisons"
tags: ["comparisons", "typescript", "flow", "static-typing", "javascript", "tooling"]
status: "stable"
last_updated: 2026-05-14
summary: "Use TypeScript for all new projects; keep Flow only if your codebase already runs it with active investment."
related: ["[[comparisons/typescript-vs-javascript]]", "[[comparisons/swc-vs-babel]]", "[[comparisons/eslint-vs-biome]]", "[[coding/typescript]]", "[[tooling/github]]", "[[comparisons/jest-vs-vitest]]", "[[comparisons/vite-vs-webpack]]"]
---

## Overview

TypeScript is the default for static typing in JavaScript projects as of 2026. Its tooling, community, ecosystem support, and hiring pool dwarf Flow's. Use Flow only if you maintain a Meta-stack codebase (React Native, Relay) that already runs Flow with active tooling investment. For any new project, the answer is TypeScript. See [[coding/typescript]] for project setup conventions.

## When TypeScript wins

TypeScript is the right pick for virtually all new JavaScript and Node.js projects.

- Ecosystem breadth: every major library ships `@types/*` or first-party declarations. Flow type stubs for third-party libraries are sparse and often outdated.
- Tooling depth: the TypeScript Language Server (tsserver) powers VS Code, Neovim, JetBrains, and every major editor. Autocomplete, go-to-definition, and refactoring across large codebases work reliably.
- Build pipeline: [[comparisons/swc-vs-babel]] and esbuild both strip TypeScript annotations without type-checking, making builds fast. Vite, Bun, and Next.js all treat TypeScript as first-class input.
- Community: the TypeScript tag on Stack Overflow has 50x more answers than Flow. Hiring TypeScript engineers is straightforward; Flow engineers are a niche pool.
- Strict mode: `strict: true` in `tsconfig.json` turns on null checking, exact optional properties, and unchecked indexed access. Flow's strict mode exists but is less battle-tested in large codebases.
- Incremental adoption: rename a `.js` file to `.ts` and add types one file at a time. The compiler accepts `// @ts-ignore` and `any` as escape hatches during migration.

## When Flow wins

Flow's advantage is narrow and shrinking. Stay on Flow when all of the following are true.

- The codebase already runs Flow with a recent version (0.230+) and the team actively maintains type coverage.
- The project uses Relay or React Native with Meta's internal toolchain, where Flow's type system is tuned for those patterns.
- Migration cost is genuinely prohibitive: a monorepo with millions of Flow-annotated lines and no automated codemod budget is a real constraint.

Outside that window, Flow is a maintenance liability. Meta continues to ship it but the external community has largely moved on. New contributors will not know it.

## Trade-offs at a glance

| Dimension             | TypeScript                                 | Flow                                         |
| --------------------- | ------------------------------------------ | -------------------------------------------- |
| Ecosystem coverage    | Near-universal `@types` and native types   | Sparse; many libraries untyped               |
| Editor support        | First-class in all major editors           | Decent in VS Code via extension; inconsistent elsewhere |
| Build speed           | Strip-only with SWC or esbuild             | `flow-remove-types` or Babel plugin          |
| Community size        | Very large                                 | Small; Meta-focused                          |
| Strict null checks    | `strict: true`                             | `strict` mode; less adoption                 |
| Learning resources    | Abundant                                   | Limited                                      |
| Framework integration | React, Vue, Angular, Next.js, Astro, all   | React and React Native primarily             |
| Hiring                | Large pool                                 | Niche                                        |
| Active external dev   | Yes (Microsoft-led)                        | Minimal outside Meta                         |
| Migration tooling     | `flowToTs`, ts-migrate, manual             | N/A (you migrate away from it)               |

## Migration cost

Flow to TypeScript is the common direction and is supported by codemods.

- `flow-to-ts`: converts Flow annotations to TypeScript syntax. Handles most constructs; expect 10 to 20 percent of files needing manual cleanup, especially around opaque types, variance annotations, and `$ObjMap`.
- `ts-migrate` from Airbnb: inserts `any` where type inference fails and gets the project compiling fast. Plan a second pass to tighten types after the build passes.
- Timeline: a 50 kloc Flow codebase typically migrates in one to three sprints depending on Flow coverage depth and library dependency sprawl.
- The hardest part is third-party types: libraries that had Flow stubs but no `@types` need type declarations written or sourced from DefinitelyTyped.

TypeScript-to-Flow migration has no documented tooling and would be a regression. Do not do it.

## Recommendation

- New project: TypeScript. No caveats.
- Existing Flow project, active and healthy: stay on it; do not rewrite for its own sake. Migrate opportunistically when a module undergoes significant change.
- Existing Flow project showing type rot (stale stubs, contributors unfamiliar with Flow): migrate. Budget one sprint per 20 kloc of annotated code.
- Mixed codebase: TypeScript files and Flow files do not coexist in the same module graph. Migrate module by module with a clear boundary.

## Related

- [[comparisons/typescript-vs-javascript]]
- [[comparisons/swc-vs-babel]]
- [[comparisons/eslint-vs-biome]]
- [[coding/typescript]]
- [[comparisons/jest-vs-vitest]]
- [[comparisons/vite-vs-webpack]]
