Skip to content

(don't yet) introduce engines field to package.json #3269

@boneskull

Description

@boneskull

What is the Problem Being Solved?

There is no explicit declaration of what engines (specifically, node) any given package is expected to support (except for promise-kit, eslint-plugin, and import-bundle). The root workspace claims support for Node.js v16+, which is most assuredly a lie.

We have dropped any version of Node.js older than 22.x from our build matrix, so we implicitly only support Node.js v22.x and newer. More precisely—as of this writing—implicit support is for Node.js v22.22.2+.

Description of the Design

Add engines.node to all package.json files and update those which need updating.

I do not recommend claiming support for an engine if we are not testing against it in CI.

We need to pick a minimum version. I recommend Node.js v22.5.1 as the absolute minimum version we support due to the major regression fixed in this version. However, there are certainly features which would be useful to us in newer versions; see the list below.

TypeScript Support

Version Feature
22.6.0 --experimental-strip-types — strips type annotations from .ts files; initial TypeScript execution support
22.7.0 --experimental-transform-types — transforms TypeScript-only syntax (enum, namespace) to JS
22.14.0 TypeScript support in STDIN eval (node --input-type=typescript)
22.14.0 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX error code
22.14.0 Worker eval TypeScript input
22.18.0 Type stripping enabled by defaultnode file.ts works without flags (experimental, disable with --no-experimental-strip-types)

Module System (ESM / CJS)

Version Feature
22.7.0 Module syntax detection (--experimental-detect-module) enabled by default
22.10.0 New "module-sync" exports condition for package.json — enables dual-package ESM/CJS without the hazard
22.12.0 require(esm) enabled by default — no longer behind a flag
22.13.0 module.stripTypeScriptTypes() API
22.13.0 require(esm) experimental warning only emitted under --trace-require-module
22.14.0 module.findPackageJSON() utility
22.15.0 module.registerHooks() — synchronous customization hooks; used for import(cjs) preparsing
22.16.0 import.meta.filename and import.meta.dirname graduated to stable
22.16.0 Top-level Wasm import without needing a "type" field in package.json
22.18.0 import.meta.maintrue if the current module is the entry point
22.19.0 --experimental-wasm-modules unflagged — WebAssembly modules now stable
22.22.1 --heapsnapshot-near-heap-limit marked stable

CLI Flags

Version Feature
22.8.0 Coverage thresholds: --test-coverage-branches, --test-coverage-functions, --test-coverage-lines
22.10.0 node --run stabilized — runs package.json scripts directly
22.13.0 --trace-env and `--trace-env-[js
22.14.0 --disable-sigusr1 — prevents creating the signal I/O thread (stabilized in v22.20.0)
22.15.0 --cpu-prof* flags now allowed in NODE_OPTIONS
22.18.0 --watch-kill-signal — configure the signal used to kill watched processes
22.19.0 NODE_USE_SYSTEM_CA=1 environment variable
22.19.0 ${pid} placeholder in --cpu-prof-name
22.16.0 node.config.json default config file support — Node.js reads this file at startup
22.21.0 --use-env-proxy — enable proxy from environment variables (HTTP_PROXY, etc.)
22.21.0 Percentage support in --max-old-space-size (e.g., --max-old-space-size=75%)

node:sqlite

Version Feature
22.13.0 node:sqlite unflagged — the module is no longer experimental by default
22.13.0 StatementSync.prototype.iterate() method
22.13.0 SQLite constants aggregated under a single property
22.12.0 SQLite Session Extension support (createSession(), applyChangeset())
22.14.0 StatementSync accepts TypedArray and DataView as bind parameters
22.15.0 User-defined functions can return ArrayBufferViews
22.16.0 StatementSync.prototype.columns() — returns column metadata
22.18.0 readBigInts option at the DB connection level

node:test (test runner)

Version Feature
22.6.0 test_runner.run() gains watch support and globPatterns option
22.6.0 context.filePath property
22.6.0 Snapshot test file determined from context
22.8.0 Support running tests in-process
22.8.0 Defer inheriting hooks until run()
22.10.0 Support custom argv in run()
22.10.0 'test:summary' event
22.10.0 Code coverage via run() API
22.14.0 TestContext.prototype.waitFor() — wait for a condition to become true
22.14.0 t.assert.fileSnapshot() — file-based snapshot assertions
22.14.0 assert.register() — register custom assertion methods
22.20.0 Object property mocking (mock.getter(), mock.setter())

HTTP / HTTPS

Version Feature
22.6.0 Diagnostics channel http.client.request.error
22.12.0 Diagnostics channel http.client.request.created
22.19.0 server.keepAliveTimeoutBuffer option
22.20.0 Agent.agentKeepAliveTimeoutBuffer option
22.21.0 shouldUpgradeCallback — servers can control HTTP upgrade behavior
22.21.0 Built-in proxy support in http.request(), https.request(), and Agent — picks up HTTP_PROXY/HTTPS_PROXY when --use-env-proxy or NODE_USE_ENV_PROXY is set
22.21.0 Fetch respects proxy under NODE_USE_ENV_PROXY

HTTP/2

Version Feature
22.10.0 Expose nghttp2_option_set_stream_reset_rate_limit as a session option
22.17.0 Diagnostics channel http2.server.stream.finish
22.20.0 Raw header arrays in h2Stream.respond()

Crypto / TLS

Version Feature
22.9.0 tls.createSecureContext({ allowPartialTrustChain: true }) — treat intermediate certs as trusted
22.10.0 KeyObject.prototype.toCryptoKey()
22.10.0 x509.validFrom / x509.validTo as Date objects
22.13.0 WebCryptoAPI Ed25519 and X25519 algorithms graduated to stable
22.15.0 --use-system-ca support on macOS and Windows
22.15.0 tls.getCACertificates()
22.19.0 tls.setDefaultCACertificates()
22.20.0 OpenSSL updated to 3.5.2 (previously 3.0.x)

Streams

Version Feature
22.6.0 stream.DuplexPair API exposed
22.16.0 stream.finished() preserves AsyncLocalStorage context
22.20.0 Brotli support in CompressionStream / DecompressionStream

Workers

Version Feature
22.10.0 worker.markAsUncloneable() — mark objects to throw on structured clone
22.14.0 worker.isInternalWorker() — detect internal Node.js workers
22.16.0 worker.getHeapStatistics()
22.18.0 Worker is now async disposable (Symbol.asyncDispose)
22.20.0 CPU profiling APIs for workers

Process

Version Feature
22.10.0 process.features.require_module
22.10.0 process.features.typescript
22.14.0 process.ref() and process.unref() — control whether the process stays alive
22.15.0 process.execve() — replace process image (Unix only)
22.19.0 process.threadCpuUsage() — CPU usage for the current thread

File System

Version Feature
22.14.0 fs.glob() exclude option accepts glob patterns
22.17.0 fs.FileHandle.readableWebStream({ autoClose }) option
22.17.0 fs.Dir supports explicit resource management (Symbol.asyncDispose)
22.18.0 fs.watch() async iterator correctly handles event bursts
22.20.0 path.matchesGlob() graduated to stable

Networking

Version Feature
22.13.0 net.BlockList support in net.connect() and net.Server
22.13.0 SocketAddress.parse()
22.13.0 net.BlockList.isBlockList(value)
22.13.0 dgram blocklist support (UDP)
22.12.0 UV_TCP_REUSEPORT for TCP sockets
22.12.0 UV_UDP_REUSEPORT for UDP sockets
22.19.0 net.BlockList can now save/load to/from files
22.19.0 DNS max timeout support
22.15.0 DNS: TLSA record query and parsing

Compile Cache

Version Feature
22.8.0 module.enableCompileCache() — JS API to enable on-disk code caching
22.10.0 module.flushCompileCache() — flush cache to disk

Utilities

Version Feature
22.9.0 util.getCallSite() — retrieve current execution stack trace
22.13.0 util.getCallSites() gains source map support
22.15.0 util.diff() — expose the Myers diff function used internally by assert
22.16.0 util.types.isFloat16Array()
22.17.0 util.styleText() gains 'none' style for removing terminal styling

node:assert

Version Feature
22.12.0 AssertionError uses Myers diff algorithm for nicer diffs
22.13.0 assert.partialDeepStrictEqual() (experimental)
22.15.0 Improvements to partialDeepStrictEqual error comparison
22.17.0 assert.partialDeepStrictEqual() graduated to stable

node:v8 / node:vm

Version Feature
22.8.0 vm.constants.DONT_CONTEXTIFY — create a context with a freezable globalThis
22.15.0 v8.getCppHeapStatistics()

SEA (Single Executable Applications)

Version Feature
22.20.0 execArgv support in SEA config
22.20.0 execArgvExtension

Inspector / DevTools

Version Feature
22.6.0 Experimental network inspection (--experimental-network-inspection)
22.7.0 Inspector Network.loadingFailed event

Compression (node:zlib)

Version Feature
22.15.0 Zstd compression support (zlib.createZstd*, etc.)
22.19.0 Dictionary support in zstdCompress / zstdDecompress

Permission Model

Version Feature
22.13.0 Permission Model graduated to stable
22.18.0 Permission model flags propagated when spawning child processes
22.18.0 permission.has('addon') support
22.17.0 Implicit --allow-fs-read to entrypoint file

Other Stabilizations (v22.17.0 batch)

APIs graduated to stable in a single batch in v22.17.0:

  • dirent.parentPath
  • filehandle.readableWebStream()
  • fs.glob()
  • fs.openAsBlob()
  • node:readline/promises
  • port.hasRef()
  • readable.compose()
  • readable.iterator()
  • readable.readableAborted
  • readable.readableDidRead
  • Duplex.fromWeb()
  • Duplex.toWeb()
  • Readable.fromWeb()
  • Readable.isDisturbed()
  • Readable.toWeb()
  • stream.isErrored()
  • stream.isReadable()
  • URL.createObjectURL()
  • URL.revokeObjectURL()
  • v8.setHeapSnapshotNearHeapLimit()
  • Writable.fromWeb()
  • Writable.toWeb()
  • writable.writableAborted
  • Startup Snapshot API
  • ERR_INPUT_TYPE_NOT_ALLOWED
  • ERR_UNKNOWN_FILE_EXTENSION
  • ERR_UNKNOWN_MODULE_FORMAT
  • ERR_USE_AFTER_CLOSE

Security Considerations

n/a

Scaling Considerations

n/a

Test Plan

n/a

Compatibility Considerations

We should document the minimum supported engine(s) in the README.md files.

Upgrade Considerations

I think this is a breaking change for certain package manager/version pairings. Others will warn.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agendaTopics for next Endo meeting agendaenhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions