Repository navigation
chore: maintenance update for Node.js 24 and current Ubuntu LTS releases - #4875
Merged
Merged
Conversation
lerna 7 hoists node-gyp 9.4.1, whose bundled gyp still imports `distutils`. Python 3.12 removed `distutils`, so `yarn setup` fails while compiling bcrypto on Ubuntu 24.04 (Python 3.12) and 26.04 (Python 3.14). Adding node-gyp 11 as a root devDependency hoists a modern node-gyp to `node_modules/.bin`, which yarn uses for native install scripts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With nan 2.18.0 from the lockfile, tiny-secp256k1 and bstring fail to compile against the Node.js 24 headers and silently fall back to their JavaScript implementations. Production installs resolve the newest nan and build them natively, so CI tested different code than nodes run. Only the lockfile changes, the version ranges stay the same. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
better-sqlite3 9.x compiles as C++17, but the V8 headers shipped with Node 24 require C++20, so the transaction pool's storage cannot be built. Majors 10, 11 and 12 only dropped support for EOL Node.js and Electron versions; the JavaScript API used in `storage.ts` is unchanged. 12.x ships prebuilt binaries for Node 24 (glibc and musl). Pool database files are compatible in both directions between 9.3.0 and 12.11.1. @types/better-sqlite3 is updated to 7.6.13 alongside. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Node.js >= 19 enables keep-alive on `http.globalAgent` and `https.globalAgent`. Core's API server destroys the socket once a response has finished (core-api `server.ts`) while still advertising keep-alive, so a client that reuses the pooled socket fails with `ECONNRESET: socket hang up`. Core's own outbound requests hit this when they talk to other Core nodes (peer API port checks) and in webhooks; on Node 24 it also broke 14 of 18 transaction-forging functional tests. Turn keep-alive off on the existing global agents during application bootstrap so every request opens a new connection, as before Node 19. Changing the agents instead of replacing them keeps their other defaults, such as the proxy configuration used with `NODE_USE_ENV_PROXY` and the request timeout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Updates ws to the latest 7.x release. The changes since 7.5.10 do not affect the API Core uses, and P2P messages are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Updates protobufjs to the latest 7.x release. The committed static code only requires `protobufjs/minimal` and keeps working unchanged. protobufjs-cli is updated to 1.3.3 so that future `yarn build:proto` runs match the runtime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Updates joi to the latest 17.x release. Same major; schema behaviour is unchanged for the features Core uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core only uses `qs.stringify` with `encode: false` to build pagination links; the generated links are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core only uses random bytes, AES-CBC, PBKDF2 and base64 for BIP38. Of these, only AES-CBC decryption changed: it now rejects invalid padding, which Core's own encrypt and decrypt round trip never produces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm marks reflect-metadata 0.2.1 as deprecated ("This version has a
critical bug in fallback handling. Please upgrade to reflect-metadata@0.2.2
or newer."), so yarn prints that warning for core-cli, core-database and
core-kernel on every install, including `yarn global add @ArkEcosystem/core`.
The fallback is used when an older reflect-metadata without a metadata
registry was loaded first. typeorm still depends on reflect-metadata 0.1.x
(0.1.14 is installed nested under it), so that combination can occur in
Core. In 0.2.1 the fallback reports no metadata for a property once it has
recorded metadata for another property of the same object; 0.2.2 fixes
that, and its only other code change is in the random bytes helper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm marks @hapi/boom 9.0.0 as deprecated ("no longer supported or
maintained"), so every install prints that warning twice. core-api and
core-magistrate-api already use 9.1.4 and hapi 20 itself depends on
^9.1.0; the changes since 9.0.0 do not affect how Core creates or checks
Boom errors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pm2/io 6 drops the tracing support built on @opencensus, which pulled in uuid@3, and npm reports that as deprecated three times during every install. Core only registers process actions through `pmx.action()`, which is unchanged in 6.x; process error handling, exit codes and IPC messages behave as in 5.0.2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
npm marks uuid 10 and below as unsupported, so every install prints a deprecation warning for core-webhooks' uuid 9.0.1. uuid 11 still ships a CommonJS build, and `v4()`, the only function Core uses to create webhook ids, is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Updates tar to the latest 6.x release. tar only extracts plugin archives the operator installs with `ark plugin:install`; the `extract()` call used there is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pg-query-stream depends on pg-cursor, which lists `pg` as a peer dependency and requires `pg/lib/*` at runtime. core-snapshots never declared `pg`, so every install printed an "unmet peer dependency" warning and the module was only found because core-database's copy is hoisted. Declare the same pg version core-database uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`ark reinstall` installs the newest pm2 that satisfies this range globally (Installer.installPeerDependencies -> installRangeLatest). With `^4.5.0` that is pm2 4.5.6, which is no longer maintained and prints a `util._extend` deprecation warning on every command under Node 24. install.sh already installs the latest pm2, so fresh installations run pm2 7 and this aligns `ark reinstall` with them. Mark the peer dependency as optional: install.sh installs pm2 for root, outside the global folder `yarn global add @ArkEcosystem/core` sees, so every install printed an "unmet peer dependency" warning. The CLI still reads the range to install pm2 on `ark reinstall`. `ark update` is not affected: it passes the channel dist-tag to `yarn info <pkg>@<tag> peerDependencies`, which returns no data for a dist-tag in yarn 1, so it never installs peer dependencies. The pm2 commands used by the process manager (start, jlist, id, trigger, reload, restart, reset, stop, delete, flush, reloadLogs, ping, update) work unchanged with pm2 7.1.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`relay:share` only exposed a local relay through an ngrok tunnel, but the ngrok package it needs is a liability for every installation: - ngrok 4.3.3 has a postinstall script that downloads the deprecated ngrok v2 agent (a 14 MB archive from bin.equinox.io) on every Core install and exits with code 1 if that download fails, which aborts the whole `yarn global add`. - Commands are discovered eagerly, so the module was loaded on every `ark` invocation, not only for `relay:share`. Operators who want to share a relay can run the ngrok agent themselves. BREAKING CHANGE: the `ark relay:share` command has been removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Node.js 16 and 18 are end-of-life and this release is built and tested on Node.js 24. Declare `^24.22.1` in `engines`: Node.js 24 only, at least 24.22.1, the latest release at the time (2026-10-20). `yarn global add` then refuses to install Core on an older runtime instead of failing while compiling native modules, and `.nvmrc` is pinned to the same version. yarn also enforces `engines` when running package scripts, so building the monorepo (`yarn setup`, `yarn build`) requires Node.js >= 24.22.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Build the image on node:24-alpine. - Pin postgres:18-alpine instead of the floating postgres:alpine tag, and mount the volume at /var/lib/postgresql as PostgreSQL 18 images require. The floating tag already resolves to 18, and those images refuse to start with a volume mounted at /var/lib/postgresql/data, so pulling a fresh image broke existing compose setups without any change on our side. - Document how to keep or upgrade an existing volume, and warn against migrating with pg_dump/pg_restore, which silently skips the blocks and transactions tables (the integrity check functions reference tables without a schema while pg_restore runs with an empty search_path). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The packages now require Node.js ^24.22.1 and yarn enforces `engines` when running package scripts. Run every job that installs or builds Core on the latest Node.js 24 release, the same version operators get from NodeSource `node_24.x` and the `node:24` Docker images. actions/setup-node@v4 with `check-latest` is needed for that: setup-node otherwise uses the 24.x cached on the runner image, which can be older than the required 24.22.1, and v1 has no way to skip the cache. The CodeQL job gains the same setup step and moves from the retired github/codeql-action v1 to v4. Include the Node.js major in the node_modules cache key so a cache built on Node.js 16 (native modules for ABI 93) is not restored. The e2e node image runs the repository built on the runner and moves to node:24. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PostgreSQL 12 is end-of-life and outside the supported 16 and 18. Run the functional and integration jobs against PostgreSQL 18, and pin the e2e network to 18 instead of the floating alpine tag. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
packages/core-manager no longer exists, so its publish line failed on every release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
oXtxNt9U
requested review from
ItsANameToo,
boldninja and
sebastijankuzner
as code owners
October 28, 2026 04:05
oXtxNt9U
force-pushed
the
chore/node-24-maintenance
branch
from
October 29, 2026 01:59
2bc0617 to
75e5e8a
Compare
3 tasks
ItsANameToo
approved these changes
Oct 29, 2026
sebastijankuzner
approved these changes
Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Core 3.13 can't be installed on a supported operating system. This PR makes Core run on Node.js ≥ 24.22.1 and updates its dependencies, Docker and CI. The installer changes for Ubuntu 22.04–26.04 are in #, stacked on this one.
Scope: only changes that reach a running or installing node, plus the build and CI changes needed to ship them.
Note
This is not a hard fork. It changes no consensus rules, milestones or network configuration, and P2P messages are byte-identical to 3.13.0. Nodes on 3.13.0 and nodes on this release run side by side on the same network, so operators can upgrade at their own pace.
This release will be published under a new npm dist-tag, not
latest. The publishing change comes in a follow-up PR, which lands before the release. Existing nodes are not affected:ark updateon a 3.13.0 node only checkslatest, so a node that runs it by accident stays on 3.13.0 and isn't offered this release. Upgrading is a deliberate, manual step, described in the upgrade guide.Changes
Runs on Node 24
ECONNRESETengines→^24.22.1Dependency updates
No code changes; behaviour verified identical.
pgdeclared in core-snapshots; pm2 peer dependency^7.0.0, marked optionalRemoved:
ark relay:shareand ngrokOperators who need a tunnel can run a current agent, e.g.
ngrok http 4003.Docker and CI
node:24-alpineandpostgres:18-alpinepinnedTesting
On Node 24.22.1, Ubuntu 26.04 and PostgreSQL 18:
Release notes
To be added before the release.
Operator notice
Important
Core
<version>requires Node.js 24.22.1 or newer. Not every server can run it. Check the table below before upgrading.Can my server upgrade?
Upgrading in place
To be added before the release.
Moving to a new server
To be added before the release.
Other changes
ark relay:sharehas been removed. To expose a relay, run a current ngrok agent yourself (e.g.ngrok http 4003).Checklist