· typescript / flow / javascript

TypeScript vs Flow — Flow còn cầm cự được bao lâu?

TypeScript dẫn trước 244:1 về lượt tải, hỗ trợ Node.js native, và compiler 10× nhanh hơn vào 2026. Flow sống sót ở Meta — zombie-ware ở mọi nơi còn lại.

Bởi

2.417 từ · 13 phút đọc

Dự án mới? Chọn TypeScript, không cần bàn thêm. Nếu bạn đang dùng Flow ngoài Meta, hãy bắt đầu lên kế hoạch migration — khoảng cách giữa hai ecosystem giờ đã đủ lớn để việc giữ nguyên trở thành một khoản chi phí thực sự. Flow vẫn được duy trì tích cực, nhưng chỉ phục vụ nội bộ Meta. Với tất cả những người khác, đó là zombie-ware: còn thở, nhưng không ai chăm sóc ở nơi quan trọng.

Bài này dành cho ai

Kỹ sư đang chọn hệ thống type tĩnh cho dự án JS hoặc React mới, và các team đang dùng Flow mà không biết có nên migrate không. Nếu bạn đang ở Meta và làm thứ gì đó liên quan đến React internals, bài so sánh này không áp dụng cho bạn — Flow là ràng buộc, không phải lựa chọn.

Chúng tôi đã test gì

TypeScript 6.0.3 (phát hành 2026-03-23) và Flow 0.315.0 (phát hành 2026-05-28). Dữ liệu lượng tải về từ npmtrends.com, snapshot tháng 5/2026. Trải nghiệm IDE trên VSCode 1.98, macOS: TypeScript language service tích hợp sẵn, Flow Language Support extension v3.1.3. Benchmark incremental check lấy từ một bài test công khai tháng 5/2026 trên monorepo 50.000 dòng, chạy trên AWS EC2 G4dn.xlarge / Ubuntu 24.04 / 16 GB RAM.

Tổng quan

TypeScript ra mắt năm 2012 — Microsoft muốn giải quyết bài toán scale JavaScript ở quy mô doanh nghiệp. Flow ra đời ở Facebook năm 2014 với hướng tiếp cận khác: typing dần dần thông qua opt-in từng file bằng // @flow, tích hợp chặt chẽ với React và Babel’s AST.

Vài năm đầu, cuộc cạnh tranh thực sự có ý nghĩa. Flow inference sắc bén hơn ở một số chỗ, React integration là first-party, và sự chống lưng của Facebook tạo cảm giác lâu dài. Cộng đồng React chia đôi: các shop lớn gần với Facebook dùng Flow, phần lớn ecosystem còn lại chọn TypeScript hoặc không dùng gì cả.

Đến năm 2026, cuộc chiến đã kết thúc. TypeScript thắng. Câu hỏi còn lại chỉ là: có lý do gì chính đáng để giữ Flow trong một codebase hiện có, hay bạn chỉ đang trì hoãn một migration sẽ ngày càng tốn kém hơn?

Ecosystem hiện tại (2026)

Con số tải về nói thẳng vào vấn đề.

TypeScript: ~143,7 triệu lượt tải về npm mỗi tuần. Flow (qua flow-bin): ~587.000. Tỉ lệ 244:1.

State of JS 2025 ghi nhận 40% người tham gia chỉ viết TypeScript — tăng từ 34% năm 2024 và 28% năm 2022. Chỉ 6% dùng JavaScript thuần. Flow không xuất hiện trong khảo sát, dù chỉ là chú thích.

TypeScript xếp hạng #1 trên GitHub theo số người đóng góp hàng tháng vào tháng 8/2025: 2,6 triệu contributors, tăng 66% so với cùng kỳ.

Ecosystem @types/* — type definitions cho các package bên thứ ba — được xây dựng gần như hoàn toàn trên TypeScript. Khi import một package trong TypeScript, khả năng cao là IDE đã cho bạn autocomplete và báo lỗi mà không cần cấu hình gì. Với Flow, bạn tự lo cho mọi package không ship Flow types — mà đó là phần lớn.

Các migration thực tế cũng cho thấy dòng chảy đang chạy về hướng nào. Pinterest di chuyển 3,7 triệu dòng từ Flow sang TypeScript vào tháng 4/2025. Stripe migrate 6,5 triệu dòng bằng codemod tùy chỉnh. Factorial chuyển hơn 400.000 dòng. Không ai migrate theo chiều ngược lại.

Tooling

Đây là nơi trải nghiệm hàng ngày khác biệt rõ nhất.

Hỗ trợ IDE

VSCode và TypeScript không cần cấu hình. TypeScript được tích hợp vào bản thân VSCode — cả hai đều của Microsoft. Mở một file .ts và bạn có đầy đủ IntelliSense, gạch chân lỗi, go-to-definition, rename, và refactor. Không cần extension, không cần binary, không cần config file.

VSCode và Flow đòi hỏi cài thêm Flow Language Support extension (v3.1.3, 3/5 sao trên 43 đánh giá). Bạn còn cần một binary Flow local, một file .flowconfig ở project root, và // @flow ở đầu mỗi file muốn được kiểm tra. Repository riêng của extension bị archive vào ngày 19/12/2024 — development chuyển vào monorepo chính facebook/flow, nhưng người dùng đã trải qua gần hai năm (từ tháng 1/2022 đến tháng 12/2024) không có bản release mới, kèm theo các báo cáo về IDE crash, server treo, và diagnostics cũ.

Extension đã ổn hơn (v3.0 là một bản viết lại), nhưng niềm tin đã mất. 3/5 sao sau nhiều năm mất ổn định phản ánh sự hoài nghi còn đó.

JetBrains (WebStorm, IntelliJ): cả TypeScript và Flow đều có hỗ trợ built-in trong 2026.1. TypeScript sâu hơn — tsconfig.json được tự động nhận diện, TypeScript Language Service được tích hợp sẵn, không cần annotation từng file. Flow có mặt nhưng ở mức thứ yếu.

Nếu team bạn dùng Cursor — editor AI-first xây trên VS Code — zero-config setup của TypeScript có nghĩa là các tính năng AI (autocomplete, inline edits, codebase-aware chat) hoạt động ngay. Flow đòi setup thủ công như VSCode, và lịch sử mất ổn định của extension khiến lớp AI thường nhận được type context cũ hoặc thiếu.

Node.js native type stripping

TypeScript 5.8 (tháng 2/2025) giới thiệu --erasableSyntaxOnly, một flag giới hạn TypeScript chỉ dùng syntax mà Node.js có thể strip natively. Node.js 22.18 (phát hành 31/7/2025) đã ship tính năng này ở trạng thái stable — bạn có thể chạy file .ts trực tiếp bằng node trên Node 22.18+ mà không cần bước build.

Flow không có con đường tương tự. Nó không được thiết kế theo mô hình JS-runtime-first mà TypeScript đang hướng đến.

Migration tooling

Khi bạn sẵn sàng migrate từ Flow sang TypeScript, lựa chọn chính là @khanacademy/flow-to-ts. Lần publish cuối: 27/4/2021. Repository bị archive: 26/4/2024. Tool này xử lý được hầu hết object types, interfaces, function signatures, và React-specific types — nhưng tự mô tả là “WIP — nhiều thứ vẫn chưa hoạt động đúng.”

Codemod của Stripe (stripe-archive/flow-to-typescript-codemod) cũng bị archive. Cả hai tool đều coi migration là vấn đề đã giải quyết xong một khi phục vụ xong mục đích nội bộ.

Thực tế là: bạn chạy codemod, nó convert khoảng 80–90% codebase tự động, rồi bạn dành nhiều tuần sửa tay phần còn lại. Khoảng cách giữa “đã convert” và “compile sạch” có thể lớn tùy thuộc vào lượng Flow-specific syntax bạn đã dùng.

Với team TypeScript vừa hoàn thành migration, Biome vs ESLint phân tích liệu hệ sinh thái linting 2026 đã đủ để chuyển đổi như một phần của cùng quá trình.

Hiệu năng

Về tốc độ incremental type-checking, Flow nhanh hơn hiện tại.

Trên monorepo 50.000 dòng ở watch mode, Flow hoàn thành incremental check trong 2,1 giây. TypeScript mất 4,8 giây — chậm hơn 2,3 lần.

Dữ liệu nội bộ của Meta từ năm 2021, sau khi triển khai Types-First architecture, cho thấy thời gian recheck trung bình giảm từ 9,10s xuống 1,37s (−85%) và p99 giảm từ 107s xuống 5,63s (−95%). Server model của Flow luôn được thiết kế để giữ incremental check nhanh.

Lợi thế này có thực, nhưng nhiều khả năng chỉ tạm thời.

TypeScript 7.0 Beta ra mắt ngày 21/4/2026 với compiler viết bằng Go, nhắm mục tiêu hiệu năng nhanh hơn ~10× so với TypeScript 6.0. Với 10×, incremental check của TypeScript trên repo 50.000 dòng tương tự sẽ xuống còn khoảng 0,5 giây — thấp hơn nhiều so với 2,1s của Flow.

TypeScript 7.0 đang ở bản beta tại thời điểm viết bài. Go compiler là mục tiêu phát triển chính và các bản production dự kiến cuối năm 2026. Lợi thế tốc độ của Flow đang đếm ngược.

Cần lưu ý thêm: việc Flow đang được viết lại ~50% bằng Rust (có thể thấy trong phân tích ngôn ngữ của repo — 49,9% Rust, 30,3% OCaml — nhưng chưa được công bố chính thức) nhiều khả năng nhằm duy trì khả năng cạnh tranh về hiệu năng. Nhưng bản rewrite chưa được ship công khai, và chưa có thông báo nào về mục tiêu cụ thể.

Tiêu chíTypeScriptFlow
Type inference✅ Mạnh (satisfies, const params, conditional types)✅ Tốt (conditional types thêm năm 2024)
Hỗ trợ IDE✅ Tích hợp VSCode (zero config)⚠️ Cần extension (3/5 sao)
Tuỳ chọn strictnessstrict, noUncheckedIndexedAccess, v.v.flow strict mode
Cộng đồng/ecosystem✅ 143M lượt tải/tuần⚠️ 588K lượt tải/tuần
Migration path— (đã ở đây rồi)⚠️ flow-to-ts (archive 2024)
Bảo trì tích cực✅ Microsoft, ra mắt hàng quý✅ Meta, ra mắt hàng tuần
Mức độ áp dụng bên ngoài✅ 40% dùng độc quyền (State of JS 2025)❌ Không xuất hiện trong khảo sát
Tốc độ (incremental)⚠️ 4,8s (repo 50K dòng)✅ 2,1s (repo 50K dòng)
Node.js native strip✅ Node 22.18+ (Jul 2025)❌ Không hỗ trợ

Migration

Nếu bạn đang dùng Flow và muốn chuyển, đây là những gì bạn thực sự cần đối mặt.

Codemod xử lý được phần đơn giản. @khanacademy/flow-to-ts tự động convert object types, interfaces, function signatures, React types, và generic annotations. Bạn nhận được khoảng 80–90% conversion miễn phí.

Phần còn lại bạn phải sửa tay. Ba loại Flow-specific syntax không có cách convert tự động sạch sẽ:

  • %checks type predicates — bị xoá kèm warning, logic phải viết lại thành TypeScript type predicates
  • $Keys<T> utility type — tương đương là keyof T, nhưng codemod không phải lúc nào cũng bắt được trong context
  • $FlowFixMe suppression comments — phải đổi thành // @ts-ignore hoặc // @ts-expect-error

Một ví dụ trước/sau tối giản để hình dung phần dễ trông như thế nào:

// TRƯỚC (Flow)
// @flow
type User = {
  id: number,
  name: string,
  email: ?string,
};

function greet(user: User): string {
  return `Hello, ${user.name}`;
}

const getUser = (id: number): Promise<User> =>
  fetch(`/users/${id}`).then(r => r.json());
// SAU (TypeScript)
type User = {
  id: number;
  name: string;
  email: string | null;  // ?T thành T | null
};

function greet(user: User): string {
  return `Hello, ${user.name}`;
}

const getUser = (id: number): Promise<User> =>
  fetch(`/users/${id}`).then(r => r.json());

Các điểm khác biệt syntax chính:

  • ?T (nullable) → T | null
  • Trailing comma trong object types → dấu chấm phẩy (hoặc dấu phẩy; cả hai đều hợp lệ trong TypeScript)
  • // @flow bị xoá — TypeScript opt-out qua tsconfig.json, không opt-in từng file
  • $Keys<T>keyof T
  • $Values<T>T[keyof T]

Quy mô là yếu tố quyết định. Migration 3,7 triệu dòng của Pinterest tốn đáng kể thời gian kỹ sư dù đã có automation. Stripe phải xây codemod nhiều bước tùy chỉnh (Babel conversion pass + ts-morph error-fixing pass) để xử lý codebase nặng React. Không công ty nào tìm được giải pháp ấn nút là xong.

Hệ quả thực tế: bắt đầu migration trước khi team thêm vào codebase thêm vài trăm nghìn dòng Flow. Khoảng cách giữa lần publish cuối của flow-to-ts (2021) và hiện tại (2026) là năm năm. Nó sẽ không cải thiện.

Kết luận

Flow không chết. Nó có bản release hàng tuần, bản Rust rewrite gần như hoàn toàn đang trong quá trình (chưa phát hành), và React Component Syntax đã được triển khai trên các codebase nội bộ của Meta. Meta đang chạy nó trên hàng trăm triệu dòng code nội bộ và đặt cược tài nguyên kỹ thuật vào đó.

Nhưng “không chết” là một ngưỡng quá thấp. Với bất kỳ ai ở ngoài Meta, Flow năm 2026 là zombie-ware. Ecosystem đã đi tiếp, tooling IDE có lịch sử đứt đoạn, migration tooling bị archive, và lý do duy nhất để ở lại với Flow là chi phí để thoát ra.

Tình huốngKhuyến nghịLý do
Dự án mớiTypeScriptEcosystem, IDE, Node native strip, TS 7.0 sắp ra
Codebase Flow cũ (công ty ngoài Meta)Lên kế hoạch migrationflow-to-ts đã archive; khoảng cách tăng theo năm; TS 7.0 xoá lợi thế tốc độ
Codebase Flow cũ quy mô MetaFlow tạm thờiTooling nội bộ, phối hợp React, hiệu năng incremental đã được kiểm chứng
Team đang dùng TypeScriptGiữ nguyênKhông có gì trong Flow đáng để đổi

Cái tên “còn cầm cự” trong tiêu đề bài này phản ánh đúng thực trạng của ecosystem bên ngoài. Flow đang cầm cự hoàn toàn trong nội bộ Meta. Bên ngoài đó, quyết định đã được đưa ra từ nhiều năm trước — tỉ lệ 244:1 về lượng tải về là bảng điểm.

Nếu Go vẫn đang trong danh sách cân nhắc cùng TypeScript cho backend, Go vs TypeScript cho dịch vụ backend phân tích cách các đánh đổi diễn ra trong 2026. Đã chọn TypeScript? TypeScript strictness và tỉ lệ bug thực tế đo lường mức độ strict nào thực sự ảnh hưởng đến chất lượng code.

Lưu ý

Benchmark incremental sử dụng một repo 50.000 dòng trên phần cứng cụ thể. Con số của bạn sẽ khác. Tuyên bố 10× của TypeScript 7.0 dựa trên benchmark Microsoft tự chạy trên test suite của họ; cần xác nhận độc lập. Archive của @khanacademy/flow-to-ts có nghĩa là nó có thể dần lạc hậu so với cú pháp Flow mới — hãy test trên một branch trước khi chạy trên code production.

Link Cursor phía trên (/go/cursor) là affiliate link.

Tài liệu tham khảo