Skip to content

Build1 publisher2 min readPublished

Stability labels decide which npm packages Node's built-ins can replace in production

Flavio Copes matched twelve Node.js built-ins to the npm packages they replace and graded each one by its stability in the current LTS line. Node 22 still labels its SQLite driver experimental, so a server on that line can see the API change in a minor release.

The Engineer · Build desk

Drafted by a language model from the sources cited here and checked against its claim ledger before publication. How we use AISend a correction

Illustration accompanying Stability labels decide which npm packages Node's built-ins can replace in production
Generated illustration

What happened

  • Copes checked each claim against the Node 24.21.0 API docs, the Active LTS line as of September 2026, and ran every example on Node 26.0.0.
  • Node 20 reached end of life on April 30, 2026, Node 22 stays in maintenance until April 2027, and Node 26 becomes the next LTS on October 28, 2026.
  • The built-in test runner's coverage and module mocking still sit behind experimental flags, while function mocks and spies through t.mock.fn() are stable.
  • Global fetch is built on the undici HTTP/1.1 client and ships Request, Response, Headers and FormData as globals alongside it.

Compiled by The EngineerSomething wrong?How this is made

Why it matters

  • decision With node:test stable on every supported Node line, whether a given suite can drop Jest comes down to whether it needs coverage or whole-module mocks.
  • exposure Node 22 servers that adopted node:sqlite depend on an API that can change in any minor release, on a line that stays in maintenance until April 2027.
  • cost Leaving better-sqlite3 means writing BEGIN, COMMIT and ROLLBACK by hand in try/catch wherever code relied on its db.transaction(fn) helper.

Node grades each API on a stability scale, and the grade is published in the docs [4]. Stability 2 means stable. Stability 1 means experimental, with 1.0 for early development, 1.1 for active development and 1.2 for a release candidate [4]. "Anything experimental can change or disappear in a minor release, so the number matters if you're putting it in production," Copes wrote [5].

On Node 22, the --experimental-sqlite flag was removed in 22.13, but node:sqlite kept its 1.1 label [9]. Removing the flag also removed the only opt-in step, so code can import the module without ever marking it as experimental [2]. The docs describe that level as "nearing minimum viability" [9].

The SQLite swap takes a native build out of every install [6]. The better-sqlite3 package is a native addon that gets compiled, or fetched as a prebuilt binary, on each install [6]. node:sqlite arrived in Node 22.5 and is synchronous like the package it replaces, so query code keeps its top-to-bottom shape with no await [6]. One porting trap is small. The module exists only under the node: prefix, and a plain import 'sqlite' fails [7].

The test runner has been Stability 2 since Node 20.0.0, and node --test finds files named like math.test.js with no configuration [11]. Copes wrote a post on Jest in 2018 and now runs every test script on his own site through node --test [14]. He draws the line at one feature. "If your suite leans on mocking whole modules, keep Jest for now," he wrote [13].

Copes's list also names dotenv, nodemon and uuid among the packages Node now covers [1]. The entries cited here do not include their stability levels, so for those three the replacement claim rests on his list alone.

I think adoption should follow the labels. A plain unit-test suite can move to node:test on any supported line [1]. A production SQLite path belongs on Node 24.15.0 or later, where node:sqlite is a 1.2 release candidate and prints no warning [8].

What to watch

  • Whether a later Node 24 or 26 release promotes node:sqlite from a 1.2 release candidate to Stability 2.
  • Whether test coverage and mock.module() reach stable status, the remaining reason Copes gives for keeping Jest.
  • The Node 26 API docs at the October 28 LTS promotion, for stability labels that differ from the Node 24 line.
Loading claim ledger
Loading source directory links
Loading share composer
Loading topic controls
Loading related stories