· pnpm / yarn / package-manager
pnpm vs Yarn — So sánh package manager toàn diện 2026
Đang dùng Yarn Classic? Yarn 4 phức tạp hơn pnpm để chuyển đổi và không có lợi thế hiệu suất đáng kể trong CI. Đây là lý do nên chọn pnpm năm 2026.
Bởi Ethan
1.973 từ · 10 phút đọc
Nếu bạn đang dùng Yarn Classic (v1) và đang cân nhắc bước tiếp theo, hãy chuyển sang pnpm. Nâng cấp lên Yarn Berry phức tạp hơn nhiều so với chuyển sang pnpm, hệ sinh thái PnP vẫn còn nhiều ma sát trong năm 2026, và pnpm cho hiệu suất cài đặt tốt hơn trong kịch bản CI quan trọng nhất. Yarn Berry thắng sạch ở một benchmark, nhưng điều kiện để đạt được kết quả đó hiếm khi xảy ra trong thực tế.
Bài này dành cho ai
Các kỹ sư JavaScript và TypeScript đang dùng Yarn Classic và cần ra quyết định vào năm 2026. Các team đang chọn nền tảng cho monorepo mới cũng sẽ tìm được thông tin hữu ích ở đây. Nếu bạn đã gắn bó hoàn toàn với Yarn PnP và có toolchain tương thích, bài này không thay đổi được quyết định của bạn — và cũng không có ý định đó.
Phiên bản được kiểm thử
| Công cụ | Phiên bản | Phát hành |
|---|---|---|
| pnpm | 11.1.3 | 2026-05-18 |
| Yarn Berry | 4.15.0 | 2026-05-19 |
| Yarn Classic | 1.22.x | EOL |
Yarn Classic không còn được phát triển tích cực. Đây là công cụ bạn đang di chuyển khỏi, không phải điểm đến.
Tốc độ cài đặt
Số liệu benchmark lấy từ pnpm.io/benchmarks, cập nhật ngày 2026-05-18. Đây là số liệu do pnpm tự đo; hãy xem đây là chỉ số định hướng. Bài kiểm thử độc lập từ DEV Community (monorepo thực tế trên Railway CI, 2026) cho kết quả cùng chiều hướng.
| Kịch bản | pnpm 11 | Yarn Berry (node_modules) | Yarn PnP |
|---|---|---|---|
| Cold install (không cache, không lockfile) | 6.9s | 7.9s | 3.4s |
| Cache + lockfile (kịch bản CI phổ biến) | 2.2s | 5.7s | 1.3s |
| Cache + lockfile + node_modules đã có | 471ms | 5.6s | n/a |
Yarn PnP nhanh nhất ở cold install — thực sự như vậy. Nhưng cold install không phải kịch bản chạy trên mỗi PR. Kịch bản quan trọng trên CI là cache + lockfile không có node_modules: pnpm thắng với 2.2s so với 5.7s của Yarn ở chế độ node_modules.
Lợi thế cold install của PnP chỉ có giá trị nếu bạn thực sự chạy với PnP. Nhiều team không làm vậy — chi tiết ở phần dưới.
Kiểm chứng độc lập: Trên monorepo đa package thực tế chạy Railway CI, pnpm 9.15 đạt 41s cold so với 72s của Yarn Berry 4.5, và 9s warm so với 14s warm. (Nguồn: DEV Community, 2026)
Việc cấu hình cache lockfile đúng cách trên nền tảng CI có tác động lớn đến các con số này — GitHub Actions vs GitLab CI phân tích chi tiết cách mỗi nền tảng xử lý dependency caching.
Bản viết lại store của pnpm 11
pnpm 11, phát hành tháng 4 năm 2026, thay thế hàng triệu file JSON từng gói trong content-addressable store bằng một database SQLite duy nhất. Tốc độ cài đặt cải thiện ở mọi kịch bản.
Khả năng tương thích PnP trong năm 2026
Cam kết cốt lõi của Yarn PnP là zero-install artifact và deploy nhanh hơn. Trong thực tế, kết quả phụ thuộc rất nhiều vào toolchain của bạn.
Vẫn bị lỗi hoặc chưa hỗ trợ trong năm 2026:
- React Native và Expo — phải dùng fallback
nodeLinker: node-modules; chưa có kế hoạch sửa - Turbopack (Next.js) — PnP không được hỗ trợ; chế độ Webpack hoạt động được với cấu hình bổ sung (xem Turbopack vs Vite để so sánh build tool rộng hơn)
Hoạt động được, nhưng cần thêm bước cấu hình:
- VS Code cần chạy
yarn dlx @yarnpkg/sdks vscode— một bước thủ công dễ làm bối rối contributor mới - Các package có peer dependency không khai báo sẽ báo lỗi kiểu
"@babel/plugin-transform-react-jsx tried to access @babel/core (a peer dependency) but it isn't provided"— có thể sửa quapackageExtensionstrong.yarnrc.yml, nhưng không tự động - Webpack 5, Vite 5, TypeScript 5.4+, và esbuild hoạt động tốt ngay từ đầu
Cách đánh giá trung thực là “không hỏng, nhưng phức tạp.” Sự phức tạp này tích lũy: các team không đủ nguồn lực xử lý setup PnP sẽ fallback sang nodeLinker: node-modules, lúc đó lợi thế hiệu suất của Yarn Berry so với pnpm biến mất. 471ms so với 5.6s với warm cache không phải khoảng cách nhỏ.
Isolation nghiêm ngặt: mặc định của pnpm, opt-in của Yarn
pnpm lưu trữ package trong content-addressable store và tạo cấu trúc node_modules qua hard link và symlink. Chỉ các package được khai báo trong package.json của bạn mới có thể được import. Những dependency không khai báo nhưng tình cờ được hoisted bởi npm hay Yarn sẽ bị phát hiện ngay lúc cài đặt thay vì ẩn đến tận production.
Điều này bắt được bug thực. Một bài viết về migration năm 2026 từ team Pedalboard monorepo ghi nhận rằng chuyển sang pnpm đã phát lộ “nhiều khai báo dependency cẩu thả mà Yarn’s hoisting đã âm thầm che giấu” — bao gồm @types/react không khai báo và thiếu cả style-loader lẫn css-loader.
Nếu bạn muốn hiểu sâu hơn về isolation model và phantom dependencies của pnpm, pnpm vs npm có giải thích chi tiết.
DX với monorepo
Workspace protocol của pnpm là chuẩn thực tế cho TypeScript monorepo năm 2026. Vue, Vite, Nuxt, và Astro đều chạy trên pnpm-workspace.yaml. Nếu bạn dùng Turborepo, pnpm là con đường được tài liệu hóa — xem hướng dẫn thiết lập pnpm với Turborepo để có ví dụ cụ thể.
Yarn Berry cũng có workspace protocol và nó hoạt động tốt. Điểm khác biệt là hệ thống constraints: Yarn 4 viết lại bằng JavaScript (bỏ hệ Prolog từ v2/v3), giúp dễ tiếp cận hơn cho các team cần quản lý policy phức tạp trong monorepo. Nếu bạn cần kiểm soát nghiêm ngặt dependency graph trên hàng chục package, constraints runner của Yarn Berry đáng để xem xét.
Xung đột lockfile
pnpm-lock.yaml là YAML. Dài và do máy sinh ra, nhưng có cấu trúc có thể đoán trước, giúp merge conflict dễ hiểu hơn. Hầu hết conflict trong monorepo đến từ việc nâng phiên bản package; chúng theo một mẫu nhất định và có thể giải quyết mà không cần chỉnh tay một khi bạn nhận ra mẫu đó.
Lockfile của Yarn Berry (.yarn/cache/ cộng với yarn.lock) gọn hơn ở chế độ PnP vì lưu binary cache artifact. Conflict trong đó đòi hỏi phải hiểu định dạng artifact. Ở chế độ nodeLinker: node-modules, lockfile trông giống của npm hơn.
Không định dạng nào làm merge conflict dễ chịu. Lockfile của pnpm là cái có nhiều công cụ hỗ trợ và pattern giải quyết conflict được ghi chép nhiều hơn.
Bảo mật chuỗi cung ứng
pnpm 11 tích hợp minimumReleaseAge mặc định là 1.440 phút (24 giờ). Các phiên bản mới sẽ không được resolve tự động cho đến khi đã công khai được một ngày, thu hẹp cơ hội một phiên bản độc hại xâm nhập CI trước khi bị phát hiện.
Yarn 4.10 thêm npmMinimalAgeGate với mục đích tương tự. Cả hai công cụ đã hội tụ về điểm này — đây không còn là điểm phân biệt, nhưng đáng biết là cả hai đều bật tính năng này ngay từ đầu.
So sánh lộ trình migration
Yarn Classic → pnpm:
- Xóa
node_modulesvàyarn.lock - Chạy
corepack enablevàcorepack use pnpm@11 - Chạy
pnpm install— sẽ đọc từpackage.jsondependencies như cũ - Sửa các phantom dependency được phát lộ (isolation nghiêm ngặt của pnpm làm chúng hiện ra)
- Cập nhật CI để dùng
pnpm install --frozen-lockfile
CKEditor đã migration cấu trúc multi-repo với ~2.000 dependency theo cách này vào tháng 1 năm 2026. Cold CI install giảm từ 80s xuống 16s. Họ cần một pnpm-hooks.cjs tùy chỉnh để link package giữa các repo tùy chọn, nhưng việc migration cốt lõi chỉ mất một ngày. (Nguồn: Blog CKEditor)
Yarn Classic → Yarn Berry:
- Nâng cấp lên Yarn 4 qua
corepack use yarn@4 - Di chuyển
.yarnrc.yml— các cài đặt.npmrccủa v1 không tự chuyển theo - Chọn
nodeLinker:pnp,pnpify, hoặcnode-modules - Nếu dùng PnP: chạy
yarn dlx @yarnpkg/sdksđể cấu hình tích hợp editor, kiểm tra từng công cụ trong chuỗi về khả năng tương thích PnP, thêm các entrypackageExtensionscho package có peer dependency bị lỗi - Cập nhật CI — chế độ zero-installs yêu cầu commit cache artifact, thay đổi kích thước repo và cách quản lý branch
Team của Tom Vaidyan đã đánh giá cả hai hướng vào tháng 4 năm 2026 và chọn pnpm vì Yarn 4 “về cơ bản là một sản phẩm khác chứ không phải bản cập nhật từng bước từ Yarn 1.x.” (Nguồn: tvaidyan.com) Nhận định đó đúng: bề mặt cấu hình của Berry sâu hơn pnpm nhiều, và bạn phải trả chi phí đó ngay trong giai đoạn migration.
Kết luận
Chọn pnpm nếu:
- Bạn đang dùng Yarn Classic và cần chọn hướng đi tiếp — migration nhẹ hơn và bảo trì về lâu dài cũng đơn giản hơn
- Bạn chạy monorepo với Turborepo — pnpm là mặc định được tài liệu hóa, và cộng đồng công cụ cũng giả định vậy
- Bạn dùng Next.js với Turbopack — Yarn PnP không được hỗ trợ
- Bạn muốn isolation dependency nghiêm ngặt mà không cần kiểm tra khả năng tương thích PnP
- Team bạn muốn quy trình onboard ngắn gọn cho contributor mới
Chọn Yarn Berry nếu:
- Bạn đã có toolchain tương thích hoàn toàn với PnP và đang dùng zero-installs CI — cold install 3.4s là thật, và ở quy mô CI đủ lớn, nó tích lũy thành khoản tiết kiệm đáng kể
- Bạn cần hệ thống constraints lập trình được để quản lý policy monorepo (của Yarn là lựa chọn mạnh hơn)
- Bạn hoạt động ở quy mô mà chi phí bảo trì PnP được bù đắp bởi tiết kiệm hạ tầng
Ở lại Yarn Classic chỉ khi:
- Codebase ổn định và team không có bandwidth để migration ngay lúc này
- Xem đây là trạng thái tạm thời trong khi lên kế hoạch chuyển sang pnpm, không phải điểm dừng
Lưu ý
Số liệu benchmark từ pnpm.io là do pnpm tự đo. Bài trên DEV Community dùng phiên bản pnpm cũ hơn (9.15) so với Yarn 4.5 — khoảng cách có thể lớn hơn với pnpm 11. Chất lượng trải nghiệm migration khác nhau tùy codebase; các trường hợp CKEditor và Tom Vaidyan mang tính tham khảo, không phải phổ quát.
Isolation nghiêm ngặt của pnpm đôi khi phát lộ tooling giả định hoisting. Escape hatch shamefully-hoist=true có đó, nhưng dùng nó là bỏ đi đảm bảo isolation — hãy kiểm tra phantom deps thay vì tắt tính năng.
Bài này không có affiliate link.
Tài liệu tham khảo
- pnpm 11.0 release — SQLite store, pnpm ci, ESM, Node 22+
- pnpm benchmarks — cập nhật 2026-05-18
- Yarn Berry changelog — 4.15.0;
npmMinimalAgeGateđược thêm vào trong 4.10.0 - CKEditor migration sang pnpm (tháng 1 năm 2026) — 80s → 16s CI
- DEV Community: pnpm vs npm vs Yarn năm 2026 — benchmark monorepo độc lập
- Tom Vaidyan: tại sao chúng tôi chuyển sang pnpm (tháng 4 năm 2026) — ghi chép quyết định của team
- Matti Bar-Zeev: migration monorepo từ Yarn sang pnpm (DEV Community) — phát lộ phantom dependency
- Turbopack PnP support (Next.js tracking issue) — PnP không được hỗ trợ