Node.js 26.5.0 đã có sẵn. Đây là bản phát hành Current, không phải nhánh LTS, vì vậy nó nằm ở ranh giới tiên phong của những gì nền tảng này có thể thực hiện. Sự khác biệt đó rất quan trọng. Bạn không nên thay thế nó một cách mù quáng vào một hệ thống production vốn đòi hỏi sự ổn định trong mười tám tháng. Nhưng chính những bản phát hành nhỏ và nhanh chóng này là nơi bạn chứng kiến tương lai dần hình thành. Chúng cho thấy những API nào đang được các nhà duy trì tinh chỉnh và runtime sẽ hướng tới đâu tiếp theo. Trong phiên bản 26.5.0, công việc trọng tâm nằm ở Web Streams API, với một cặp bản sửa lỗi mục tiêu giúp đưa Node tiến gần hơn đến sự tương đồng với trình duyệt. Bản phát hành này cũng xử lý triệt để hai vấn đề còn tồn đọng trong các lớp xử lý hệ thống tệp (file system) và URL.
Web Streams đang làm gì trong Node.js?
Nếu bạn đã viết mã streaming trong Node được một thời gian, bạn sẽ biết module stream tích hợp sẵn có cá tính riêng của nó. Readable, Writable, Transform, và Duplex đã là những "ngựa thồ" của hệ sinh thái này trong nhiều năm. Chúng mạnh mẽ, nhưng không giống với các stream mà bạn gặp trong trình duyệt. Khi bạn cố gắng chia sẻ logic giữa một front-end service worker và một back-end route handler, khoảng cách đó sẽ tạo ra sự xung đột. Kết quả là bạn phải viết lại các adapter, sao chép dữ liệu sang các định dạng không quen thuộc, hoặc đơn giản là tránh sử dụng mã dùng chung hoàn toàn.
Web Streams API tồn tại để lấp đầy khoảng cách đó. Nó là cùng một tiêu chuẩn hỗ trợ việc xử lý body của fetch trong trình duyệt. Bằng cách đưa nó vào Node, dự án cho phép bạn viết logic streaming một lần và chạy được ở cả hai môi trường. API này làm việc với các đối tượng ReadableStream, WritableStream, và TransformStream giúp truyền các chunk thông qua một giao diện thống nhất. Phiên bản 26.5.0 không viết lại giao diện đó, nhưng nó siết chặt hai "con ốc" quan trọng.
Sửa lỗi releaseLock và dọn dẹp các BYOB Readers
Một thay đổi cụ thể trong bản phát hành này là bản sửa lỗi cho phương thức releaseLock trên WritableStreamDefaultWriter. Trong mô hình Web Streams, một writer lock ngăn chặn nhiều consumer cùng tác động lên một stream cùng một lúc. Khi bạn gọi releaseLock(), bạn đang báo hiệu rằng writer của mình đã hoàn tất và stream bên dưới đã sẵn sàng cho hoạt động tiếp theo. Một triển khai lỗi ở đây có thể khiến stream rơi vào trạng thái lấp lửng, vẫn tin rằng nó đang bị chiếm hữu ngay cả khi writer đã biến mất. Trong một máy chủ bận rộn đang phân tích các bản upload hoặc chuyển tiếp dữ liệu đến bộ lưu trữ, loại lock cũ đó có thể làm đình trệ một pipeline hoặc gây ra các lỗi khó truy vết nguồn gốc. Bản sửa lỗi trong 26.5.0 giúp việc bàn giao trở nên có thể dự đoán được một lần nữa.
Thay đổi thứ hai của Web Streams là cải thiện cách ReadableStream và TransformStream hoạt động với các BYOB reader. BYOB viết tắt của Bring Your Own Buffer. Thay vì stream cấp phát một khối bộ nhớ mới mỗi khi nó truyền dữ liệu, bạn đưa cho nó một buffer mà bạn đã chuẩn bị sẵn. Stream sẽ lấp đầy buffer đó, bạn xử lý các byte, và sau đó bạn đưa chính buffer đó trở lại để tái sử dụng. Đó là một sự khác biệt nhỏ về mặt cơ chế nhưng mang lại kết quả vượt trội khi bạn đang di chuyển khối lượng dữ liệu lớn.
Node đã hỗ trợ BYOB được một thời gian, nhưng các trường hợp biên trong ReadableStream và TransformStream có thể hoạt động sai khi một BYOB reader được gắn vào. Chi tiết cụ thể của bản sửa lỗi ít quan trọng hơn kết quả thực tế: các stream sử dụng buffer tường minh giờ đây đáng tin cậy hơn trong cả giai đoạn đọc và chuyển đổi. Nếu bạn từng tránh sử dụng BYOB reader vì các lỗi kỳ lạ trong các sự kiện backpressure, bản phát hành này đã loại bỏ thêm một lý do để tránh xa chúng.
BYOB thực sự xuất hiện ở đâu
Thật dễ dàng khi nói về việc tái sử dụng buffer một cách trừu tượng. Sẽ hữu ích hơn nếu nghĩ về nơi mà nó thực sự quan trọng.
Hãy tưởng tượng bạn đang viết một dịch vụ chấp nhận các bản upload telemetry. Những bản upload đó có thể là các log đã nén hoặc dữ liệu thô từ cảm biến, mỗi bản nặng vài trăm megabyte. Nếu stream cấp phát một Node Buffer mới cho mỗi phần dữ liệu, bộ thu gom rác (garbage collector) sẽ phải làm việc quá tải và mức tăng vọt bộ nhớ sẽ tăng nhanh. Với một BYOB reader, bạn cấp phát một nhóm buffer khi khởi động. Stream lấp đầy chúng, trình phân tích của bạn rút hết dữ liệu từ chúng, và chúng quay trở lại vòng lặp. Bộ nhớ luôn ở mức ổn định. Mô hình tương tự cũng áp dụng khi bạn đang proxy lưu lượng mạng giữa hai socket hoặc phân tích các tệp CSV lớn theo từng dòng mà không cần tải toàn bộ vào RAM.
Transform streams are equally important here. A TransformStream sits in the middle of a pipeline, perhaps decompressing a gzip stream or encrypting chunks on the fly. If the transform step mishandles BYOB buffers, you can see corrupted output, dropped chunks, or stalls under load. The 26.5.0 fixes address exactly those kinds of pipeline hiccups, which is why anyone running high-throughput I/O should pay attention.
The Quiet Wins: File System and Error Clarity
Not everything in 26.5.0 is about streaming. The release also fixes behavior in fs.rm and fs.rmSync when the recursive option is set to false. Previously, passing recursive: false alongside a directory path could produce unexpected results during cleanup. The method might act in ways that did not match the explicit intent of the caller, deleting more than expected or failing in inconsistent ways depending on the platform. Cleaning up files is the sort of operation that should be boring and predictable. Boring is good. This fix restores that predictability, so your temporary directory cleanup scripts or deployment teardown logic behave exactly as the code suggests.
There is also a quality-of-life improvement in how URL.canParse reports failure. The method checks whether a string is a valid URL without throwing on malformed input. In 26.5.0, it now carries better Error.cause information when something goes wrong. Rather than swallowing the original reason, the error object preserves a causal chain. That means when a URL parse fails deep inside a validation helper, the stack you log tells you whether the issue was a bad protocol, a missing hostname, or some other structural problem. You spend less time sprinkling manual debug logs across every call site.
Should You Upgrade?
The answer depends on what you are running.
If your production workloads sit on an LTS version such as the v20.x line, stay there. These fixes will eventually backport or arrive in the next active LTS. Stability and predictable support timelines outweigh the benefit of a slightly smoother stream lock or clearer URL error on a server that is already working.
If you are building a new service, prototyping a real-time data pipeline, or actively using the Web Streams API for performance-critical I/O, 26.5.0 is worth the jump. The incremental alignment between Node streams and browser Web Streams is not just a compatibility win. It is a bet on a more unified JavaScript runtime where the same data-pushing logic can travel between server and client without translation layers. That cuts down on cognitive load and reduces the surface area for bugs when your team ships code to both environments.
This release is small, but the direction is clear. Node is continuing to invest in standards-based APIs that work everywhere JavaScript runs. The Web Streams improvements are not headline features, but they smooth out a path that has been rocky for years. Grab 26.5.0 if you live on the Current line, and watch for these fixes to land in your LTS world when the time is right.
Source: Dev.to – Node.js 26.5.0: What's New for Web Streams and Error Handling
Join the discussion and keep learning with the GyaanSetu community on Telegram.
