---
title: 'diagram-scene v2026.10.0: a laid-out diagram as plain data'
url: https://www.grahambrooks.com/post/diagram-scene-first-release/
date: 2026-10-14T06:10:43-06:00
author: Graham Brooks
description: diagram-scene v2026.10.0 is the first release of a Rust library that describes a laid-out software diagram as data, so layout engines and painters stop being coupled to each other.
tags:
- diagrams
- rust
- developer-tools
- personal-software
---

# diagram-scene v2026.10.0: a laid-out diagram as plain data

*A diagram that has been laid out is just data: boxes with sizes, lines with routes, colours that mean something. Nothing about that requires the code that drew it to be the code that displays it.*

**diagram-scene** is a small Rust library for engineers who build diagram tooling. It defines a `Scene`, a laid-out software diagram expressed as data, so that a layout engine can produce one and any number of painters can draw it. I wrote it because my own diagram tools were each carrying their own idea of what a diagram is. This is the first release, v2026.10.0, tagged on 13 October 2026. It's the project's first post too, so there's nothing earlier to link.

Today the producers and consumers are all mine. [`mmd`](https://github.com/grahambrooks/mmd) lays out Mermaid (flowcharts, git graphs, C4 context). [`puml`](https://github.com/grahambrooks/puml) lays out PlantUML (sequence, class, activity, state). [`forge`](https://github.com/grahambrooks/forge) lays out its architecture views. On the painting side, the emx editor paints scenes natively in its own theme, and `svg::to_svg` writes them as SVG.

## What's in the first release

There's one commit of substance, `c49b080`, 14 files and 3,822 inserted lines, plus an MIT license added in `c84f52c`. Since there's no previous release, "what changed" is really "what exists".

**A scene describes meaning, not primitives.** Nodes carry a shape, a stereotype, a label, a sublabel and badges. The shape list is long: rect, rounded, stadium, circle, ellipse, diamond, hexagon, cylinder, person, actor, component, package, queue, cloud, fork bars, and tables and classes with compartments, among others. Containers are drawn under the nodes and cover groups, subgraphs, C4 boundaries, deployment nodes, trust zones, swimlanes, sequence fragments with their guards, and lifelines. Edges arrive with their paths already routed, a pen (solid, dashed or dotted, thin to heavy), a marker at each end (including UML hollow triangles and diamonds, and crow's feet for each cardinality), labels and step numbers.

**Colours are roles, not values.** A scene refers to things like background, surface, text, line, accent, person, system and database, and a theme resolves them. So you lay a diagram out once and paint it in any theme. The exception is a colour that the diagram's own source sets explicitly, which stays concrete as `Paint::Rgb`. For SVG there are `Theme::light()` and `Theme::dark()`.

**The drawing rules live in one place.** This is the part I care about most. If every painter reimplements how a hexagon is outlined or where an arrowhead sits, they drift apart. The library exposes the rules instead: `shape::outline` for each shape's paths, `shape::text_layout` for where a node's text goes, `shape::natural_size` for how big a node needs to be for its text, and `shape::marker` for the end of an edge. For layout engines there's `route`, which clips to outlines, does straight, orthogonal (rounded) and spline routes, and places labels. For painters that can only draw straight segments or convex fills, there's `flatten`.

**Two features.** `svg` is on by default and writes SVG using presentation attributes and no CSS. `measure` is optional: `measure::FontMeasure` shapes text with the font you supply, so boxes fit the font they'll be drawn in. It pulls in `rustybuzz` (0.20) and nothing else. The default build has no dependencies at all.

## Seeing it

The repository has a gallery example that renders every shape and marker in light and dark:

```console
$ cargo run --example gallery -- /tmp
```

It uses `resvg` as a dev-dependency only.

## Installing and upgrading

This is the awkward part. The README has no install section, and `Cargo.toml` sets `publish = false`, so it isn't on crates.io. The README's only command is the gallery one above, run from a clone of https://github.com/grahambrooks/diagram-scene. The crate declares `rust-version = "1.98.1"` and pins the toolchain in `rust-toolchain.toml`. Other projects depend on it from git, pinned to a release tag; for this release that's `diagram-scene = { git = "https://github.com/grahambrooks/diagram-scene", tag = "v2026.10.0" }`, which is how mmd, puml and forge take it.

There's nothing to upgrade from, since this is the first tag.

## What to make of it

This is a single commit's worth of evidence, and it hasn't yet been tested by anyone but me. The honest claim is narrow: the model is large enough to cover Mermaid, PlantUML and forge's views, per the README. I can't yet say how well it holds up as more painters arrive. Since then, mmd, puml and forge have all moved onto it: as of 1 November each depends on diagram-scene v2026.10.25.
