{"slug": "show-hn-anyone-else-frustrated-with-mermaid-diagrams", "title": "Show HN: Anyone else frustrated with mermaid diagrams?", "summary": "A tool called ablauf, published as the npm package @uberblick/ablauf by uberblick.ai, renders diagrams from a small text format in which the author fixes every element's position, producing deterministic themed SVG rather than using Mermaid's automatic layout. The package requires Node.js 22.18 or newer, ships compiled JavaScript and TypeScript declarations with no runtime dependencies, and its render(source, options?) function returns { svg, diagnostics, layout }, reporting source problems with one-based line numbers while still producing SVG. Ablauf supports two diagram kinds, routed flows and standalone outcome fan-outs, both at v0, and offers no automatic layout and no Mermaid import or export; its author states that \"if you need Mermaid's breadth, Mermaid is the better choice.", "body_md": "A small text format for diagrams that agents write and people read, rendered as deterministic, themed SVG.\n\nThe author decides where everything goes, the way they would draw the figure by hand. The text records those decisions, so another agent can read and edit the diagram without looking at the picture. The renderer sizes the grid and draws; it never moves anything, and it reports every problem with its line number.\n\nThe kinds are routed flows and standalone outcome fan-outs; both formats are\nv0. See them on [ablauf.uberblick.ai](https://ablauf.uberblick.ai).\n\nWe started with Mermaid, and the first version of ablauf was a Mermaid\nsubset. Mermaid lays a diagram out automatically, which makes it quick to\nwrite. For the documents we work on we wanted the author to decide where each\nstep sits and which side each edge leaves and enters, so that a small edit to\nthe text leaves the rest of the picture where it was. Edges are still spelled\nlike Mermaid's (`-->`, `: label`), because agents already know that spelling.\n\nablauf is much narrower than Mermaid: two kinds, flows and fan-outs, no\nautomatic layout and no Mermaid import or export. If you need Mermaid's\nbreadth, Mermaid is the better choice. The\n[motivation page](https://ablauf.uberblick.ai/motivation) has the longer\nstory.\n\nThe playground puts an editor beside the live render and lists each problem\nwith its line number; click one to jump to it. It switches between light and\ndark and between a bare page and a 710 px document column, and it opens every\nexample in this repository. In a checkout, with [mise](https://mise.jdx.dev):\n\n```\nmise trust && mise run setup\nmise run playground\n```\n\nThen open [http://localhost:4620](http://localhost:4620). Rendered examples of both kinds are on\n[ablauf.uberblick.ai](https://ablauf.uberblick.ai).\n\nRequires Node.js 22.18 or newer. The package ships compiled JavaScript and TypeScript declarations, with no runtime dependencies or TypeScript loader required. Its public entry point is an ES module.\n\nInstall it in your project:\n\n```\nnpm install @uberblick/ablauf\n```\n\nSave this as `render-flow.mjs`:\n\n``` js\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { render } from \"@uberblick/ablauf\";\n\nconst [input, output] = process.argv.slice(2);\nif (!input || !output) {\n  console.error(\"Usage: node render-flow.mjs input.flow output.svg\");\n  process.exit(2);\n}\n\nconst source = await readFile(input, \"utf8\");\nconst { svg, diagnostics } = render(source, {\n  idPrefix: \"build-flow\",\n  scheme: \"light\",\n});\nawait writeFile(output, svg);\n\nfor (const { line, severity, message } of diagnostics) {\n  console.error(`${input}:${line} ${severity}: ${message}`);\n}\n// Keep the SVG for inspection, but fail the build on any source problem.\nprocess.exitCode = diagnostics.length ? 1 : 0;\n```\n\nRun it with a flow file and the desired output path:\n\n```\nnode render-flow.mjs diagram.flow diagram.svg\n```\n\n`render(source, options?)` returns `{ svg, diagnostics, layout }`. Source\nproblems return diagnostics with one-based `line`, `severity` and `message`\nfields while still producing SVG. Invalid caller options can throw.\n`idPrefix` defaults to `\"ab\"`; supply distinct prefixes for diagrams sharing\na page. Omit `scheme` to follow the system theme, or pin it to `\"light\"` or\n`\"dark\"`. The existing `fonts` option accepts host font families and synchronous\nwidth metrics; see [host fonts and width metrics](https://github.com/uberblick-ai/ablauf/blob/main/docs/plan.md#host-fonts-and-width-metrics).\nTypeScript consumers can import `RenderOptions`, `Diagnostic`, `FontOptions`,\n`FontsOptions` and `TextStyle` from the same entry point. `LIGHT` and `DARK`\nexport the default palettes.\n\n```\nflow v0\ncolumns fix main manual\n\npill push col=main tone=muted \"push to main\"\nbox build \"compile and package\"\nbox test \"unit and integration tests\"\nbox staging \"deploy to staging\"\nbox smoke \"smoke tests\"\nbox production \"deploy to production\"\nend live \"Live\"\n\npill failed col=fix row=test tone=rework \"checks failed\"\nbox rollback col=fix row=production tone=rework \"restore the last release\"\npanel approve col=manual row=smoke tone=stop\n  strong \"Release manager\"\n  muted \"approves the release\"\n\npush --> build : on push\nbuild --> test\ntest --> staging : green\nstaging --> smoke\nsmoke --> approve tone=stop : passed\napprove --> production tone=stop from=bottom to=right label=end : approved\nproduction --> live : healthy\nbuild --> failed tone=rework to=top.2 : fails\ntest --> failed tone=rework : red\nfailed --> push tone=rework from=top.1 to=left label=end : fix and push\nproduction --> rollback tone=rework : unhealthy\n\nlegend\n  pill \"event or state\"\n  box \"automated job\"\n  panel \"manual step\"\n  edge tone=rework \"failure path\"\n```\n\n- `columns` names the columns left to right. Each node starts a new row unless`row=` puts it beside another node.\n- Nodes are `text` ,`pill` ,`box` ,`end` ,`panel` or`decision` , coloured by a tone.\n- Edges use Mermaid's arrows. `from=` and`to=` pick the sides an edge leaves\nand enters; each pair of sides has one fixed shape.\n- `legend` explains the shapes in fine print under the diagram.\n\n[spike/PRIMER.md](https://github.com/uberblick-ai/ablauf/blob/main/spike/PRIMER.md) is the full format on one page, and the\npage an agent reads before writing a flow.\n\nFor phone widths, [author separate wide and narrow layouts](https://github.com/uberblick-ai/ablauf/blob/main/docs/narrow-layouts.md).\nThe worked pair keeps the same content and lets the host select a readable SVG.\n\nFrom [spike/examples/checkout.flow](https://github.com/uberblick-ai/ablauf/blob/main/spike/examples/checkout.flow), with two\nsections:\n\nThe loop [ub-agents](https://github.com/uberblick-ai/ub-agents) runs on\nUberblick's repositories, from\n[spike/examples/loop.flow](https://github.com/uberblick-ai/ablauf/blob/main/spike/examples/loop.flow):\n\n`decision` asks a question over a small diamond, and `label=inline` sets each\nanswer into a gap in its edge. From\n[spike/examples/project-workflow.flow](https://github.com/uberblick-ai/ablauf/blob/main/spike/examples/project-workflow.flow):\n\nA `fan-out v0` diagram is one step and its ordered outcomes, each with a reason\nand a destination:\n\n```\nfan-out v0\nstep \"Check whether approval permits the run\"\n\noutcome \"Approved\" reason=\"A maintainer started it and the input is unchanged\" destination=\"Start the run\" tone=\"done\"\noutcome \"Outside input\" reason=\"The input has not been cleared by a maintainer\" destination=\"Ask a maintainer\" tone=\"stop\"\noutcome \"Edited since\" reason=\"The input changed after the maintainer started it\" destination=\"Ask a maintainer\" tone=\"stop\"\n```\n\nInline SVGs can follow a page's `data-theme=\"light\"` / `data-theme=\"dark\"`\nswitch through the existing `--ab-*` CSS properties, without rerendering.\nSee [host page themes](https://github.com/uberblick-ai/ablauf/blob/main/docs/theming.md) for the complete base and tone palette,\ncopyable host CSS and the difference between inline SVG and image embedding.\n\nYou need [mise](https://mise.jdx.dev). In a fresh checkout or worktree:\n\n```\nmise trust && mise run setup\n```\n\n| Command | What it does | \n|---|---|\n| `mise run setup` | Installs the pinned Node and pnpm and the locked dependencies. | \n| `mise run playground` | Serves the review page at [http://localhost:4620](http://localhost:4620) (another port if that one is busy). Open`#examples/loop` to see the loop beside its hand-drawn reference. | \n| `mise run check FILE` | Renders one `.flow` file to an`.svg` beside it and lists its problems with line numbers. | \n| `mise run render` | Renders every example to `spike/out/` and refreshes the figures in this README. | \n| `mise run site` | Builds [ablauf.uberblick.ai](https://github.com/uberblick-ai/ablauf/blob/main/site/README.md) into`site/out/` ;`mise run site-serve` serves it. | \n| `mise run measure` | Shows what moved between the loop and the loop with a role inserted. | \n| `mise run ci` | Lint, typecheck and tests, before you push. | \n\n`pnpm build` emits the package into `dist/`. `npm pack` builds it automatically.\nThe tests in `mise run ci` install the actual tarball with production dependencies\nonly in an isolated directory and exercise the public import and this build script.\n\n`mise tasks` lists everything. The plan is in [docs/plan.md](https://github.com/uberblick-ai/ablauf/blob/main/docs/plan.md), and\nthe spike's results in [spike/FINDINGS.md](https://github.com/uberblick-ai/ablauf/blob/main/spike/FINDINGS.md).\n\nMaintainers release an already-prepared version with `mise run release X.Y.Z`.\nStart with `mise run release X.Y.Z --check`; see [releases](https://github.com/uberblick-ai/ablauf/blob/main/docs/releases.md)\nfor trusted-publishing setup, confirmation and partial-release recovery.\n\nThe earlier Mermaid-subset version lives in\n[uberblick-ai/old-ablauf](https://github.com/uberblick-ai/old-ablauf).\n\nMIT", "url": "https://wpnews.pro/news/show-hn-anyone-else-frustrated-with-mermaid-diagrams", "canonical_source": "https://github.com/uberblick-ai/ablauf", "published_at": "2026-10-23 15:52:27+00:00", "updated_at": "2026-10-23 16:14:03.488347+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools"], "entities": ["ablauf", "uberblick.ai", "Mermaid", "@uberblick/ablauf", "Node.js 22.18", "mise"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-anyone-else-frustrated-with-mermaid-diagrams", "markdown": "https://wpnews.pro/news/show-hn-anyone-else-frustrated-with-mermaid-diagrams.md", "text": "https://wpnews.pro/news/show-hn-anyone-else-frustrated-with-mermaid-diagrams.txt", "jsonld": "https://wpnews.pro/news/show-hn-anyone-else-frustrated-with-mermaid-diagrams.jsonld"}}