From a frustrated developer's insight about blocking I/O to the runtime that powers the modern web. 15 years of revolution.
In 2009, Ryan Dahl was frustrated. He was watching a file upload progress bar on Flickr and realized the browser had no way to know how much of the file had been uploaded — because web servers like Apache used blocking I/O. Each connection consumed a thread, and threads were expensive. The server couldn't push real-time progress updates.
Dahl had been experimenting with event-driven, non-blocking I/O servers in C, Lua, and Haskell. But none of these languages had the right combination of a fast VM, no existing I/O libraries (that would be blocking), and a massive developer base. Then he realized: JavaScript had all three. V8 was blazing fast, JavaScript had no server-side I/O conventions to break, and millions of web developers already knew the language.
He built a prototype in just a few weeks: a C++ wrapper around Google's V8 engine, with a custom event loop based on libev (later libuv), and non-blocking bindings for file I/O, networking, and DNS. He called it Node.
package.json convention make sharing and reusing code trivially easy. This single tool would become the world's largest software registry.node_modules. It's both a critique and a spiritual successor.--watch mode, single executable applications, built-in .env file support, and experimental TypeScript stripping. Node.js 22 becomes the current LTS with stable WebSocket client support.The io.js fork of 2014 was one of the most dramatic events in open-source JavaScript history. The core issue was governance: Joyent controlled the project, releases were slow, and V8 updates lagged months behind Chrome. Contributors felt locked out of decision-making.
io.js adopted an open governance model with a Technical Committee (TC) where decisions were made by consensus among active contributors, not by a corporate sponsor. It shipped weekly releases, updated V8 aggressively, and added ES6 features (arrow functions, generators, template literals) months before Node.js did.
The reunification in September 2015 was a victory for the community. Node.js adopted io.js's governance, its codebase, and its release cadence. The result was a project that was both enterprise-stable (via LTS releases) and community-driven (via open governance). The fork, while painful, ultimately made Node.js stronger.
| Version | Codename | Release Date | Status | Key Additions |
|---|---|---|---|---|
| v0.1 | — | 2009 | Historical | Initial release, event loop, HTTP server |
| v4.0 | Argon | Sep 2015 | End of Life | First merged io.js + Node.js release, ES6 support |
| v6.0 | Boron | Apr 2016 | End of Life | 93% ES6 coverage, inspector protocol |
| v8.0 | Carbon | May 2017 | End of Life | async/await, N-API, npm 5 |
| v10.0 | Dubnium | Apr 2018 | End of Life | fs.promises, HTTP/2 stable, Worker Threads experimental |
| v12.0 | Erbium | Apr 2019 | End of Life | Worker Threads stable, ES modules, V8 7.4 |
| v14.0 | Fermium | Apr 2020 | End of Life | Diagnostic reports, optional chaining, nullish coalescing |
| v16.0 | Gallium | Apr 2021 | End of Life | Timers Promises API, Web Crypto API, Apple Silicon builds |
| v18.0 | Hydrogen | Apr 2022 | Maintenance | fetch API, test runner, watch mode, Web Streams |
| v20.0 | Iron | Apr 2023 | LTS Active | Permission model, stable test runner, V8 11.3 |
| v22.0 | Jod | Apr 2024 | LTS Active | WebSocket client, require(esm), glob/globSync, V8 12.4 |
Even-numbered releases become LTS (Long-Term Support) with 30 months of maintenance. Odd-numbered releases are short-lived "Current" releases for early adopters.