Skip to the content.

Software Bill of Materials (SBOM)

Project: EyeMatics Clinical Demonstrator (EMD) — emd-app Application version: 1.20.3 Project license: MIT Generated: 2026-10-08 (v1.20.3, dependencies unchanged since v1.20.1 — plotly.js-dist-min → plotly.js-strict-dist-min, the CSP-safe build; the missing Plotly row added; Inter + JetBrains Mono self-hosted via Fontsource) Format: Human-readable Markdown SBOM derived from package.json + package-lock.json (lockfileVersion 3) and per-package license fields. Replaces: the earlier point-in-time BOM.md (v1.9.3, removed). SBOM.md is the canonical, maintained software bill of materials going forward. Runtime: Node.js ≥ 22 · npm ≥ 10 · ECMAScript modules ("type": "module") Container image: ghcr.io/okohlbacher/eyematics-emd-app — base node:24-bookworm-slim (Debian 12, glibc), built from Containerfile (v1.20)

⚠️ Research & development prototype — not a medical device. No PHI; all shipped data is synthetic.

Maintenance policy

This SBOM MUST be updated at the end of each phase and before every release. Whenever dependencies are added, removed, or version-bumped (any change to package.json / package-lock.json), regenerate the tables below and bump the Generated date. The end-of-phase verification and the pre-release checklist both include an “SBOM current?” gate.

Summary

Metric Value
Direct production dependencies 24
Direct development dependencies 26
Total installed packages (incl. transitive) 640
License distribution (direct deps) MIT ×44 · OFL-1.1 ×2 · ISC ×2 · BSD-3-Clause ×1 · Apache-2.0 ×1
Copyleft / restrictive licenses none for code — the two font packages are OFL-1.1 (bundling with any software permitted; obligations apply only to modified fonts)

All direct dependency licenses are OSI-approved permissive licenses compatible with the project’s MIT license. No GPL/AGPL/LGPL or other copyleft obligations are present in the direct dependency set.

Production dependencies

Package Declared range Resolved License
@fontsource-variable/inter ^5.3.0 5.3.0 OFL-1.1
@fontsource-variable/jetbrains-mono ^5.3.0 5.3.0 OFL-1.1
@tailwindcss/vite ^4.2.4 4.2.4 MIT
bcryptjs ^3.0.3 3.0.3 BSD-3-Clause
better-sqlite3 ^12.9.0 12.9.0 MIT
compression ^1.8.1 1.8.1 MIT
cookie-parser ^1.4.7 1.4.7 MIT
express ^5.2.1 5.2.1 MIT
helmet ^8.1.0 8.1.0 MIT
html-to-image ^1.11.13 1.11.13 MIT
http-proxy-middleware ^3.0.5 3.0.5 MIT
js-yaml ^4.1.1 4.1.1 MIT
jsonwebtoken ^9.0.3 9.0.3 MIT
jwks-rsa ^3.2.0 3.2.2 MIT
lucide-react ^1.9.0 1.9.0 ISC
otplib ^12.0.1 12.0.1 MIT
plotly.js-strict-dist-min ^3.6.0 3.6.0 MIT
qrcode ^1.5.4 1.5.4 MIT
react ^19.2.4 19.2.5 MIT
react-dom ^19.2.4 19.2.5 MIT
react-router-dom ^7.14.2 7.14.2 MIT
recharts ^3.8.1 3.8.1 MIT
tailwindcss ^4.2.4 4.2.4 MIT
tsx ^4.21.0 4.21.0 MIT

Role notes (key components): express + helmet + compression + cookie-parser + http-proxy-middleware — backend HTTP/security/proxy; better-sqlite3 — audit log + refresh_sessions + saved-search storage; jsonwebtoken + jwks-rsa + bcryptjs + otplib + qrcode — auth (JWT/HS256, Keycloak JWKS prep, password hashing, TOTP 2FA); js-yaml — config/settings.yaml loading; react + react-dom + react-router-dom — UI; recharts — trajectory/outcome charts; tailwindcss + @tailwindcss/vite — styling; @fontsource-variable/* — self-hosted Inter / JetBrains Mono (no Google Fonts request — CSP + GDPR); lucide-react — icons; html-to-image — chart export; plotly.js-strict-dist-min — WebGL cohort trajectories (strict build: no new Function, so it runs under the production CSP); tsx — runs the uncompiled TypeScript server (node --import tsx server/index.ts), hence a production dependency since v1.20.

Development dependencies

Package Declared range Resolved License
@eslint/js ^9.39.4 9.39.4 MIT
@testing-library/react ^16.3.2 16.3.2 MIT
@types/better-sqlite3 ^7.6.13 7.6.13 MIT
@types/compression ^1.8.1 1.8.1 MIT
@types/cookie-parser ^1.4.10 1.4.10 MIT
@types/express ^5.0.6 5.0.6 MIT
@types/js-yaml ^4.0.9 4.0.9 MIT
@types/jsonwebtoken ^9.0.10 9.0.10 MIT
@types/node ^24.12.2 24.12.2 MIT
@types/qrcode ^1.5.6 1.5.6 MIT
@types/react ^19.2.14 19.2.14 MIT
@types/react-dom ^19.2.3 19.2.3 MIT
@types/supertest ^7.2.0 7.2.0 MIT
@vitejs/plugin-react ^6.0.1 6.0.1 MIT
eslint ^9.39.4 9.39.4 MIT
eslint-plugin-react-hooks ^7.1.1 7.1.1 MIT
eslint-plugin-react-refresh ^0.5.2 0.5.2 MIT
eslint-plugin-simple-import-sort ^13.0.0 13.0.0 MIT
globals ^17.5.0 17.5.0 MIT
jsdom ^29.0.2 29.0.2 MIT
knip ^6.6.2 6.6.2 ISC
supertest ^7.2.2 7.2.2 MIT
typescript ~6.0.3 6.0.3 Apache-2.0
typescript-eslint ^8.59.0 8.59.0 MIT
vite ^8.0.10 8.0.10 MIT
vitest ^4.1.5 4.1.5 MIT

Transitive dependencies

405 packages are installed in total (direct + transitive); the authoritative, fully-resolved set with integrity hashes is package-lock.json (lockfileVersion 3), which is committed to the repository and is the canonical machine-readable manifest. The tables above enumerate the direct dependencies; transitive packages are pinned transitively by the lockfile.

Notable considerations

How to regenerate

# Direct deps, resolved versions, and licenses (used to build the tables above):
npm ls --omit=dev --depth=0          # production direct deps
npm ls --depth=0                     # all direct deps
# License audit across the tree (optional tooling):
npx license-checker --summary        # or: npx @cyclonedx/cyclonedx-npm --output-file sbom.cdx.json

For a standards-based machine-readable SBOM (CycloneDX/SPDX), generate alongside this file:

npx @cyclonedx/cyclonedx-npm --output-format JSON --output-file sbom.cdx.json

Sources of truth: package.json (direct deps) · package-lock.json (resolved + transitive, lockfileVersion 3). Update this file at the end of each phase and before release.