Skip to content
Español

0014. Icon packs, project assets and the asset lock

Status: accepted (icons-and-assets change, 10 October 2026)

icon "<pack>:<name>" was accepted but nothing drew it. The proposal asks for icons referenced by stable names or by aliases of installed packs, with optical scale, margins and position next to the label normalised, and measured before layout. It also asks the catalog to keep the version, origin and licence of every collection, for provider icons to keep their own terms, and for fonts to carry distribution and embedding permissions. Projects hold assets/icons/, assets/fonts/, assets/licenses.json and assets.lock.json, and imported SVG must be sanitised and size-limited.

  • A host-neutral package, @meltemi/diagrams-assets, holds the parts: icon packs, an SVG sanitiser built on a small strict XML reader, path geometry, the lock format and a portable SHA-256.

  • The built-in pack is Tabler (@tabler/icons 3.48.0, MIT), read from its node JSON. Filled variants take a -filled suffix. Hosts without a file system pass the same JSON through a reader.

  • Project packs are Iconify JSON files (assets/icons/<prefix>.json) or SVG folders (assets/icons/<prefix>/). project.json maps aliases to packs.

  • The sanitiser keeps an allow-list:

    • shapes, groups and transforms;
    • local linear and radial gradients;
    • paint, opacity and fill rule;
    • limited style.

    It refuses scripts, external references, DTDs and the other elements, and enforces size and complexity limits. Shapes become path data, so renderers only draw paths.

  • Normalisation is per pack. Each pack’s median content share of the view box is scaled to Tabler’s 20 of 24 units, and icons stay centred on their own grid. Per-icon content centring is not used, because it unbalances grid-designed icons.

  • Icons sit left of or above the text (iconPosition, a token and a style property), before group titles, tag and note text, and in relation label pills. Boxes and overflow checks count them. Monochrome icons take iconColor or the text colour.

  • Every project pack and font needs a licence, from its own metadata or assets/licenses.json, with a redistribute flag for provider terms.

  • Fonts in assets/fonts/ join a project’s font library. OS/2 fsType restricted embedding keeps a font for measurement only.

  • assets.lock.json records versions, sources, licences and integrity hashes. When it exists, drift is a warning, which --strict turns into a failure.

  • Project compilation checks icon references when the host provides asset services: unknown packs and icons are errors at the written value.

  • Bundling Iconify’s full collection: not approved for download, mixed licences, and megabytes of JSON for the few icons a diagram uses.
  • <use> or <image> references in the SVG: not portable to office applications, and external references are refused by the proposal.
  • Normalising each icon to its own content box: breaks the balance of icons designed on a grid.
  • Hashing assets on every run without a lock: the lock is opt-in, so projects that do not pin assets pay nothing.
  • ProjectHost gains readBinary, and memory hosts accept bytes.
  • The scene gains radial gradients, gradient units and transforms, and path transforms, opacity and fill rule; the renderer writes them.
  • Corpus fonts are generated by test-support/synthetic-font.ts (CC0), so no third-party font file is added for tests.
  • Icons of one’s own are added from the editor as a project pack, with its licence and its library entry, since decision 0054.