🔄 Technology Lifecycle Management for Static Intelligence Platform
📦 Node.js 26 Active • ⏭️ Node.js 26 LTS Promotion October 2026 • ⚡ Future-Ready Architecture
📋 Document Owner: CEO | 📄 Version: 1.4 | 📅 Last Updated: 2026-04-20 (UTC)
🔄 Review Cycle: Annual | ⏰ Next Review: 2027-04-20
🏢 Owner: Hack23 AB (Org.nr 5595347807) | 🏷️ Classification: Public
🆕 What changed since last review (v1.3 → v1.4, 2026-04-20):
- 📈 IMF data integration added per ADR 0001 (alongside SCB and World Bank). EOL risk assessment: LOW. IMF is consumed via the pure-TypeScript client
scripts/imf-client.ts(no runtime dependency on any external MCP package, no Python / uvx / third-party container). Upstream protocols are both stable and long-lived: SDMX 3.0 (ISO 17369 international standard, backward-compatible versioning) and the IMF Datamapper JSON v1 public endpoint (www.imf.org/external/datamapper/api/v1). No new third-party npm dependencies were introduced — the client uses only the existing Node.jsfetchstdlib and existing dev/test tooling, so IMF adds no new EOL pressure beyond what is already tracked for Node.js, TypeScript, and Vitest. If either transport is ever deprecated by the IMF, the client pattern mirrorsscripts/world-bank-client.tsand can be repointed without affecting the downstream data contract (Economic Data Contract v2.0).🆕 What changed since last review (v1.2 → v1.3, 2026-04-20):
- Confirmed runtime alignment with Node.js ≥26 (
engines.nodeinpackage.json); Node 26 LTS upgrade window now the imminent transition target.- Locked current EOL/support horizons for the toolchain powering Riksdagsmonitor
v0.8.48: TypeScript 6.x, Vite 8.x, Vitest 4.x, ESLint 10.x, Cypress 15.x, Playwright 1.59.x, typedoc 0.28.x, happy-dom 20.x, knip 6.x, ajv 8.x, htmlhint 1.9.x.- Peer-dependency runtime surface (optional to consumers of the npm package): Chart.js ^4, chartjs-plugin-annotation ^3, D3 ^7, papaparse ^5.
- Added npm package deprecation policy: public API contract lives in exported subpaths
./,./shared,./shared/*,./cia/*,./dashboards/*,./ui/*. Breaking changes require a major SemVer bump, a 2-release deprecation window with@deprecatedJSDoc, and a migration note inRELEASE_PROCESS.md.- Confirmed SLSA provenance (
npm publish --provenance) attestations accompany every published version and are verifiable vianpm provenance verify.- Aligned with Hack23 ISMS-PUBLIC Open_Source_Policy and Secure_Development_Policy §6 "Dependency Management".
Riksdagsmonitor is a static HTML5/CSS3 website deployed to AWS CloudFront + S3 (primary) and GitHub Pages (disaster recovery), built with Vite, tested with Vitest and Cypress, and powered by Node.js 26. The platform provides Swedish Parliament transparency through interactive Chart.js and D3.js visualisations across 14 languages.
⚡ Upgrade Note (May 2026): Riksdagsmonitor has been upgraded to Node.js 26 (Current → LTS in October 2026). Node.js 26 will be promoted to LTS in October 2026 — no additional migration step needed. A Node.js 27 nightly compatibility CI job (
continue-on-error: true) tracks the next-generation release. See the Node.js Migration Roadmap for the full plan.
This document defines the technology lifecycle management strategy — covering the current stack, Node.js release schedule evolution, dependency EOL timelines, and migration plans — to ensure stability, compatibility, and security throughout the project's operational life.
This strategy should be read alongside the Business Continuity Plan, Financial Security Plan, and Architecture Documentation for full technical and business context.
Primary Goal: Maintain Riksdagsmonitor on a supported, secure technology stack by proactively tracking dependency lifecycles and planning migrations before components reach end-of-life.
Key Principles:
- Upgrade to new Node.js Current versions promptly; LTS promotion happens in-place (no second migration needed)
- Keep build tooling (Vite, Vitest, TypeScript) on latest stable versions
- Maintain zero known critical/high vulnerabilities via automated scanning
- Plan major migrations 12 months before dependency EOL dates
- Ensure the static output (HTML/CSS/JS) remains browser-compatible for 5+ years
The current Node.js release schedule is 10 years old, created during the io.js merger. A decade of usage data now shows:
- Odd-numbered releases see minimal adoption — most users wait for Long-Term Support
- The odd/even distinction confuses newcomers and many organisations skip odd releases entirely
- Volunteer sustainability — Node.js is maintained primarily by volunteers; managing security releases across four or five active release lines has become difficult to sustain, as each additional line increases backporting complexity
By reducing concurrent release lines, the project can focus on better supporting the releases people actually use while making the schedule more predictable for enterprises.
Starting with Node.js 27.x, the Node.js project is moving from two major releases per year to one (see nodejs/Release#1113 for full background). Key changes:
| Aspect | Old Model (≤26.x) | New Model (≥27.x) |
|---|---|---|
| Major releases | 2 per year (April + October) | 1 per year (April) |
| LTS promotion | Even-numbered only (October) | Every release becomes LTS (October) |
| Odd/even distinction | Odd = Current-only, Even = LTS | No distinction — all releases get LTS |
| Version numbering | Sequential | Aligned to calendar year (27 in 2027, 28 in 2028) |
| Alpha channel | N/A | 6-month alpha phase (Oct–Mar) with semver-major changes |
| Alpha versioning | N/A | Semver prerelease format (e.g., 27.0.0-alpha.1) |
| Total support window | ~36 months (LTS only) | 36 months from first Current release to EOL |
| Phase | Duration | Description |
|---|---|---|
| Alpha | 6 months (Oct → Mar) | Early testing, semver-major changes allowed. Versioning: X.0.0-alpha.N |
| Current | 6 months (Apr → Oct) | Stabilisation, bug fixes |
| LTS | 30 months (Oct → Apr+30mo) | Long-term support with security fixes |
| EOL | — | No further support |
For users who already only upgrade to LTS versions, little changes beyond version numbering. LTS support windows remain similar, and now every release becomes LTS.
- Simplified upgrade planning: Every Node.js release becomes LTS, eliminating the need to skip odd-numbered versions
- Annual upgrade cadence: Plan one major Node.js upgrade per year (April release, adopt after October LTS promotion)
- Alpha testing in CI: Integrate Node.js alpha releases into the CI matrix to catch compatibility issues early — this is critical since alpha is the only window to report bugs before they affect LTS users
- Reduced concurrent support lines: Fewer active Node.js versions means clearer migration targets and less upgrade pressure
- Library author responsibility: As a consumer of npm packages, we benefit when library authors test against alpha versions; we should also test our own build tooling compatibility early
To proactively catch Node.js compatibility issues, Riksdagsmonitor will adopt the following alpha testing approach:
| CI Matrix | Trigger | Failure Policy |
|---|---|---|
| Node.js LTS (current) | Every push, PR | ❌ Blocking — must pass |
| Node.js Current | Every push, PR | ❌ Blocking — must pass |
| Node.js Alpha (next) | Weekly scheduled |
This allows early detection of breaking changes in Node.js alpha while keeping production deployments stable on LTS.
| Category | Technology | Current Version | EOL Date | Replacement Path |
|---|---|---|---|---|
| Runtime | Node.js 26 | 26.x | April 2029 (Maintenance end) | Node.js 27 LTS (2027) |
| Package Manager | npm | Bundled with Node.js | Follows Node.js | Follows Node.js upgrades |
| Language | TypeScript | 6.0.2 | Active (quarterly releases) | Track latest stable |
| Build Tool | Vite | 8.0.3 | Active | Track latest major |
| Transpiler | tsx | 4.21.0 | Active | Track latest stable |
| Category | Technology | Current Version | EOL Date | Replacement Path |
|---|---|---|---|---|
| Unit Testing | Vitest | 4.1.2 | Active (follows Vite) | Track with Vite major versions |
| E2E Testing | Cypress | 15.13.0 | Active | Track latest stable |
| Coverage | @vitest/coverage-v8 | 4.1.2 | Active | Track with Vitest |
| DOM Simulation | happy-dom | 20.8.9 | Active | Track latest stable |
| Category | Technology | Current Version | EOL Date | Replacement Path |
|---|---|---|---|---|
| Charting | Chart.js | 4.5.1 | Active | Track latest stable |
| Chart Annotations | chartjs-plugin-annotation | 3.1.0 | Active | Follows Chart.js |
| Data Visualisation | D3.js | 7.9.0 | Active | Track latest major |
| CSV Parsing | PapaParse | 5.5.3 | Active | Track latest stable |
| JSON Validation | Ajv | 8.18.0 | Active | Track latest stable |
| JSON Formats | ajv-formats | 3.0.1 | Active | Follows Ajv |
| Category | Technology | Current Version | EOL Date | Replacement Path |
|---|---|---|---|---|
| Linting | ESLint | 10.1.0 | Active | Track latest major |
| HTML Linting | HTMLHint | 1.9.2 | Active | Track latest stable |
| Dead Code | knip | 6.1.1 | Active | Track latest stable |
| API Docs | TypeDoc | 0.28.18 | Active | Track latest stable |
| SRI Generation | vite-plugin-sri-gen | 1.3.2 | Active | Track latest stable |
| TypeScript | Release Date | Status | Support Until |
|---|---|---|---|
| 6.0.2 | Mar 2026 | ✅ Active — in use | Until 7.0 release (~12 months) |
| 5.9.x | Feb 2026 | Previous stable | Limited — security patches only |
| 5.8.x | Dec 2025 | End of life | ❌ No support |
Note: TypeScript 6.0 is a major release with breaking changes including deprecated
baseUrloption (still functional, silenced viaignoreDeprecations: "6.0"), stricter module resolution in bundler mode, and removal of implicitglobalnamespace. The project uses@typescript-eslint 8.58.0which supportstypescript >=4.8.4 <6.1.0.
- Upgrade to new patch versions immediately — bug fixes only, no breaking changes.
- Upgrade to new minor versions within 2 weeks — validate
tsc --noEmit, ESLint, and all tests pass. - Upgrade to new major versions within 1 month — major versions may require code changes and
@typescript-eslintcompatibility updates. - Never use TypeScript versions unsupported by
@typescript-eslint— this would disable type-aware linting.
| Trigger | Action | Timeline |
|---|---|---|
| New patch release (e.g., 6.0.3) | Update package.json, run full CI |
Within 1 week |
| New minor release (e.g., 6.1.0) | Verify @typescript-eslint compatibility first |
Within 2 weeks |
| New major release (e.g., 7.0.0) | Full compatibility assessment, dedicated PR | Within 1 month |
@typescript-eslint drops support |
Upgrade @typescript-eslint or pin TypeScript |
Within 24 hours |
| Milestone | Date | Status |
|---|---|---|
| Node.js 24 Current Release | April 2025 | ✅ Adopted |
| Node.js 24 LTS Promotion | October 2025 | ✅ Production deployment |
| Node.js 24 → 25 Migration | March 2026 | ✅ Completed |
| Node.js 25 → 26 Migration | May 2026 | ✅ Completed (this release) |
Node.js 26 is the last release under the old two-per-year schedule. It releases as "Current" in April 2026 and will be promoted to LTS in October 2026 — no additional migration will be needed at that point, as the project will already be on Node.js 26.
Strategy: Stay on Node.js 26 from Current through LTS in-place — no additional upgrade step required at October 2026 LTS promotion.
| Milestone | Date | Status |
|---|---|---|
| Node.js 26 Current Release | April 2026 | ✅ Available |
| Riksdagsmonitor upgrade to 26 | May 2026 | ✅ Completed (this release) |
| Node.js 26 LTS Promotion | October 2026 | ⏳ No migration needed — will transition in-place |
| Node.js 26 Active LTS End | October 2027 | Begin evaluating Node.js 27 |
| Node.js 26 Maintenance End | April 2029 | Must be off Node.js 26 |
Completed upgrade checklist (for Node.js 26):
- Validate TypeScript native type-stripping (
process.features.typescript === "strip") still works - Confirm all 43+ workflows pass on Node.js 26 (blocking CI jobs)
- Verify GitHub Actions
ubuntu-latestrunners include Node.js 26 - Update all
node-version: '25'→'26'across all workflow YAML and markdown files - Update
package.jsonengines.nodefrom>=25to>=26 - Update
.nvmrcfrom25to26 - Update skills documentation (
./github/skills/**SKILL.md) code examples - Update documentation (End-of-Life-Strategy.md, WORKFLOWS.md, FUTURE_WORKFLOWS.md, README.md, TESTING.md)
- Add Node.js 27 nightly CI compatibility job (
continue-on-error: true)
Node.js 27 is the first release under the new one-per-year schedule where every release becomes LTS.
| Milestone | Date | Action |
|---|---|---|
| Node.js 27 Alpha Phase | October 2026 – March 2027 | Add alpha to CI matrix |
| Node.js 27 Current Release | April 2027 | Evaluate compatibility |
| Node.js 27 LTS Promotion | October 2027 | Plan migration from Node.js 26 |
| Migration Window | Oct 2027 – Mar 2028 | Upgrade riksdagsmonitor to Node.js 27 |
| Node.js 27 EOL | ~April 2030 | Plan next migration |
| Milestone | Date | Action |
|---|---|---|
| Node.js 28 Alpha Phase | October 2027 – March 2028 | Add alpha to CI matrix |
| Node.js 28 Current Release | April 2028 | Evaluate compatibility |
| Node.js 28 LTS Promotion | October 2028 | Plan migration from Node.js 27 |
| Migration Window | Oct 2028 – Mar 2029 | Upgrade riksdagsmonitor to Node.js 28 |
| Node.js 28 EOL | ~April 2031 | Plan next migration |
gantt
title Node.js Lifecycle & Riksdagsmonitor Migration Plan
dateFormat YYYY-MM
axisFormat %Y-%m
section Node.js 24 (completed)
Active LTS :done, n24lts, 2025-10, 2026-03
Migration Off 24 :done, m24, 2026-03, 2026-03
section Node.js 25 (interim — completed)
Current (interim) :done, n25curr, 2025-10, 2026-04
Riksdagsmonitor on 25:done, rm25, 2026-03, 2026-04
section Node.js 26 (last old-model — LTS)
Current :n26curr, 2026-04, 2026-10
Active LTS :n26lts, 2026-10, 2027-10
Maintenance :n26maint, 2027-10, 2029-04
Riksdagsmonitor on 26:active, rm26, 2026-04, 2027-10
section Node.js 27 (new model — first annual LTS)
Alpha (27.0.0-alpha.x):n27alpha, 2026-10, 2027-04
Current :n27curr, 2027-04, 2027-10
LTS :n27lts, 2027-10, 2030-04
Riksdagsmonitor on 27 :rm27, 2027-10, 2030-04
section Node.js 28 (new model)
Alpha (28.0.0-alpha.x):n28alpha, 2027-10, 2028-04
Current :n28curr, 2028-04, 2028-10
LTS :n28lts, 2028-10, 2031-04
Riksdagsmonitor on 28 :rm28, 2028-10, 2031-04
| Priority | Category | Cadence | Automation |
|---|---|---|---|
| 🔴 Critical | Security patches (CVE) | Within 48 hours | Dependabot auto-merge |
| 🟡 High | Major framework updates (Vite, Vitest) | Within 2 weeks | Dependabot PR + manual review |
| 🟢 Medium | Minor/patch dependency updates | Weekly | Dependabot grouped PRs |
| ⚪ Low | Dev-only tooling updates | Monthly | Dependabot grouped PRs |
- Dependabot: Automated dependency vulnerability alerts and PRs
- CodeQL: Static analysis for JavaScript/TypeScript security issues
- GitHub Secret Scanning: Prevent credential leaks
- npm audit: Integrated into CI pipeline
- knip: Dead code and unused dependency detection
Riksdagsmonitor outputs static HTML5, CSS3, and ES2020+ JavaScript. Browser support targets:
| Browser | Minimum Version | EOL Consideration |
|---|---|---|
| Chrome | 90+ | Evergreen (auto-updates) |
| Firefox | 90+ | Evergreen (auto-updates) |
| Safari | 15+ | Tied to macOS/iOS versions |
| Edge | 90+ | Chromium-based, evergreen |
Vite Build Target: The Vite build configuration ensures output is compatible with modern browsers. The static output continues to function independently of the Node.js build tooling version.
| Component | Current | Maintenance Strategy |
|---|---|---|
| GitHub Actions runners | ubuntu-latest |
Auto-updated by GitHub |
| Action versions | SHA-pinned | Update via Dependabot |
| step-security/harden-runner | SHA-pinned | Update via Dependabot |
| Node.js in CI | node-version: '26' |
Update with each Node.js migration |
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Node.js 26 reaches EOL before Node.js 27 upgrade | Very Low | Medium | Node.js 27 upgrade planned when it reaches Current (Oct 2027); automated process ready |
| Node.js 26 breaking changes | Low | Medium | Test on Node.js 26 RC in CI matrix before it releases |
| Vite major breaking changes | Medium | Medium | Pin to major version, test upgrades in branch |
| Chart.js/D3.js API deprecation | Low | Medium | Abstraction layer isolates visualisation logic |
| Cypress major breaking changes | Medium | Low | E2E tests are supplementary; can temporarily skip |
| npm ecosystem supply chain attack | Low | High | SHA-pinned actions, SRI hashes, Dependabot alerts |
| Browser API deprecation affecting static output | Very Low | Low | ES2020+ features are stable and widely supported |
| TypeScript major upgrade breaks build | Low | Medium | Test with tsc --noEmit, lint, and full test suite before merging |
| @typescript-eslint drops TypeScript version support | Medium | High | Monitor peer dependency ranges; pin TypeScript if needed |
| Migration | Complexity | Estimated Effort | Risk Level |
|---|---|---|---|
| Node.js 24 → 25 | Very Low | < 1 day | 🟢 Very Low |
| Node.js 25 → 26 (✅ completed) | Very Low | < 1 day | 🟢 Very Low |
| Node.js 26 → 27 (new schedule) | Low | 1–2 days | 🟢 Low |
| Vite 7 → next major | Medium | 2–5 days | 🟡 Medium |
| TypeScript 5 → 6 | Low | < 1 day | 🟢 Very Low (completed) |
| TypeScript 6 → 7 | Low–Medium | 1–3 days | 🟢 Low |
| Chart.js 4 → 5 | Medium | 3–5 days | 🟡 Medium |
| D3.js 7 → 8 | Medium | 3–7 days | 🟡 Medium |
Riksdagsmonitor is a continuously maintained platform with no planned end-of-life. However, the project would enter EOL status if:
- All maintainers cease activity and no successors are appointed
- Core dependencies (Node.js, Vite, Chart.js, D3.js) all simultaneously reach EOL with no migration path
- Browser standards fundamentally change, making the static HTML/CSS/JS output non-functional
- The Riksdag (Swedish Parliament) ceases to exist or provide public data
In any EOL scenario:
- The static website will remain accessible on GitHub Pages indefinitely (read-only)
- All source code will remain available under Apache 2.0 license
- Data archives will be preserved in the repository
- A final release will be tagged with EOL notice
The ongoing maintenance strategy aligns with Hack23 AB's ISMS-PUBLIC framework to ensure systematic security management throughout the platform lifecycle.
| 🛡️ ISMS Policy | 🔧 Maintenance Activity | 📋 Implementation |
|---|---|---|
| Change Management | Node.js LTS migration planning Major dependency upgrades |
Risk-assessed transition with testing Documented migration path via PRs |
| Vulnerability Management | Automated security patching Dependency updates via Dependabot |
Weekly vulnerability scans 48-hour patch SLA for critical issues |
| Asset Register | EOL tracking for dependencies Technology stack monitoring |
Documented component lifecycle (this document) Replacement planning for EOL tech |
| Business Continuity Plan | Platform availability during transitions Rollback procedures |
Dual deployment (AWS + GitHub Pages) Tested recovery procedures |
| Secure Development Policy | Security testing during upgrades Supply chain verification |
CodeQL, npm audit, SLSA attestation SHA-pinned GitHub Actions |
Security Assurance:
- ✅ All dependency updates security-vetted through WORKFLOWS.md automated scanning
- ✅ Version compatibility tested before production deployment
- ✅ Security patches prioritised per Vulnerability Management policy
- ✅ EOL components tracked in Asset Register
- 🏛️ Architecture — Current system architecture (C4 models)
- 🚀 Future Architecture — Long-term architectural vision
- 🧠 Mindmap — System conceptual relationships
- 📋 README — Project overview and quick links
- 🛡️ Security Architecture — Current security implementation
- 🎯 Threat Model — STRIDE risk analysis
- 💰 Financial Security Plan — Cost analysis and security investment
- 📋 CRA Assessment — EU Cyber Resilience Act compliance
- 🔒 Security Policy — Vulnerability disclosure and management
- 📋 BCP Plan — Business continuity and disaster recovery
- 🚀 Release Process — Release procedures with attestations
- 🔄 CI/CD Workflows — Security-hardened CI/CD pipelines
- 🔮 Future Workflows — Enhanced CI/CD roadmap
- 🔐 Information Security Policy — Overall security governance
- 🔍 Vulnerability Management — Security testing and remediation
- 📝 Change Management — Risk-controlled change processes
- 🏷️ Classification Framework — Business impact and risk assessment
- 🛡️ Secure Development Policy — DevSecOps requirements
📋 Document Control:
✅ Approved by: James Pether Sörling, CEO
📤 Distribution: Public
🏷️ Classification:
📅 Effective Date: 2026-03-18
⏰ Next Review: 2027-03-18
🎯 Framework Compliance:
Effective: 2026-04-24 · Authoritative hub:
analysis/imf/README.md·analysis/imf/agentic-integration.md·analysis/imf/indicators-inventory.json·analysis/imf/data-dictionary.md·.github/aw/ECONOMIC_DATA_CONTRACT.md
| Asset | Preservation strategy | Rationale |
|---|---|---|
analysis/imf/indicators-inventory.json |
Archived in final analysis/ snapshot; mirrored to Internet Archive |
Schema documents what we cached |
analysis/imf/data-dictionary.md |
Archived; mirrored | Reproducibility of vintage interpretation |
analysis/imf/agentic-integration.md |
Archived; mirrored | Reproducibility of integration pattern |
Vintage-tagged IMF cache (analysis/daily/*/economic-data.json) |
Preserved in full in archival snapshot | Provenance integrity — never delete |
economicProvenance blocks in articles |
Preserved (immutable) | Article-level audit trail |
| SHA-256 cache pin index | Preserved | Integrity verification post-sunset |
The IMF data licence (attribution required, redistribution permitted) survives platform sunset. Archived IMF-cached data may be redistributed by successor projects provided the IMF attribution remains intact.
Future maintainers inheriting Riksdagsmonitor receive:
- The vintage-tagged IMF cache (full historical depth at sunset moment)
- The
scripts/imf-*.tsruntime (reusable in any TypeScript context) - The IMF integration playbook (
agentic-integration.md) - The IMF threat model (
THREAT_MODEL.md§IMF +FUTURE_THREAT_MODEL.md§IMF)
This enables a successor to either continue IMF integration immediately or migrate to a different economic-data provider (with full provenance for the data they inherit).
Canonical rule. Every economic claim in a Riksdagsmonitor article cites an IMF dataflow first; World Bank citations are reserved for governance, environment and social residue (the classes IMF does not publish). SCB is the Swedish-specific ground truth layer. See ECONOMIC_DATA_CONTRACT.md v2.1 for the banned-phrase list and vintage discipline (>6 mo → annotation).
| 🌐 Platforms | 📦 Open-Source Projects | 🛡️ Governance & Standards |
|---|---|---|
|
🗳️ Riksdagsmonitor — Swedish Parliament intelligence 🇪🇺 EU Parliament Monitor — European coverage 🕵️ Citizen Intelligence Agency — political-data engine 🌐 Hack23 AB — corporate site 📰 Hack23 Blog — engineering & policy 💼 Hack23 on LinkedIn |
🗳️ Hack23/riksdagsmonitor 🕵️ Hack23/cia 🇪🇺 Hack23/euparliamentmonitor 🔌 Hack23/european-parliament-mcp ✅ Hack23/cia-compliance-manager 🥋 Hack23/black-trigram 🏠 Hack23/homepage |
🛡️ Hack23 ISMS-PUBLIC — public ISMS 🔒 Information Security Policy 🤖 AI Policy 🧪 Secure Development Policy 🎯 Threat Modeling Policy 🏷️ Classification Framework |
🗳️ Empower citizens · 🔍 Strengthen democratic accountability · 🕵️ Illuminate the political process
© 2008–2026 Hack23 AB (Org.nr 559534-7807) · Maintainer: James Pether Sörling, CISSP CISM