Guide
Editable diagrams with coding agents
Keep a diagram as a short JSON file your agent edits, checks, and re-renders to light and dark SVG, PNG, and tldraw, instead of drawing it again.
By HranessPublished
Drafted with AI from the source code and reviewed by Claude Opus 5.5.
A service gets renamed, and the architecture diagram in the docs has to change with it. If the diagram exists only as a PNG, or as a one-off picture a model generated, a coding agent has to draw it again from a new description, and the boxes, spacing, and colors can come out different from the last version. If it is hand-written SVG, the agent can change the one <text> node in place. That edit does not update the dark version, the PNG exports, or the tldraw file, and nothing checks whether a longer label still fits its box.
SlopCamera avoids that by making a small JSON file the diagram's source. The agent writes and edits that file. The slopcamera command checks it and renders the exports: a tldraw file, light and dark SVG, and light and dark PNG. A later change is a one-line JSON edit and a new render.
Write the diagram as source
A SlopCamera diagram is a .diagram.json file. It names the shapes, their labels and sizes, the arrows between them, and a layout. This source describes a four-step checkout path:
{
"version": 1,
"name": "checkout-architecture",
"canvas": { "width": 1400, "height": 360, "padding": 64 },
"layout": { "type": "stack", "direction": "horizontal", "gap": 140, "align": "center" },
"shapes": [
{ "id": "web", "type": "rect", "width": 200, "height": 140, "label": "Web app" },
{ "id": "api", "type": "rect", "width": 200, "height": 140, "label": "Checkout API" },
{ "id": "queue", "type": "rect", "width": 200, "height": 140, "label": "Order queue" },
{ "id": "db", "type": "rect", "width": 200, "height": 140, "label": "Orders DB" }
],
"edges": [
{ "id": "web-api", "from": "web", "to": "api" },
{ "id": "api-queue", "from": "api", "to": "queue" },
{ "id": "queue-db", "from": "queue", "to": "db" }
]
}
The stack layout places the boxes in array order with a fixed gap, so the file has no x or y coordinates to drift. Each shape has a stable id, which the edges refer to. A diagram with branches can use explicit positions instead; the diagram format reference covers both forms.
Keep this file in the repository, next to the page that uses it or in a diagrams/ directory. The SlopCamera skill follows the repository's existing layout and otherwise puts new sources at diagrams/<slug>.diagram.json. Treat everything rendered from the source as generated output.
Check before you render
slopcamera diagram check checkout.diagram.json --strict
The check does two things. First it validates the file. A shape tone outside the seven supported names (neutral, blue, orange, green, red, purple, yellow), or a stack wider than the canvas, stops with exit code 1 and a message that names the problem. An earlier draft of this diagram, on a 1280px canvas with a 120px gap, failed with:
slopcamera: Invalid stack layout:
- horizontal stack needs 1160px but only 1152px remain inside 64px padding
Then it lints the layout for problems a reader would notice. The lint checks cover labels longer than 32 characters, arrow labels longer than 24 characters, boxes smaller than 120 by 64 pixels, text that likely overflows its box, boxes that sit outside the canvas, arrows shorter than 96px, two arrows sharing one connector point, and more than nine primary shapes. The overflow check estimates text width from label length and font size; it does not measure the rendered text. With --strict, any finding sets exit code 2. Without --strict, the check prints its findings and still exits 0. When the second box was labeled "Checkout API and payment session handler", the check reported:
[long-label] api has a 40-character label; prefer a short noun phrase
That exit code is what makes the loop work for an agent. It can edit the JSON, run the check, read the finding, and edit again until the check is clean, without anyone opening an image. The same exit codes let you run the check in continuous integration. If CI runs it with --strict on each diagram source, a pull request that fails the check, including an estimated label overflow, fails the build.
Render the exports
slopcamera diagram render checkout.diagram.json
The render uses the document's name for its filenames and writes five files beside the source:
checkout-architecture.tldrcheckout-architecture.light.svgandcheckout-architecture.dark.svgcheckout-architecture.light.pngandcheckout-architecture.dark.png
The light and dark versions come from the same source, so a docs site that switches themes shows the same diagram in both. The .tldr file opens in tldraw if someone wants to sketch on top of it. SlopCamera writes that file but does not read it back, so changes made in tldraw do not reach the JSON. Make lasting changes in the source.
To keep several diagrams consistent, put a slopcamera.config.* file beside the sources, or pass one with --config. It sets the font, named icons, and light and dark theme colors the diagrams render with. A JSON config is only read as data. A TypeScript or JavaScript config runs as code with your user's access.
Change one label
When the orders database moves to Postgres, the whole revision is one line:
- { "id": "db", "type": "rect", "width": 200, "height": 140, "label": "Orders DB" }
+ { "id": "db", "type": "rect", "width": 200, "height": 140, "label": "Postgres" }
Run the check and render again. All five exports are replaced, and the other three boxes, the arrows, and the spacing stay where they were because nothing in the source moved them. When this example was rendered twice from the same source on one Mac, the two sets of files were byte-identical. Other machines can produce different bytes, because system fonts and rendering libraries vary.
This is where an installed tool pays off for an agent. Without a source file, the agent must describe the whole diagram again and hope the new drawing matches the old one. With one, it reads a short JSON file, changes a field, and runs two commands. The layout rules, the lint checks, and the light and dark variants are handled by the CLI instead of being redone in each reply.
Use Mermaid for diagrams read on GitHub
Mermaid diagrams are text inside a Markdown code block, and GitHub renders them in issues, pull requests, discussions, wikis, and Markdown files. For a sequence diagram in a pull request description, or a flowchart in a README that should update whenever someone edits the Markdown, Mermaid is simpler. There is nothing to install, nothing to render, and the diff a reviewer sees is the diagram's source. Many documentation site generators render Mermaid blocks too.
SlopCamera adds four things. Shape sizes, gaps, and order come from the source file. The light and dark PNG and SVG files are built ahead of time, so they work where no Mermaid renderer runs, such as slides, social images, and email. One config file sets the font, icons, and theme for many diagrams, and each render also writes a tldraw file.
The cost is generated files. In this example each SVG was about 197 KB. About 192 KB of that is the regular and bold Nebula Sans font files, which the default render embeds in each SVG as base64, so most of each SVG is the font, not the diagram. Each PNG was about 34 KB. A diff of those files is not readable, so review the JSON change, then look at the new PNG.
Use it from an agent
Install SlopCamera and its agent skill:
bun add --global https://github.com/hraness/slopcamera/releases/download/v3.9.2/hraness-slopcamera-3.9.2.tgz
slopcamera skill install --target agents
For Claude Code, install the skill with slopcamera skill install --target claude instead; the Claude Code tutorial covers that setup.
The skill tells the agent to look for an existing .diagram.json on the same subject before creating a new one, to update that source rather than edit a generated image, and to keep labels to a few words. Agents that use MCP instead of a shell can run the same two steps with the check_diagram and render_diagram tools. Those tools use the built-in icons and themes and do not read a slopcamera.config.* file, and the check returns its findings instead of an exit code. The first diagram tutorial walks through the same loop with the starter file from slopcamera diagram init. The techniques reference lists the other diagram techniques, and Why SlopCamera explains why the agent writes source instead of drawing.
What the checker does not catch
The linter checks geometry, not meaning. It cannot tell whether an arrow points the right way or whether a box should exist. Someone still needs to look at the rendered PNG before it ships. The diagram format covers rectangles, ellipses, text, lines, and labeled arrows, with optional icons; it is not a general drawing tool, and a diagram with more than nine primary shapes draws a lint finding that suggests a higher-level view.
The install steps use release 3.9.2.