At a glance
Last verified 21 October 2026 with TypeScript 5.9.3 (the examples); Flow per its documentation and releases, not run here.
| Compared | JSDoc with TypeScript | Flow |
|---|---|---|
| Checker | tsc, from the typescript package | flow, from the flow-bin package |
Types in a .js file | JSDoc comments: /** @param {string} name */ | Flow syntax, or comment types: /*: string */ and /*:: … */ |
| Which files are checked | checkJs in jsconfig.json, or // @ts-check per file | Files with a @flow comment, or all files with all=true in .flowconfig |
| Type syntax inside the comments | TypeScript's: string | null, Readonly<T>, unknown | Flow's: ?string, $ReadOnly<T>, mixed, exact objects |
| Reads the other's types | No: Flow comment types are plain comments to tsc | No: Flow does not read JSDoc types |
| Package types | .d.ts files, which TypeScript, editors and most tools read | .js.flow files and flow-typed definitions |
| Latest release (21 October 2026) | TypeScript 7.0.2 (this site checks with 5.9.3) | Flow 0.336.0, 15 October 2026 |
Two checkers for typed JavaScript
Flow and TypeScript are both checkers for JavaScript, and both can work on plain .js files with the types kept in comments: Flow through its comment syntax, TypeScript through JSDoc. They are separate checkers with separate type systems, and neither reads the other’s annotations.
Where they stand on 21 October 2026, per their own sites: Flow ships frequent releases (0.336.0 on 15 October 2026), and flow.org describes it as a typed dialect of JavaScript used in production at Meta. A 2021 post on Flow’s direction and its open source engagement is now marked historical on the Flow blog. TypeScript’s checker is the one most editors run for JavaScript, and the one packages publish .d.ts files for. We did not run Flow for this page.
The same function, typed both ways
Flow’s comment types put Flow syntax inside comments, so the file runs without a build: /*: Type */ after a name, and /*:: … */ around a whole declaration such as a type alias. To TypeScript those are ordinary comments, so the function below has an untyped parameter, which strict reports, and the wrong call at the bottom passes:
// @flow
/*:: type LineItem = { sku: string, quantity: number, unitCents: number }; */
export function totalCents(items /*: Array<LineItem> */) /*: number */ {error TS7006: Parameter 'items' implicitly has an 'any' type.
let sum = 0;
for (const item of items) sum += item.quantity * item.unitCents;
return sum;
}
totalCents("not a list");jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["**/*.js"]
} The JSDoc version of the same file, checked by tsc, with the wrong call caught:
/** @typedef {{ sku: string, quantity: number, unitCents: number }} LineItem */
/**
* @param {LineItem[]} items
* @returns {number}
*/
export function totalCents(items) {
let sum = 0;
for (const item of items) sum += item.quantity * item.unitCents;
return sum;
}
totalCents("not a list");error TS2345: Argument of type 'string' is not assignable to parameter of type 'LineItem[]'.type LineItem = { sku: string; quantity: number; unitCents: number };
export function totalCents(items: LineItem[]): number {
let sum = 0;
for (const item of items) sum += item.quantity * item.unitCents;
return sum;
}
totalCents("not a list");error TS2345: Argument of type 'string' is not assignable to parameter of type 'LineItem[]'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["**/*.js"]
} Moving from Flow to JSDoc
A file-by-file move works the way any migration to checked JavaScript does: add // @ts-check to a file, rewrite its annotations, remove // @flow. The translations are mostly mechanical:
| Flow | JSDoc for TypeScript |
|---|---|
name /*: string */ | @param {string} name above the function |
/*:: type Item = { … }; */ | @typedef {{ … }} Item |
?string (maybe type) | string | null | undefined |
mixed | unknown |
$ReadOnly<T>, $ReadOnlyArray<T> | Readonly<T>, readonly T[] |
{| a: string |} (exact object) | { a: string }: TypeScript’s object literal checks are similar, not identical |
import type { T } from "./x" | /** @import { T } from "./x.js" */ |
Two differences need care rather than translation. Flow’s object types are exact by default, while TypeScript checks extra properties only on fresh object literals, so code that relied on exactness elsewhere loses that check. And Flow’s ?T means “may be null or undefined”, which is wider than TypeScript’s optional property a?: T. Run tsc with strict from the first file, so both show up as errors rather than surprises.
For packages, publish .d.ts files when you switch: shipping types from a JavaScript package covers writing them from JSDoc.
Which to choose
Choose JSDoc with TypeScript when…
- You are starting to type a JavaScript codebase today: editors, packages'
.d.tsfiles and most tooling speak TypeScript. - You publish packages:
.d.tsfiles reach the most users.
Choose Flow when…
- The codebase already uses Flow heavily and works well with it, and the cost of moving is higher than the cost of staying.
- You rely on Flow-specific checking that you would lose in a move, and have weighed that against the ecosystem around TypeScript.
Questions
Can TypeScript read Flow comment types?
No. To tsc, /*: string */ is an ordinary comment. A parameter typed only that way is untyped to TypeScript, which strict reports as TS7006, as the example on this page shows.
Is Flow still maintained?
Yes. Releases continue (0.336.0 came out on 15 October 2026), and flow.org describes Flow as used in production at Meta. Its tooling and documentation are centered on that use.
Is there an official Flow-to-TypeScript converter?
Meta publishes flow-api-translator, which writes TypeScript .d.ts files from Flow source; its README says it is not meant as a tool for migrating away from Flow. Community converters exist, but the best known, Khan Academy's flow-to-ts, is archived.
Sources
- Flow: comment types · Flow documentation
- Flow: .flowconfig [options] (all) · Flow documentation
- Flow releases (v0.336.0) · GitHub
- Clarity on Flow's Direction and Open Source Engagement (2021, marked historical) · Flow blog
- JSDoc Reference · TypeScript handbook
Last reviewed 21 October 2026.