NEWS

Node.js 26 brings debounce, throttle, and PKCS#12 parsing to the core

Node.js version 26.10.0 put debounce, throttle, and a PKCS#12 certificate parser directly into the core, and LTS 26 Lithium is already in active support until April 2029.

Node.js 26 brings debounce, throttle, and PKCS#12 parsing to the core
Image: Redação iMasters
News
Reading
4 min
Code
2

Node.js version 26.10.0 put debounce, throttle, and a PKCS#12 certificate parser directly into the core, and LTS 26 Lithium is already in active support until April 2029.

Node.js 26.10.0 incorporated into the core a group of utilities that, until then, only existed as third-party dependencies. node:util gained debounce() and throttle(), node:crypto began exposing parsePKCS12() to read .p12 and .pfx certificates, and the experimental virtual file system (VFS) was extended to node:ffi. The release is part of the sequence of Current-line releases that preceded Node.js 26's entry into Active LTS, under the codename "Lithium".

These are small changes in terms of lines of code, but they directly address one of the most common habits in the JavaScript ecosystem: vendoring third-party utilities for trivial tasks. Rate limiting and certificate parsing have been on that list for years.

Debounce and throttle without lodash

util.debounce() and util.throttle() were implemented by James M Snell in a single pull request. According to InfoQ's reporting, Matteo Collina commented that he uses these utilities in practically every app he writes:

essentially every app

Matteo Collina

Until now, covering this use case meant installing all of lodash just to use _.debounce, or adding the throttle-debounce package as a direct dependency. With the new functions in the core, that vendor dependency comes out of package.json:

js
const { debounce } = require('node:util');

const salvarRascunho = debounce(() => persistirEstado(), 300, { leading: true });

The implementation wasn't straightforward. Contributors ljharb and bakkot pointed out a design problem: an AbortSignal only transitions to the aborted state once, which is unsuitable for a function meant to be called repeatedly throughout an application's lifetime. Snell reworked the signal to cancel all future invocations and added the leading option, which allows the first call to fire immediately instead of waiting for the end of the interval.

The same patch also brought util.markPromiseAsHandled(), an explicit mechanism for framework authors to signal to the runtime that a promise has already been handled. The function addresses a recurring source of confusion around unhandled rejection warnings, which today often trigger false positives when the framework handles the error through a path that V8 doesn't see.

parsePKCS12() closes a long-standing gap

Node.js already knew how to read .p12 and .pfx bundles internally, used in the pfx option of the TLS module, but it never exposed that result to the user's JavaScript code. The new crypto.parsePKCS12() changes that: it wraps OpenSSL's d2i_PKCS12_bio() and PKCS12_parse() functions and returns an object with the privateKey, certificate, and additionalCertificates fields.

js
const { parsePKCS12 } = require('node:crypto');
const fs = require('node:fs');

const { privateKey, certificate, additionalCertificates } = parsePKCS12(
  fs.readFileSync('certificado.p12')
);

The contribution was Brian Muenzenmeyer's first significant participation touching the core's C++ code, refined with help from Filip Skokan. In practice, it eliminates two common routes for this problem: calling the openssl binary via child_process or depending on packages like node-forge just to extract the private key and certificate from a .pfx file.

For those working with integrations that require a digital certificate in Brazil, this is more relevant than it first appears. e-CNPJ and e-CPF certificates (Brazil's digital certificates for companies and individuals, respectively), used in NF-e (Brazil's electronic invoice system), eSocial (Brazil's government payroll and labor reporting system), and in various integrations with public agencies, are typically distributed precisely in .pfx format. Removing the dependency on an OpenSSL binary installed in the environment or on a third-party JS library simplifies the deployment of these services in containers and serverless functions.

VFS comes to node:ffi

Node.js's experimental virtual file system also gained ground. Matteo Collina and Philipp Dunkel extended node:ffi to load native libraries directly from a mounted VFS, reusing the same self-cleaning anonymous memfd trick that native addons already use on Linux. The same patch fixed a bug in which dlopen forwarded an undefined flags argument, which silently broke addon loading from the real file system.

It's a niche feature today, but it points to where Node.js's VFS is headed: not just data files, but also compiled libraries, bundled with the application without touching the host's disk.

The pattern behind the changes

InfoQ notes that this set of additions follows a visible trend in Node.js over recent cycles: reducing dependence on userland utilities, in contrast with Bun and Deno, which have historically shipped a richer standard library by default. The side effect is relevant for software supply chains: every function that migrates to the core is one less dependency in a typical node_modules tree, and therefore one less surface for supply-chain attacks via compromised npm packages.

For Brazilian teams running Node.js in production, this translates into less auditing of transitive dependencies and fewer packages to update after a CVE in something as simple as a debounce. It's not a standalone reason to migrate, but it is one more reason to keep the runtime up to date.

Where this fits in the support timeline

The changes arrived first in the Current line, but development didn't stop there: version v26.11.0 already brought additional Buffer and http module utilities. Node.js 26 is now in Active LTS under the codename "Lithium", with support guaranteed until April 2029. Installers for all major platforms are available at nodejs.org/en/download.

For those maintaining long-running services, the combination of a newly active LTS with this batch of native utilities is a good moment to review package.json for dependencies that the runtime itself now covers.

Translated from the Brazilian Portuguese original · Read the original