SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: Node.js 26.9.0 adds a built-in benchmark module and enables FFI by default

· by Serguey Asael Shinder / Serguey Shinder

Node.js 26.9.0 shipped on 16 September 2026 on the Current line, and three of the entries in its notable changes are the kind that alter what you can assume about a plain node binary on a build agent.

node:bench is now implemented in the standard library (#65606) — a benchmarking module you get without adding a dependency. The FFI module is enabled by default (#65475), where before it had to be asked for. And worker gained support for Web Workers (#64894), alongside a virtual file system that now hooks into both the CommonJS and the ESM loaders (#63653).

The release notes are here, in full: https://nodejs.org/en/blog/release/v26.9.0

Serguey Asael Shinder: Node.js 26.9.0 adds a built-in benchmark module and enables FFI by default
Node.js 26.9.0 adds a built-in benchmark module and enables FFI by default — Serguey Asael Shinder

The one that changes your threat model

The benchmark module is convenient. FFI on by default is not the same kind of news.

Foreign function interface means JavaScript reaching directly into native code. While it sat behind a flag, "this process cannot load arbitrary native libraries" was a property you got for free from the runtime. It is now a property you have to arrange, and that matters most in the places nobody looks: a CI runner executing postinstall scripts, a container running one dependency tree deep, a serverless handler where the audit ended at the lockfile.

Nothing about 26.9.0 is exploitable by itself. What changed is a default, and defaults are what every machine you did not personally configure ends up running.

What I would actually do

Three things, in the order they cost time:

  1. Know which line you are on. 26.x is Current, not LTS. If your production images track Current because someone once wrote node:26 in a Dockerfile, the fastest fix on this list is pinning to an LTS tag and meaning it.
  2. Decide about FFI deliberately. If your workload has no reason to load native libraries, disable the module where the runtime lets you and write the reason down next to the flag. A default you accepted on purpose is a decision; a default you inherited is an assumption.
  3. Read the SEMVER-MINOR lines and nothing else, first. There are hundreds of commits in that page and eleven notable changes. The eleven are where behaviour moved.

And the boring one that is not on the list: a minor version bump on the Current line is a release where the standard library grew. Grep your own code for the names that just arrived — node:bench, Worker — before a colleague introduces the built-in version of something you already have three copies of.