Skip to content

Technical documentationInternal

For the team and anyone taking the product over. Not linked from the site and not indexed.

Technical documentation pages

Dependencies and licences

This page lists every npm dependency and development dependency, the browser engines served from public/vendor/, code and data ported from third-party projects, the fonts and other assets, and the build-time Python, R and Blender tools, each with its licence as the repository records it. It also documents the licence check in scripts/licences.mjs, the notices file written by scripts/notices.mjs, the exceptions held for the General Counsel, and what the current state would mean for commercial shipping.

Current state, as checked on 10 October 2026

Two commands were run in the repository with node_modules installed:

npm ls --depth=0 exited 0 and listed the 26 direct packages at the versions in the tables below. It also listed six packages as extraneous: @emnapi/core@1.10.0, @emnapi/runtime@1.11.3, @emnapi/wasi-threads@1.2.1, @img/sharp-wasm32@0.35.5, @napi-rs/wasm-runtime@1.2.2 and @tybys/wasm-util@0.10.3. They are installed but not reachable from package.json on this platform. In package-lock.json, @img/sharp-wasm32 is an optional dependency of @img/sharp-freebsd-wasm32 and @img/sharp-webcontainers-wasm32, both platform-restricted. Its declared licence is Apache-2.0 AND LGPL-3.0-or-later AND MIT.

node scripts/licences.mjs --json exited 0 with "findings": []. Its summary:

Part Result
Production closure 259 packages; 3 by exception: @img/sharp-libvips-linux-x64@1.3.4, @img/sharp-libvips-linuxmusl-x64@1.3.4, caniuse-lite@1.0.30001806
Development closure 345 packages; reported, not refused: axe-core@4.12.1 (MPL-2.0), caniuse-lite@1.0.30001806 (CC-BY-4.0), lightningcss@1.32.0, lightningcss-linux-x64-gnu@1.32.0 and lightningcss-linux-x64-musl@1.32.0 (MPL-2.0), minimatch@10.2.6 (BlueOak-1.0.0)
Vendored browser builds 3
GPL or academic-only tools named in the registry Blender 5.2 (bpy 5.2.2) and Molecular Nodes (Cell, build-time); primer3-py 2.3.1 (Sequence, oracle); R 4.3.3, drc 4.0-0 and MASS 7.3-60.0.1, and R 4.4.3 in the oracle image for the 0.5.0 cross-checks (Assay, oracles)

Licence distribution of the production closure, computed with the script's own walkClosure("dependencies"): MIT 230, Apache-2.0 10, ISC 7, BSD-3-Clause 5, LGPL-3.0-or-later 2, (MIT AND Zlib) 2 (pako 2.2.0 via 3dmol, and pako 1.0.11 via upng-js, itself a 3dmol dependency), Python-2.0 1 (argparse 2.0.1 via molstar and js-yaml), CC-BY-4.0 1 (caniuse-lite, via next and browserslist), 0BSD 1 (tslib 2.8.1).

The development closure: MIT 291, Apache-2.0 22, ISC 15, BSD-2-Clause 7, MPL-2.0 4, BSD-3-Clause 2, Python-2.0 1, CC-BY-4.0 1, CC0-1.0 1, BlueOak-1.0.0 1.

The production closure counts every package reachable from dependencies, not only code that reaches the browser. For example, molstar declares express, compression, cors, swagger-ui-dist, h264-mp4-encoder, react-markdown and others for its own command-line and server tools. The suite serves only Mol*'s prebuilt viewer, but those packages are walked, checked and listed in the notices file.

Runtime dependencies

package.json dependencies, with the installed version, the licence declared in the package's package.json, and where the code uses it.

Package Range in package.json Installed Licence Purpose Where used Reaches the browser
next 16.3.8 16.3.8 MIT Framework, build, routing, next/font, next/og, image optimisation Whole app Yes
react, react-dom 19.2.8 19.2.8 MIT UI Whole app Yes
@floating-ui/dom 1.8.0 1.8.0 MIT Positioning of popovers and menus src/components/suite/overlay/floating.ts Yes
@rdkit/rdkit 2026.3.6 2026.03.6 BSD-3-Clause RDKit.js WebAssembly chemistry engine Served from public/vendor/rdkit@2026.3.6/ and loaded with importScripts in src/components/suite/engines/rdkit/rdkit.worker.ts; client code imports only its types; Node tests and src/apps/education/experiments/applied/build-molecules.mjs load the package directly Yes, as a vendored build
molstar 5.11.0 5.11.0 MIT Mol* 3D viewer Served from public/vendor/molstar@5.11.0/; loaded by src/components/tools/protein-explorer/molstar-view.tsx and src/components/tools/inside-a-cell/molstar-viewer.tsx Yes, as a vendored build
3dmol 2.5.5 2.5.5 BSD-3-Clause 3Dmol.js conformer viewer Served from public/vendor/3dmol@2.5.5/; loaded by src/apps/molecule-workbench/panels/shape-panel.tsx Yes, as a vendored build
openchemlib 9.25.0 9.25.0 BSD-3-Clause Structure editor, conformers, MMFF94s+ Dynamic import("openchemlib") in src/components/tools/molecule-workbench/structure-editor.tsx; conformer.worker.ts; the developer kit Yes, bundled
uqr 0.1.3 0.1.3 MIT QR codes as inline SVG src/components/tools/lab-calculators/panels/label-dialog.tsx Yes, bundled
fuse.js 7.5.0 7.5.0 Apache-2.0 Fuzzy matching src/lib/literature/search/concepts.ts, saved-papers.ts Yes, bundled
fast-xml-parser 5.11.2 5.11.2 MIT Europe PMC full-text XML; the .pzfx project file in Assay's Import src/lib/literature/fulltext.ts; src/lib/grid/pzfx.ts Server for literature; in the browser for Assay, loaded on demand when a .pzfx file is chosen
marked 18.0.14 18.0.14 MIT Rendering the technical documentation src/lib/technical-docs/render.ts No (server)
@supabase/ssr ^0.12.7 0.12.7 MIT Account sessions with cookies src/lib/workspace/server.ts No (server)
@supabase/supabase-js ^2.117.2 2.117.2 MIT Service-role client src/lib/workspace/server.ts No (server)
stripe ^23.0.0 23.0.0 MIT Billing src/lib/workspace/billing.ts, src/app/api/workspace/billing/checkout/route.ts No (server)
server-only ^0.0.1 0.0.1 MIT Build fails if a server module is imported by a client component Imported by src/lib/workspace/server.ts, billing.ts, src/lib/search/catalog-server.ts, src/lib/technical-docs/load.ts, src/components/suite/marketing/landing-education.marketing.tsx No

Notable transitive packages: sharp 0.35.5 (Apache-2.0, an optional dependency of next) with its platform binaries @img/sharp-linux-x64 and @img/sharp-linuxmusl-x64 (Apache-2.0) and the libvips binaries @img/sharp-libvips-* (LGPL-3.0-or-later). These serve Next's image optimisation, which the suite uses through next/image (for example src/components/tools/inside-a-cell/still.ts and src/components/suite/marketing/poster.marketing.tsx).

Development dependencies

Package Range Installed Licence Purpose
@playwright/test 1.56.1 1.56.1 Apache-2.0 Browser tests under e2e/
axe-core 4.12.1 4.12.1 MPL-2.0 Accessibility checks injected by e2e/support/axe.ts
eslint ^9 9.39.5 MIT Linting
eslint-config-next 16.3.8 16.3.8 MIT Next's lint rules
typescript ^5 5.9.3 Apache-2.0 Type checking (npx tsc --noEmit)
tailwindcss ^4 4.3.3 MIT CSS
@tailwindcss/postcss ^4 4.3.3 MIT PostCSS plugin; brings lightningcss (MPL-2.0)
@types/node ^20 20.19.43 MIT Node types
@types/react ^19 19.2.18 MIT React types
@types/react-dom ^19 19.2.4 MIT React DOM types

The development tools never ship. Tailwind's output is CSS the suite writes from its own classes; lightningcss runs at build time.

Version pinning policy

What the repository does, as found:

  • Twelve of the sixteen runtime dependencies are pinned to an exact version. The four with caret ranges are @supabase/ssr, @supabase/supabase-js, server-only and stripe. Of the development dependencies, @playwright/test, axe-core and eslint-config-next are exact; the rest use caret ranges.
  • package-lock.json (lockfile version 3) fixes every installed version. Every GitHub workflow installs with npm ci. There is no .npmrc and no Dependabot or Renovate configuration.
  • The three vendored engines must be pinned exactly: scripts/vendor.mjs throws "pin <pkg> to an exact version in package.json" otherwise, and src/lib/vendor.test.ts asserts that vendorVersions in src/lib/vendor.ts equals the package.json pins. Since Wave 4, bundledVersions in the same file records OpenChemLib (9.25.0), which is bundled rather than vendored; the test checks it against package.json, the installed package, OpenChemLib's runtime version and every "OpenChemLib JS x.y.z" in content/tools/molecule-workbench.ts. RDKIT_VERSION (src/components/tools/molecule-workbench/versions.ts) is checked against vendorVersions by policy.test.ts. The version is part of the served path (/vendor/<name>@<version>/), so a new release is a new URL and can be cached as immutable.
  • EXCEPTIONS in scripts/licences.mjs is keyed by name@version. A version change of an excepted package makes the check report the new version as not on the allow-list, and the old key as "an exception names a package that is not installed; remove it" (unless the old key is an optional package for another platform in the lockfile). caniuse-lite changes version often, so updating next or browserslist usually needs this entry updated.
  • engines.node is >=22.18 and .nvmrc is 22.18, while @types/node is ^20.

When an engine version changes, these places name the version in text and are not checked against package.json by any test found: the registry source names (Mol* 5.11.0 in content/apps/protein-explorer.ts and content/apps/inside-a-cell.ts, and in the cspAllowances reasons; RDKit and RDKit.js 2026.03.6, 3Dmol.js 2.5.5 in content/apps/molecule-workbench.ts; RDKit.js 2026.03.6 in content/apps/assay-analyser.ts; uqr 0.1.3 in content/apps/lab-calculators.ts); _version in public/data/molecule-workbench/ocl-resources.json; painsSource in src/components/tools/molecule-workbench/pains-data.ts; and the RDKit pin in .github/workflows/scheduled.yml and pipeline/molecule-workbench/rdkit_reference.py, which refuses any other release.

Vendored browser builds

scripts/vendor.mjs exports a packages list and, when run as the main script (npm run vendor, run by predev and prebuild), copies each build and its licence text into public/vendor/<name>@<version>/. It deletes copies of other versions. public/vendor/ is gitignored. Build, test and CI covers the build hook.

Name Package Files copied Licence text served as LICENSE.txt Exposes
molstar molstar build/viewer/molstar.js, build/viewer/molstar.css The package's LICENSE (MIT, "Copyright (c) 2017 - now, Mol* contributors") window.molstar
rdkit @rdkit/rdkit dist/RDKit_minimal.js, dist/RDKit_minimal.wasm scripts/licenses/rdkit-LICENSE.txt (BSD 3-Clause, Rational Discovery LLC, Greg Landrum, Julie Penzotti and others), because the npm package ships no licence file; the comment says it is copied from the Release_2026_03_6 tag. Also scripts/licenses/inchi-LICENSE.txt, served as INCHI-LICENSE.txt, for the InChI code compiled into the WebAssembly initRDKitModule
3dmol 3dmol build/3Dmol-min.js, build/3Dmol-min.js.LICENSE.txt The package's LICENSE (BSD-3-Clause) window.$3Dmol

The paths are built in src/lib/vendor.ts (vendor.molstarJs, vendor.rdkitWasm and so on). The /vendor/:path* header rule caches them as immutable (Security and network). Mol* also needs 'unsafe-eval' and data: in connect-src in the apps that load it; RDKit needs 'wasm-unsafe-eval' (Security and network).

The registry records InChI (MIT, "Copyright (c) 2024 InChI Project") as bundled in RDKit.js (content/apps/molecule-workbench.ts, source inchi). RDKit's Release_2026_03_6 builds it from InChI's v1.07.3 source archive (INCHI-1-SRC.zip, named with its MD5 in RDKit's Code/cmake/Modules/FindInchi.cmake), and the WebAssembly names "InChI version 1, Software 1.07.3 (API Library)". scripts/licenses/inchi-LICENSE.txt holds, verbatim, the repository's LICENSE at tag v1.07.3, the MIT notice in the header of every source file RDKit compiles ("Copyright (c) 2024 IUPAC and InChI Trust") and the separate MIT notice of INCHI_BASE/src/sha2.c (Paul Bakker), each read on 17 October 2026 from the archive whose MD5 matched RDKit's (comment markers removed; the provenance is in BUNDLED_NOTICES in scripts/lib/licence-texts.mjs). The text is served beside the vendored build as INCHI-LICENSE.txt and written into public/third-party-notices.txt. Whether the minimal RDKit build bundles other third-party code with its own notice requirements is not checked by any script.

Third-party code and tables inside the suite's own files

What File Origin and licence as recorded
QED src/components/tools/molecule-workbench/qed.ts TypeScript port of RDKit's rdkit/Chem/QED.py (Release_2026_03_6). The file keeps Novartis's BSD-3-Clause notice in full. public/tools/molecule-workbench/qed-notice.txt repeats it and is linked from the Molecule source list
PAINS filters src/components/tools/molecule-workbench/pains-data.ts Generated by pipeline/molecule-workbench/rdkit_reference.py pains from RDKit's FilterCatalog (Code/GraphMol/FilterCatalog/pains_*.in); header names the RDKit BSD-3-Clause licence and points to /third-party-notices.txt
OpenChemLib conformer and MMFF94 tables public/data/molecule-workbench/ocl-resources.json Copied from openchemlib's dist/resources.json by pipeline/molecule-workbench/copy-ocl-resources.mts; _licence: "BSD-3-Clause", _version: "9.25.0", and a _notice naming cheminfo's copyright
Genetic code tables src/lib/seq/codes-data.ts Built by pipeline/sequence-toolkit/build-codes.mts from NCBI gc.prt 4.6 (public domain, NCBI)
Helvetica, Helvetica-Bold and Symbol widths (Stage A) src/lib/figure/afm-widths.ts Generated by pipeline/assay-analyser/figure/afm_widths.py from Adobe's Core 14 AFM files (Helvetica.afm, Helvetica-Bold.afm, Symbol.afm, 1997), vendored unmodified with Adobe's MustRead.html in pipeline/assay-analyser/figure/afm/ (fetched on 12 October 2026 from the Apache PDFBox repository; SHA-256 in the generated header). MustRead permits use, copying and distribution with or without modification provided the copyright notices are kept, the AFM files travel with it, modifications are noted and its paragraph is unchanged; the generated file repeats the notices and the paragraph verbatim and says what was extracted. Minified bundles drop comments, so the shipped table carries no notice; whether that meets the terms, and "Helvetica" and "Symbol" as names in copy, are held for the General Counsel (CTO's ruling 7). The generator uses pypdf 6.17.0's Adobe Glyph List (BSD-3-Clause) at build time only and cross-checks the widths against pypdf's core-font metrics
The viridis colour map (Stage A, the figure editor's heatmaps) src/lib/figure/viridis.ts Generated by pipeline/assay-analyser/figure/viridis_ts.py from pipeline/assay-analyser/fixtures/figure/viridis-table.json: the 256 entries of _viridis_data in matplotlib 3.9.2's lib/matplotlib/_cm_listed.py (fetched 13 October 2026; the file's SHA-256 in the fixture). CC0-1.0: "New matplotlib colormaps by Nathaniel J. Smith, Stefan van der Walt, and (in the case of viridis) Eric Firing ... released under the CC0 license / public domain dedication" (github.com/BIDS/colormap, colormaps.py and LICENSE.txt, read the same day); credit is asked, not required, and is given in the generated file's header
BLOSUM62 (Wave 4) src/lib/protein/align/blosum62.ts Generated by pipeline/protein-explorer/blosum62.py from NCBI's BLOSUM62 file (stored with its sha256), checked against Biopython 1.88's copy; no licence recorded; redistribution terms held for the General Counsel (D-0055)

Engines written from published methods with GPL tools used only as oracles (four-parameter logistic fitting, Tm and secondary structure, restriction digests) are described on Oracles and verification; src/lib/fit/index.ts states that nothing is ported from drc.

The licence check

scripts/licences.mjs is the "dependency-licence test" (design system §11.7; the board memo of 5 October 2026; charter §6). It runs five checks and returns findings; npm run check-licences exits 1 on any. It runs:

  • under npm test, through scripts/licences.test.mjs (eleven tests, two of which check the notices file's output: see The third-party notices file);
  • in the CI check job, after npm test and before npm run build;
  • with --release, which also measures licence read dates against today (the release gate); --json prints findings and the summary.

Check 1: the production closure

walkClosure("dependencies") (in scripts/lib/licence-texts.mjs, shared with the notices writer and re-exported by scripts/licences.mjs) walks package.json dependencies, then each package's dependencies and the optionalDependencies npm installed, Node-style through node_modules, one entry per name@version. For each:

  • The licence field must be an SPDX expression that the allow-list satisfies (spdxSatisfies: OR passes if any side is allowed, AND needs both, WITH is read as its left side, an unparseable expression never passes), or the package must have an EXCEPTIONS entry whose licence equals the declared one.
  • A copyleft licence (COPYLEFT: GPL, LGPL, AGPL, SSPL, BUSL, EUPL) is never covered for shipped code: its exception must say serverOnly: true, and if .next/static exists the check fails when any .js or .map file there contains node_modules/<name>/.
  • A licence text must travel with the package: a file named licence, license, copying or notice (with optional .md, .txt or .markdown), or a LOCAL_LICENCES entry whose file exists (licenceTextPath, the same lookup the notices writer uses to write the text), unless a server-only exception says textNotRequired.
  • Every EXCEPTIONS key must be installed, unless the lockfile holds it as an optional package for another platform.

Check 2: the development closure

The same walk over devDependencies. A package fails only if it has no licence field, or a copyleft, UNLICENSED or SEE LICENSE IN licence with no alternative in the allow-list or in MPL-2.0, BlueOak-1.0.0, CC-BY-4.0 or BSD-2-Clause. Other non-allow-listed licences are reported, not refused. Licence texts are not required. The header records the CEO's rule as "nothing GPL in dependencies or devDependencies".

Check 3: the vendored builds

For each entry in scripts/vendor.mjs packages: installed, licence on the allow-list, and each licence text source present.

Check 4: the source scan

Every .ts, .tsx, .mts, .mjs, .js and .json file under src/ and content/ except tests is matched against SOURCE_PATTERNS: GPL licence headers ("GNU General/Lesser General/Affero General Public License", "free software; you can redistribute it and/or modify", "under the terms of the GNU") and the identifiers of GPL or academic-only tools whose code must never be ported (primer3, oligotm, libprimer3, Sequence Manipulation Suite, SMS2, EMBOSS, pLannotate, CRISPOR). SOURCE_EXEMPT lists four files where a mention is legitimate, each with its reason (CTO ruling and CSO rulings of 6 October 2026):

File Reason (summarised)
content/apps/sequence-toolkit.ts excludedSources and oracles name Primer3, SMS2, EMBOSS and CRISPOR as excluded or never run
content/tools/sequence-toolkit.ts The write-up names each method's oracle, Primer3's ntthal among them
content/apps/sequence-toolkit.docs-entries.ts The methods page's definitions (moved verbatim from sequence-toolkit.docs.ts for the methods and checks dialog, D-0085) state the conventions "as Primer3's thal, inferred from its output"
content/apps/sequence-toolkit/structure.ts The hairpin and dimer cards name Primer3 as the oracle that reports a different structure

Check 5: the registry

Described on Data sources: a sourceMeta per source, a decision or display-only flag for any no-reuse-licence source, an https:// terms page per endpoint, licence pages read within READ_WITHIN_DAYS = 365 of the reference date, and no duplicate hosts.

The listing of GPL and academic-only tools

toolListing() lists every registry oracles entry whose licence matches GPL, academic or non-commercial, and every source with licenceId: "GPL-3.0-or-later-buildtime". It reads only the registry, so the Education pipeline's Blender and Molecular Nodes, which have no registry entry, are not listed.

The allow-list, additions and exceptions

ALLOWED is the board memo's list: MIT, BSD-2-Clause, BSD-3-Clause, Apache-2.0, ISC, 0BSD, CC0-1.0, Unlicense.

ALLOWED_ADDITIONS, each recorded for the General Counsel's sign-off:

Id Why it is needed Held for Since
Zlib pako (via 3dmol, directly and through upng-js) is MIT AND Zlib General Counsel (D-0010) 2026-10-05
Python-2.0 argparse (via molstar's command-line entry, never in the vendored viewer) General Counsel (D-0010) 2026-10-05

EXCEPTIONS, each with decision: null:

Package Licence Reason (registry wording, summarised) Server only Text Since
caniuse-lite@1.0.30001806 CC-BY-4.0 Browser-support data Next.js requires at build time; data, not code; attribution in the notices file No Ships its own licence file 2026-10-05
@img/sharp-libvips-linux-x64@1.3.4 LGPL-3.0-or-later libvips binary for Next's image optimisation; server side only; not redistributed Yes textNotRequired: the package ships no licence file 2026-10-05
@img/sharp-libvips-linuxmusl-x64@1.3.4 LGPL-3.0-or-later As above, musl build Yes textNotRequired 2026-10-05
@img/sharp-libvips-darwin-arm64@1.3.4 LGPL-3.0-or-later macOS build of the same; not installed on Linux, kept because the lockfile holds it for darwin/arm64 Yes textNotRequired 2026-10-07

There is no separate deny-list: a licence the allow-list does not satisfy is refused unless an exception names the package. (An exported DENIED pattern that no check used was removed on 17 October 2026.)

LOCAL_LICENCES (in scripts/lib/licence-texts.mjs, re-exported by scripts/licences.mjs) gives the text for packages whose tarball has none: @nodable/entities and @rdkit/rdkit (files in scripts/licenses/), server-only (scripts/licenses/server-only-LICENSE.txt, MIT, Meta Platforms), and @next/env, @next/swc-linux-x64-gnu, @next/swc-linux-x64-musl, @next/swc-darwin-arm64 and client-only (pointed at node_modules/next/license.md).

The open-questions register (docs/board/open-questions.md, "Held for the General Counsel", 5 October 2026) records the two additions, the caniuse-lite exception and the three @img/sharp-libvips platform binaries (the darwin-arm64 exception of 7 October 2026 among them; the count was corrected from two on 17 October 2026), and that MPL-2.0 (axe-core, lightningcss) and BlueOak (minimatch) development tools are reported, not refused.

The third-party notices file

scripts/notices.mjs runs with npm run vendor (so before dev and build) and writes public/third-party-notices.txt, which is gitignored. Which text travels with what is recorded once, in scripts/lib/licence-texts.mjs, and both this writer and the licence check read it, so the file and the check cannot disagree about a package's text. The file has three parts:

  1. Packages. The same production closure as check 1 (walkClosure), in name@version order: ==== <name>@<version> (<licence>) followed by the package's licence file or its LOCAL_LICENCES text (licenceTextPath), or the line "No licence file is included in this package. Its package.json declares: <licence>." On 17 October 2026 the file lists 259 packages, and only the two installed libvips binaries carry that line, as their textNotRequired exceptions allow. (Until that day the writer kept its own two-entry copy of LOCAL_LICENCES, so server-only, client-only, @next/env, @next/swc-linux-x64-gnu and @next/swc-linux-x64-musl went out with the line although check 1 counted them as having a text.)
  2. Third-party code bundled inside the vendored builds (BUNDLED_NOTICES): InChI 1.07.3, compiled into RDKit_minimal.wasm, with the text in scripts/licenses/inchi-LICENSE.txt (see Vendored browser builds).
  3. Fonts (FONT_LICENCES): the four families src/lib/fonts.ts self-hosts, each with its SIL Open Font License 1.1 text (see Fonts).

scripts/licences.test.mjs checks the output: every package check 1 counts as having a text is written with it, the five packages above carry their MIT text, the InChI text names its three copyright holders and the vendored RDKit build carries it, and the font list equals the families src/lib/fonts.ts imports from next/font/google, so a new family without a recorded licence fails npm test. The registry links the file as "Third-party notices" (/third-party-notices.txt) beside RDKit, OpenChemLib, uqr and Assay's RDKit source; the InChI source entry in content/tools/molecule-workbench.ts has no such link.

The notices file does not include the licences of any third-party code the vendored builds bundle beyond InChI and what each npm package ships; no script checks the minimal RDKit build, the Mol* viewer or 3Dmol.js for other bundled code with its own notice requirement.

Build-time tools: Python, R and Blender

None of these is a dependency of the app. Each pipeline folder pins its Python packages in a requirements.txt and its README says to install into a virtual environment outside the tracked tree (Data pipeline). Licences are as recorded in the requirement comments, the registry oracles and sources, or the folder's README; "not recorded" means the repository does not state one.

Pipeline Requirements Licences as recorded Python Role
assay-analyser/requirements.txt numpy==2.4.6 BSD-3-Clause Not stated Seeded generator of synthetic curves and the MTT plate
assay-analyser/requirements-irls.txt scipy==1.17.0, numpy==2.3.5 BSD-3-Clause (registry for SciPy and NumPy) 3.12.14 Relative-weighting IRLS oracle
assay-analyser/reference.R R 4.3.3, drc 4.0-0, MASS 7.3-60.0.1, jsonlite 1.8.8; drc's dependencies car 3.1-2, gtools 3.9.5, multcomp 1.4-25, plotrix 3.8-4, sandwich 3.1-0, scales 1.3.0 (Ubuntu packages) R: GPL-2 or GPL-3; drc: GPL-2; MASS: GPL-2 or GPL-3; jsonlite: MIT; drc's dependencies: "GPL or MIT". reference.R itself is MIT and calls drc by its public API n/a Curve-fitting oracle
bioreactor-simulator/requirements.txt scipy==1.17.0, numpy==2.3.5 BSD-3-Clause 3.12.14 (PSF-2.0, registry) ODE oracle (solve_ivp Radau)
drug-pipeline-explorer/precedent/requirements.txt openpyxl==3.1.5, pypdf==6.19.0 Not recorded 3.12 in the snapshot workflow FDA precedent snapshots and fixtures
drug-pipeline-explorer/verify_stems.py (CI) pypdf, unpinned Not recorded 3.12 Weekly stem check
education/requirements.txt bpy==5.2.2, molecularnodes==520.2.0, nodebpy==520.27.0, biotite==1.7.1, numpy==2.5.3, scipy==1.18.1, imageio-ffmpeg==0.6.0, Pillow==12.3.0 bpy GPL-3.0-or-later and Molecular Nodes GPL-3.0-or-later (Cell's registry and README); Biotite, NumPy, SciPy BSD-3-Clause; nodebpy, imageio-ffmpeg and Pillow not recorded 3.13 Education posters, videos and scenes
inside-a-cell/requirements.txt numpy==2.5.3, scipy==1.18.1, biotite==1.7.1, bpy==5.2.2, molecularnodes==520.2.0 Blender binaries GPL-3.0-or-later (source GPL-2.0-or-later); Molecular Nodes GPL-3.0-or-later; others BSD-3-Clause 3.13 Trimmed structures and stills
lab-calculators/requirements.txt rdkit==2026.3.6, numpy==2.4.6, biopython==1.85 BSD-3-Clause; Biopython Licence Agreement (BSD-3-Clause file by file) 3.11 Calc oracles
molecule-workbench (README, no requirements file) rdkit==2026.3.6 BSD-3-Clause Not stated PAINS data, QED notice, reference fixtures, library comparison; since Wave 4 the fingerprint-policy and series oracles and pipeline/walks/nearest/walk_values.py
protein-explorer (no requirements file) Biopython 1.88 for align_reference.py and blosum62.py (version recorded, not enforced); standard library for the AlphaMissense and substitution oracles Biopython Licence Agreement or BSD-3-Clause (as recorded elsewhere) Not stated Wave 4 aligner and AlphaMissense oracles
plasmid-map/requirements.txt biopython==1.88 Biopython Licence Agreement or BSD-3-Clause 3.11 Plasmid oracles
sequence-toolkit/requirements.txt biopython==1.88, primer3-py==2.3.1 (bundles libprimer3 2.6.1), rdkit==2026.03.6 (for peptides.py) Biopython as above; primer3-py GPL-2.0-or-later; RDKit BSD-3-Clause 3.11.15 Sequence oracles; reference.py is MIT
oracle-env/Dockerfile (the oracle image) R 4.4.3 (rocker/r-ver:4.4.3) on the CRAN snapshot of 2026-09-30 with drc, car, chemCal, investr, outliers, multcomp, mvtnorm, jsonlite, MASS and survival; CPython 3.11.15 with five environments from the Assay, Sequence and Calc requirements files above (openpyxl 3.1.5 in the three Assay ones); MAFFT 7.526 (core only, built from source); EMBOSS 6.6.0 (Ubuntu package). Resolved versions in pipeline/oracle-env/R-packages.csv and python-packages.txt R and the R packages GPL (jsonlite MIT); MAFFT core BSD (its license file, read 12 October 2026; extensions not built); EMBOSS GPL; Python packages as above 3.11.15 Runs the Assay oracles (and is ready for Sequence and Calc) offline in Actions; never shipped (Rule G)

EMBOSS needle 6.6.0.0 (GPL) was run once, locally, for the protein aligner's cross-check (docs/science/evidence/protein-align-2026-10-11/). EMBOSS 6.6.0 is now also in the oracle image, for cai among others, as an offline oracle only. It is not in any registry oracles entry, so toolListing() does not list it, and the licence scan keeps its name out of src/ and content/.

Other offline tools named in the registry oracles: NCBI ORFfinder 0.4.3 (public domain, NCBI) and the Expasy ProtParam web form (SIB terms, "To be checked") for Sequence; Python fractions and decimal (Python-2.0 or PSF-2.0) for Calc, Sequence and Plasmid.

The pipeline notes record these rules for GPL tools: they run offline, their numbers are committed as fixtures with the tool, version and licence, and their code and parameter files are never copied into src/. pipeline/sequence-toolkit/README.md records that primer3_config files are never copied; pipeline/inside-a-cell/README.md and pipeline/education/README.md state that the GPL does not cover the rendered images and videos. The open-questions register holds the related items (Sequence naming GPL tools, Primer3 conventions, retention of R and drc output in evidence logs) for the General Counsel.

The scheduled and snapshot workflows install Python 3.12 (actions/setup-python@v5) whatever version a README names.

Fonts and other assets

Fonts

src/lib/fonts.ts loads four families through next/font/google:

Family Variable Options Licence
Inter --font-inter subsets: ["latin"], display: "swap" OFL-1.1
Bricolage Grotesque --font-bricolage subsets: ["latin"], display: "swap" OFL-1.1
IBM Plex Mono --font-plex-mono weights 400, 500, 600; subsets: ["latin"], display: "swap" OFL-1.1
Source Serif 4 --font-source-serif weights 400, 500, 600; subsets: ["latin", "latin-ext", "greek"] (Greek for subject names such as α-synuclein), display: "swap"; the workspace subject face and headline-answer face since D-0082 (13 October 2026) OFL-1.1

Next downloads the CSS and font files at build time and serves them from the site; its documentation states that the browser sends no requests to Google. The build therefore needs network access to Google Fonts. The CSP's font-src 'self' allows only these self-hosted files.

All four families are under the SIL Open Font License 1.1 (OFL-1.1). The licence of each, its text and where the text was read are recorded in FONT_LICENCES in scripts/lib/licence-texts.mjs, and the four texts are written into public/third-party-notices.txt (its "Fonts" part). Each text is the family's licence file copied byte for byte from the font's own repository on 17 October 2026:

Family Text in the repository Copied from Copyright line in that file
Inter scripts/licenses/inter-OFL.txt https://github.com/rsms/inter/blob/master/LICENSE.txt "Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)"
Bricolage Grotesque scripts/licenses/bricolage-grotesque-OFL.txt https://github.com/ateliertriay/bricolage/blob/main/OFL.txt "Copyright 2022 The Bricolage Grotesque Project Authors (https://github.com/ateliertriay/bricolage)"
IBM Plex Mono scripts/licenses/ibm-plex-mono-OFL.txt https://github.com/IBM/plex/blob/master/LICENSE.txt "Copyright © 2017 IBM Corp. with Reserved Font Name "Plex""
Source Serif 4 scripts/licenses/source-serif-4-OFL.txt https://github.com/adobe-fonts/source-serif/blob/release/LICENSE.md "Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. …"

The licence body of each file matches SIL's text (https://openfontlicense.org/documents/OFL.txt, read the same day) word for word, except that Inter's upstream copy heads one section "PERMISSION AND CONDITIONS" where SIL's reads "PERMISSION & CONDITIONS". The files next/font serves are Google Fonts' builds; Google's own OFL.txt for each family (github.com/google/fonts, ofl/<family>/OFL.txt, read the same day for comparison) has the same body, and names the copyright as "2020 The Inter Project Authors" for Inter and "2014 The Source Serif 4 Project Authors" for Source Serif 4 (the other two match upstream). scripts/licences.test.mjs fails if src/lib/fonts.ts imports a family that FONT_LICENCES does not list.

The design documents record the same licence: docs/design/prd-inside-a-cell.md (the asset table, with the intended credit line "Fonts: Inter, Bricolage Grotesque, IBM Plex Mono (SIL Open Font License 1.1).") and docs/design/build-spec-inside-a-cell.md, and the CPO memo of 13 October 2026 for Source Serif 4. That credit line is not in any content file and does not name Source Serif 4; OFL-1.1 exists as a LicenceId, but no registry source or export uses it.

Share images and the per-app icon are drawn with next/og ImageResponse (src/components/suite/marketing/og-card.marketing.tsx, src/app/(workspace)/[app]/icon.tsx) using fontFamily: "sans-serif", so they render with the font next/og supplies by default; its licence is not recorded in the repository.

Images, media and other files

Asset Origin Licence as recorded
src/app/favicon.ico, src/app/icon.svg The suite mark; last changed in commit 42e2437 ("Adopt the Bench mark across Drybench and Workspace") Not recorded; no third-party source named
public/data/inside-a-cell/stills/*.webp Rendered by pipeline/inside-a-cell/render.py with Blender and Molecular Nodes from CC0 PDB coordinates Coordinates CC0; tools GPL, stated as not covering the outputs
public/data/education/*-structure.webp, *-guide.mp4, *-guide.webm, structures/ Rendered by pipeline/education/molecular.py; FFmpeg crossfades and encodes (through imageio-ffmpeg) Coordinates CC0; FFmpeg's licence not recorded
public/media/landing/study-light.jpg, study-dark.jpg Added in commit e7f8080 ("Redesign landing around connected dry-lab workspace") Not recorded; no file in src/ or content/ references them
public/tools/molecule-workbench/qed-notice.txt Written by rdkit_reference.py pains Novartis BSD-3-Clause notice; its first line names the page as /molecule/app (the old /apps/molecule-workbench/app until 17 October 2026)
public/verification/<slug>/<version>/ Published oracle fixtures MIT where the registry records them (Assay, Plasmid, Bioreactor fixtures)
Product page posters (posterUrl in content/apps/routes.ts) /media/<slug>/preview.webp; no such files exist under public/media/, and the posters are drawn from the app mark until a file exists (AppEntry.preview comment) n/a

Data files and their licences are listed on Data sources.

What would need attention before commercial shipping

These are the facts the code and register record. Whether any licence permits sale is held for the General Counsel (D-0010) and checked at the pre-live pass (D-0014).

  • No GPL code ships. The production closure passes the allow-list with three recorded exceptions; the vendored builds are MIT and BSD-3-Clause; the source scan finds no GPL header or ported GPL tool. GPL tools (primer3-py, R, drc, MASS, Blender, Molecular Nodes) are build-time only. On the current record, no dependency needs a rewrite.
  • LGPL libvips binaries. The three @img/sharp-libvips-* exceptions rest on "server side only, never bundled for the browser". The check that enforces this needs .next/static and so does not run in CI, where the licence check runs before the build. If the exceptions were refused, the code that depends on them is Next's image optimisation behind next/image (Cell stills, marketing posters and the landing Education band). Whether to disable optimisation or change approach would be an engineering decision.
  • CC-BY-4.0 data in the toolchain. caniuse-lite is excepted as build-time data with attribution in the notices file.
  • Permissive additions. Zlib and Python-2.0 are allowed pending sign-off.
  • Notices. Since 17 October 2026 the notices file carries every package text the check counts, InChI's licence and the OFL text of the four self-hosted fonts. What remains is attribution, not code: the fonts' credit line is not in any content file, and no script checks the vendored builds for other bundled code with its own notice requirement.
  • Share-alike data. ChEMBL-derived data (the Molecule library and the public search catalogue) is a data-licence question (Q-03, Q-26), not a dependency question; see Data sources.

Gaps and divergences found

Finding Location
The copyleft browser-bundle assertion (inBrowserBundle) runs only when .next/static exists; CI runs the licence check before the build, so it never runs there, and locally it reads whatever build is present scripts/licences.mjs (inBrowserBundle, checkProduction); .github/workflows/ci.yml (check job)
The fonts' credit line in docs/design/prd-inside-a-cell.md ("Fonts: Inter, Bricolage Grotesque, IBM Plex Mono (SIL Open Font License 1.1).") is not in any content file and does not name Source Serif 4; the licence texts themselves are in the notices file docs/design/prd-inside-a-cell.md:117,308; scripts/lib/licence-texts.mjs (FONT_LICENCES)
The InChI source entry in the Molecule source list links no "Third-party notices", although its text is in the notices file content/tools/molecule-workbench.ts (source "InChI (bundled in RDKit.js)")
@img/sharp-wasm32 (Apache-2.0 AND LGPL-3.0-or-later AND MIT) is installed as extraneous; on FreeBSD or WebContainers, where it would be reachable, no exception covers it package-lock.json; scripts/licences.mjs EXCEPTIONS
toolListing() and check 5 read only the registry, so the Education pipeline's GPL build tools are not listed scripts/licences.mjs (toolListing); pipeline/education/requirements.txt
Engine versions are typed in registry source names and data files with no test tying them to package.json See Version pinning policy
@types/node is ^20 while the engine floor is Node 22.18 package.json
The weekly stems job installs pypdf unpinned .github/workflows/scheduled.yml
The licences of openpyxl, pypdf, nodebpy, imageio-ffmpeg (and the FFmpeg binary it supplies) and Pillow are not recorded The pipeline requirements.txt files

Closed on 17 October 2026 (the enterprise review's housekeeping track, F1): the notices writer's two-entry copy of LOCAL_LICENCES (now one shared record, scripts/lib/licence-texts.mjs), the unused DENIED export (removed), InChI's missing licence text (now beside the vendored build and in the notices file), the fonts' missing OFL text (now in the notices file; DAT-09 in Known issues), the register's count of two libvips exceptions (now three) and qed-notice.txt's old Molecule address (now /molecule/app, in the file and in rdkit_reference.py, which writes it).

Adding or upgrading a dependency

  1. Prefer a package under a licence in ALLOWED. A GPL dependency, or a feature built on one, means a rewrite at the pre-live pass, so say so when proposing it.
  2. For a heavy engine, load it on demand and serve it with its licence text: add it to packages in scripts/vendor.mjs with an exact pin and to vendorVersions in src/lib/vendor.ts, and declare any CSP allowance it needs in the app's dataPolicy.cspAllowances with the reason.
  3. If its tarball has no licence file, add the text under scripts/licenses/ and an entry in LOCAL_LICENCES in scripts/lib/licence-texts.mjs, which both the check and the notices writer read. Third-party code compiled inside a vendored build goes in BUNDLED_NOTICES there, and a new web font in FONT_LICENCES.
  4. A licence outside the allow-list needs an EXCEPTIONS entry keyed by name@version with licence, reason, heldFor and since, and an entry in the open-questions register's held list.
  5. Update the version wherever it is typed in text (see Version pinning policy), and the registry source if the app lists the library as a source.
  6. Run npm run check-licences, npm test and npm run build, then look at the generated public/third-party-notices.txt.