88 lines
4.5 KiB
Markdown
88 lines
4.5 KiB
Markdown
# ADR-002: Node.js 24 LTS runtime
|
|
|
|
- Status: Accepted
|
|
- Date: 2026-08-31
|
|
- Deciders: platform stream
|
|
- References: ADR index (section 70), Technology stack wiki (sections 5.2, 6, 7, 8), ADR-001
|
|
|
|
## Context
|
|
|
|
EPPP is a greenfield personal blogging platform (ADR-001) whose runtime is a
|
|
single modular-monolith application plus an optional worker, deployed as one
|
|
or more containers of one image. The whole platform — public server, admin
|
|
API, rendering pipeline, extension runtime, core services and background
|
|
jobs — executes on one runtime, so the runtime choice is a platform-wide,
|
|
hard-to-reverse decision with security, tooling and operational reach.
|
|
|
|
The workspace is a pnpm monorepo (pnpm 11.23.0) whose root manifest already
|
|
declares `engines.node: ">=24.0.0 <25.0.0"` with `engineStrict: true`, and
|
|
the CI pipeline installs and runs on Node 24 (E00-S01-T08). The technology
|
|
stack wiki classifies Node.js as support class A — a fixed upstream EOL date
|
|
— and pins the golden compatibility tuple to Node 24.19.0 LTS (Krypton), with
|
|
`node:24.19.0-bookworm-slim` as the application container base image.
|
|
|
|
## Decision
|
|
|
|
EPPP runs on the **Node.js 24 LTS** runtime line, exact-pinned to Node 24.19.0
|
|
LTS (Krypton) in the golden compatibility tuple and the container image. The
|
|
workspace root manifest restricts the engine to 24.x
|
|
(`engines.node: ">=24.0.0 <25.0.0"`), pnpm enforces it at install time
|
|
(`engineStrict: true`), and CI installs and runs on Node 24. The runtime is a
|
|
class A dependency: its upstream EOL (2028-04-30) drives the upgrade
|
|
schedule, and a move to a later major line (for example Node 26) is only
|
|
evaluated once that line is LTS and the compatibility suite passes, and then
|
|
only as a deliberate, ADR-recorded change. The decision text — **Node.js 24
|
|
LTS runtime** — matches the ADR index entry (ADR-002, section 70).
|
|
|
|
## Alternatives
|
|
|
|
- **Node 22 LTS (Jod)** — rejected: it is the previous LTS line and reaches
|
|
EOL before Node 24 (2027-04-30), shortening the runway for a platform whose
|
|
v1.1 boundary contracts (ADR-027 to ADR-032) extend past that date.
|
|
- **Node 26 (current, non-LTS at decision time)** — rejected: not LTS when
|
|
the decision was made; running a non-LTS line contradicts the class A
|
|
support posture (fixed EOL, security patching on an LTS cadence).
|
|
- **Node 24 with no exact pin (floating latest 24.x)** — rejected: a floating
|
|
minor would break the reproducibility of the golden compatibility tuple and
|
|
the container image; the line is pinned and minors move deliberately.
|
|
- **Node 24 LTS, exact-pinned 24.19.0** — chosen: an LTS major with a fixed
|
|
EOL, exact-pinned in the image and tuple, engine-restricted in the
|
|
manifest, and enforced in CI.
|
|
|
|
## Consequences
|
|
|
|
- Positive: an LTS line with a fixed upstream EOL (2028-04-30) gives a
|
|
predictable security-patching and upgrade horizon; the exact pin makes
|
|
builds and containers reproducible; the engine restriction rejects
|
|
unsupported Node versions at install time instead of failing at runtime.
|
|
- Negative: Node 24 API and behaviour become the platform floor — anything
|
|
needing a newer Node feature waits for the deliberate, ADR-recorded major
|
|
upgrade; minor upgrades inside 24.x still need the weekly dependency sweep
|
|
and full CI.
|
|
- Neutral: the runtime is shared by every module, so a future extraction
|
|
(ADR-001) keeps running on the same Node line until that module's runtime
|
|
needs diverge.
|
|
|
|
## Operational impact
|
|
|
|
- Application and worker containers run `node:24.19.0-bookworm-slim`; release
|
|
automation records the immutable image digest in the SBOM/release manifest.
|
|
- The supported runtime is enforced at install (`engineStrict: true` fails
|
|
installs on unsupported Node) and at test time (the node-engine suite
|
|
asserts the current runtime satisfies the 24.x range).
|
|
- CI installs and runs every stage on Node 24, so the committed pipeline is
|
|
the operational proof that the platform runs on the chosen line.
|
|
- Node 24 is patched on the LTS cadence; security-emergency updates go
|
|
through the focused lane (immediate, full CI), and the EOL date is the
|
|
deadline for the next major-line ADR.
|
|
|
|
## Revisit trigger
|
|
|
|
- Revisit when Node 26 becomes LTS and passes the compatibility suite, per
|
|
the LTS strategy — the decision to move majors is a new ADR, not a patch.
|
|
- Revisit on a security-emergency or patch-lane event that forces a minor
|
|
upgrade outside the weekly sweep, or if upstream announces a change to the
|
|
Node 24 support horizon.
|
|
- Revisit if a module's runtime needs (ADR-001 extraction) diverge from the
|
|
shared Node line and a second runtime enters the platform.
|