What Node.js Gained Since React Launched
Node.js gained a genuinely different kind of capability since React launched, not new language syntax, not new browser APIs, but runtime-level security, testing, and distribution tools that used to require an external package. A permission model, a built-in test runner, native TypeScript execution, and single-binary packaging are all now part of Node itself, no dependency required. Two newer runtimes, Deno (2018) and Bun (2021), shipped several of these ideas first, and that context is worth knowing, both for understanding the timing and for where all three actually stand today. The result stands on its own either way: a Node application in 2026 can reach for real security controls, real testing, and real TypeScript execution without a single external dependency.
Rundown
- Built-in
fetchshipped experimentally in Node 17.5 (February 2022) and became stable, enabled by default, in Node 18 (April 2022). - A built-in test runner arrived in that same Node 18 release, reaching stable status in Node 20 (April 2023); its
--watchmode specifically stayed experimental longer, only reaching stable in the later Node 20.13.0. node:sqlite, a built-in SQLite module needing zero npm installs or native compilation, shipped experimentally in Node 22.5.0 (2024) and reached release candidate status by Node 25.7.0.- Native TypeScript execution (
node file.ts, no build step) went from an opt-in flag in Node 22.6 (August 2024) to enabled by default in Node 23.6 (January 2025) to fully Stable in Node 24.12.0 and 25.2.0 (November 2025). It strips type annotations only, it doesn’t type-check, and it doesn’t support TypeScript-only syntax likeenumornamespacewithout an additional flag. - The permission model, letting a script’s filesystem, network, and worker-thread access be restricted, shipped experimentally in Node 20 (2023) and reached stable status in Node 23.5.0 (December 19, 2024), fourteen years after Node’s first release with no equivalent at all.
- Single Executable Applications, packaging a Node app into one native binary that runs without Node installed, got its first built-in support in Node 19.7.0, reached Stable in Node 22 (April 2024), and had its build workflow simplified into a single
--build-seaflag in Node 25.5 (January 2026), Node’s direct answer to Bun’s competing--compileflag.
The timeline, at a glance
| Capability | Version | Status |
|---|---|---|
Built-in fetch | Node 17.5 → 18 | Experimental (Feb 2022) → Stable, default (April 2022) |
| Built-in test runner | Node 18 → 20 | Introduced (2022) → Stable (April 2023) |
Test runner --watch mode | Node 20.13.0 | Stable |
node:sqlite | Node 22.5.0 → 25.7.0 | Experimental (2024) → Release candidate |
| Native TypeScript (type stripping) | Node 22.6 → 23.6 → 24.12.0 / 25.2.0 | Opt-in flag (Aug 2024) → Default (Jan 2025) → Stable (Nov 2025) |
| Single Executable Applications | Node 19.7.0 → 22 → 25.5 | Initial support → Stable (April 2024) → One-step --build-sea(Jan 2026) |
| Permission model | Node 20 → 23.5.0 | Experimental (2023) → Stable (Dec 19, 2024) |
Building the permission model
Node’s permission model, letting a script’s filesystem, network, and worker-thread access be restricted, reached stable status in Node 23.5.0, released December 19, 2024. A Node application can now scope exactly what a script and its dependencies are allowed to touch, denying anything outside that scope by default once the flag is turned on. That’s a genuinely new capability, not an incremental improvement to an existing one: for most of Node’s history, from the 2009 v0.1.0 release through the entire 2010s, every script ran with unrestricted filesystem, network, and process access, with no runtime-level control over any of it. Deno, launched in 2018, built its own default around denying access unless explicitly granted, and Node’s model, arriving later, gives Node applications a comparable level of control today. One real difference remains: Node’s model is opt-in rather than the default, so it protects an application only if a team deliberately turns it on.
Native TypeScript, without a type checker
Running a .ts file directly with node file.ts, no ts-node, no tsx, no separate build step, moved from an experimental flag to fully stable status in about fifteen months: --experimental-strip-types landed in Node 22.6 (August 2024), became the default behavior in Node 23.6 (January 2025), and was promoted to Stable in Node 24.12.0 and 25.2.0 (November 2025). The mechanism is exactly what the name says: type annotations are stripped and replaced with whitespace before execution, nothing is type-checked, and syntax that requires actual transformation rather than simple removal, enum, namespace, and similar TypeScript-only constructs, isn’t supported without a separate --experimental-transform-types flag. tsc still has a job; this replaces the need for a separate transpile step during ordinary development and script execution, not the type checker itself.
Shipping a binary, not a folder
For most of Node’s history, distributing an application meant shipping a folder: source files, a node_modules tree, and an assumption that the target machine already has the right Node version installed. Single Executable Applications close that gap, packaging a Node app into one native binary that runs on a machine with no Node installation at all. The feature’s initial built-in support landed in Node 19.7.0, stayed experimental through Node 20 and 21, and reached Stable in Node 22 in April 2024. The workflow itself kept improving after that: Node 24 added better code cache support, and Node 25.5, shipped January 26, 2026, collapsed what used to be a multi-step process, generating a preparation blob, then injecting it into a copy of the Node binary with a separate tool, into a single --build-sea flag.
The Deno and Bun context
Several of these capabilities, the permission model, the test runner, native TypeScript execution, arrived in Node after Deno had already offered something comparable from its own first release, and after Bun, founded by Jarred Sumner in 2021 and built for raw speed with TypeScript support native from day one, added further pressure specifically on startup time, developer experience, and, with its own --compile flag, single-binary distribution. That context is useful for understanding the timing; it doesn’t diminish what Node now has, real, stable, first-party tooling that simply didn’t exist five years ago. Bun’s own trajectory shifted in December 2025, when Anthropic acquired it, tying its future development more directly to AI-assisted coding tooling than to head-to-head runtime competition alone.
Where the runtimes stand now
Node remains the default for most production JavaScript backends, and that’s unlikely to change soon, it has the largest ecosystem, the longest production track record, and, as covered above, real first-party tooling for testing, TypeScript, packaging, and security that didn’t exist five years ago. Deno’s core differentiator hasn’t moved: every script still starts with zero permissions unless explicitly granted, the opposite of Node’s opt-in model, and Deno 2.x added native npm package support, closing what had been its biggest practical adoption barrier. Bun’s pitch remains speed and integrated tooling, a single binary combining a runtime, package manager, bundler, and test runner, and its Node compatibility has improved substantially since its 1.0 launch in 2023. Exact compatibility figures vary widely by source, from the low 90s to figures approaching full parity, so a specific percentage isn’t worth repeating here; the more reliable takeaway is that the gap has narrowed a great deal and keeps narrowing.
None of the three has settled the question for good, and Bun’s own security posture still remains closer to pre-2024 Node than to Deno’s default-deny approach. For a team choosing today, the honest answer depends on what’s being optimized for: ecosystem stability and first-party tooling favor Node, security-by-default favors Deno, and raw performance plus integrated tooling favor Bun. That’s a genuinely different, more competitive landscape than existed in 2013, and Node’s own response to it is exactly what this piece has covered.
Related reading
Everything vanilla JavaScript has gained since React launched and what the browser platform gained over the same window cover the language and platform sides of this same story; this piece covers the third track, the server-side runtime, which moved on its own schedule, shaped less by a standards process and more by direct competition from Deno and Bun.