Skip to content

Upgrade runtime from Node 20 to Node 22 #918

Description

@grunch

Context

Node 20 ("Iron") reached end of life on 2026-04-30 and no longer receives security patches. For a bot that custodies Lightning funds, running on an unsupported runtime is a standing risk on its own.

This became concrete in #917, which upgraded the Lightning dependencies:

  • lightning 11.1.012.2.4
  • invoices 2.0.66.0.5

Both new majors declare "engines": { "node": ">=22" }, while the repo still advertises and ships Node 20. There is no .npmrc, so engine-strict is off and npm only emits a warning instead of failing the install.

Current state: it works, but the contract is broken

To be clear about severity — this is not a live production break:

  • ci_to_main ran npm ci + npm test inside node:20-bookworm on the chore: update Lightning Network dependencies to latest #917 head commit and passed.
  • All 298 runtime .js files of lightning and invoices parse cleanly under Node 20.20.2, and both packages require() without error.
  • Neither package uses a Node 22-only API in shipped code (the only node:test references live in their own test/ directories, which are not used at runtime).

The real problem is forward-looking: upstream has declared Node 20 unsupported. Any future patch release of lightning or invoices may introduce Node 22+ syntax or APIs with no warning, and nothing in our install or CI would catch it before it reached production.

Combined with the EOL status of Node 20, the right fix is to move the runtime forward rather than pin the dependencies back.

Pre-existing inconsistency worth folding in

.github/workflows/code-linter.yaml runs on Node 18.x, which is already below the >=20.0.0 the root package.json declares. Unrelated to #917, but it should be corrected in the same pass.

What needs to change

File Line Current Target
Dockerfile 4 FROM node:20-alpine AS builder node:22-alpine
Dockerfile 48 FROM node:20-alpine AS production node:22-alpine
.github/workflows/integrate.yaml 28 image: 'node:20-bookworm' node:22-bookworm
.github/workflows/integrate.yaml 24-26 comment referencing Node 20 update wording
.github/workflows/code-linter.yaml 21 node-version: 18.x 22.x
package.json engines ">=20.0.0" ">=22.0.0"

Optional but recommended:

  • Add .npmrc with engine-strict=true so an engines mismatch fails the install instead of passing as a warning. This is what would have surfaced the chore: update Lightning Network dependencies to latest #917 problem automatically.
  • Add .nvmrc pinning 22, so local development matches CI and the Docker image. The repo currently has neither .nvmrc nor .node-version.

Risks / what to watch

The main risk is native modules and the Node ABI change:

  • canvas is compiled from source in CI (integrate.yaml installs build-essential, libcairo2-dev, libpango1.0-dev, libjpeg-dev, libgif-dev, librsvg2-dev). This is the most likely place for the bump to break.
  • @grpc/grpc-js (via lightning) ships prebuilt binaries and should be checked on the new base image.

The Alpine (node:22-alpine) and Debian (node:22-bookworm) images differ in libc, so both the Docker build and the CI container need to be validated independently — a green CI run does not by itself prove the production image builds.

Acceptance criteria

  • docker build succeeds against node:22-alpine, including the canvas native build
  • npm start runs successfully inside the built image (per AGENTS.md)
  • ci_to_main passes on node:22-bookworm
  • code-linter passes on Node 22
  • npm ci produces no engine warnings for any dependency
  • Bot verified against a signet/testnet LND node: sell order, buy order, and cancel flows complete end to end

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions