What Is New in Node.js 0.10?
| Category | Change |
|---|---|
| New Features | Streams2 -- new stream interface with proper backpressure |
| New Features | setImmediate() -- post-I/O, pre-setTimeout scheduling |
| New Features | domains -- error isolation for async operations |
| Improvements | process.nextTick() semantics fixed -- now truly runs before I/O |
| Improvements | TLS: upgraded to newer OpenSSL, significant throughput improvement |
| Improvements | fs.ReadStream and fs.WriteStream throughput improved |
| Improvements | Idle GC removed -- more stable latency |
| Improvements | Jenkins CI added for all supported operating systems |
Streams2 -- The Foundation of Modern Node.js Streaming
Node.js 0.10 introduces Streams2 -- a complete rework of the stream API that adds proper backpressure, a read() method for pull-based consumption, and consistent base classes for Readable, Writable, Duplex, and Transform streams.
Prior to Streams2, data events fired immediately and aggressively -- there was no way to slow down a readable stream without losing data. The pause() method was advisory at best. Streams2 fixes this by introducing a buffer and a read(n) API that lets consumers control the rate of data flow.
// Streams2 pipe with automatic backpressure
const readable = fs.createReadStream('./large-file.csv');
const writable = fs.createWriteStream('./output.csv');
readable.pipe(writable); // backpressure handled automatically
The readable-stream npm package was published alongside 0.10, allowing application code using Streams2 to run on older Node.js versions -- an early example of the "develop in core, publish to npm" approach.
process.nextTick() and setImmediate() -- Execution Order Clarity
Node.js 0.10 fixes process.nextTick() to reliably run callbacks before any I/O events -- not just "usually before I/O" as in prior versions. Callbacks scheduled with nextTick run to exhaustion before the event loop processes any I/O.
setImmediate() is added as a companion: it runs after I/O events and before setTimeout(fn, 0). The phase order is: nextTick queue -> I/O callbacks -> setImmediate -> setTimeout(0). Understanding this ordering is fundamental to writing correct async Node.js code.
// Use setImmediate for yielding within a long computation
function processLargeArray(arr, index) {
if (index >= arr.length) return;
process(arr[index]);
setImmediate(() => processLargeArray(arr, index + 1));
// yields to I/O between each item
}
Domains -- Grouping Async Error Handling
The domain module in Node.js 0.10 lets you group multiple async operations into a single error boundary. An error in any async operation within the domain routes to the domain's error handler instead of bubbling up to process.uncaughtException.
import domain from 'node:domain';
const d = domain.create();
d.on('error', (err) => {
console.error('Caught by domain:', err.message);
res.statusCode = 500;
res.end('Server error');
});
d.run(() => {
// async operations here are covered by the domain error handler
db.query('SELECT 1', (err, result) => { /* errors caught by d */ });
});
Domains were later deprecated (Node.js 4+) as async tracking mechanisms like AsyncLocalStorage provided better solutions. But at the time, domains were the only way to catch errors across async boundaries.
TLS Performance Leap
Node.js 0.10 upgrades to a newer OpenSSL and rewrites CryptoStream to use the Streams2 interface. TLS throughput improves dramatically in benchmarks. HTTP throughput also improves for most workloads. The fs.ReadStream and fs.WriteStream improvements mean file serving gets faster as well.
FAQ
What was wrong with streams before Streams2?
The original stream API had no true backpressure mechanism. A fast readable piped to a slow writable would buffer indefinitely in memory until the process crashed. Streams2 adds a high-water mark and pauses reading when the writable buffer is full.
Can old-style streams (v1) run alongside Streams2?
Yes. Node.js 0.10 wraps old-style streams in a compatibility layer so they behave as Streams2 when piped. The readable-stream npm package also provides a forward-compatible shim.
When should I use nextTick vs setImmediate?
Use process.nextTick() when you need to defer a callback until the current synchronous operation completes but before any I/O. Use setImmediate() when you want to yield to pending I/O before continuing. Avoid recursive nextTick() loops -- they starve I/O.
Are domains still usable in modern Node.js?
Technically yes, but they have been deprecated since Node.js 4. Use AsyncLocalStorage (stable in Node.js 16) for request-scoped context and process.on('unhandledRejection') plus promise .catch() for error handling.
Is Node.js 0.10 the first "production-ready" Node.js version?
Many practitioners consider 0.10 the first version truly suitable for high-traffic production services, due to Streams2 backpressure, the fixed nextTick semantics, and the improved TLS performance. Earlier versions (0.8 and below) were used in production but required more careful memory management.