Flora: A Diagram Library Built with (and for) AI

jillcates1 pts0 comments

Introducing Flora ๐ŸŒฑ: A Diagram Library Built With (and For) AI

Sign in<br>Subscribe

Ten days ago, I started building a diagram library from scratch. Today I'm releasing Flora โ€“ a fault-tolerant, Mermaid-compatible diagram library that renders polished, interactive SVGs from imperfect input. I want to talk about Flora, but I also want to talk about how it got built, because the process surprised me more than the product.<br>Why another diagram library?<br>As a data engineer, a big part of my job is designing architecture. Before any data pipeline gets built, there's a diagram: how data flows, where it lands, what talks to what. Diagrams are how I think, and how I convince other people my thinking is sound.<br>In this AI-native world, Mermaid has become the lingua franca of diagrams-as-code โ€“ it's what LLMs write, it's what renders on GitHub, and it's been my tool of choice for the past couple of years. I love the core idea: diagrams as markdown text. They live in the repo, get reviewed in pull requests, and never rot in someone's abandoned Lucidchart account. But two things kept bugging me.<br>First, the aesthetics. Every time I wanted a diagram to look a specific way โ€“ consistent colours across a doc site, a cylinder that doesn't squish its label โ€“ I hit a wall. A colleague built a diagram design tool that produced genuinely beautiful output, but everything was hardcoded SVG. Change one node and you're regenerating the whole thing. I had traded Mermaid's declarative superpower for aesthetics, and I missed it immediately.<br>Second, and this one snuck up on me: LLMs write Mermaid constantly โ€“ it's become the default way AI tools express diagrams. And they get it almost right. One malformed line, and Mermaid throws a parse error and your UI renders a blank box. If diagrams-as-text is the interface between AI and humans now, the renderer shouldn't fall over when the text is 95% correct.<br>That's Flora: Mermaid's syntax, better output, and a parser that bends instead of breaking.<br>What it looks like<br>Flora understands the flowchart syntax you already write:<br>flowchart LR<br>events[[Kafka: events]] --> enrich[Enrichment]<br>enrich --> wh[(Snowflake)]<br>wh --> dash([Dashboard])<br>Here's that pipeline with the default theme:

Same text, sketch theme โ€“ for when you want "whiteboard draft," not "final architecture":

Diagrams are interactive out of the box: zoom, pan, and my favourite feature โ€“ click any node to trace its lineage upstream and downstream. Try it - click a node below:

(and if it doesn't work for you, please submit a github issue ๐Ÿ˜‰)<br>Fault tolerance was the design decision I cared most about. When Mermaid hits a line it can't parse, it throws โ€“ and you get a blank box, even if the diagram is 40 lines long and 39 of them are fine. Flora skips the line it can't understand, renders everything else, and reports what it skipped as a diagnostic with a line number. Just as importantly, it never guesses: a malformed line gets dropped and flagged, not reinterpreted into nodes you didn't write. If you'd rather fail loudly โ€“ in CI, say โ€“ strict: true throws instead of rendering best-effort.<br>There are a few avenues to use Flora, depending on where you work:<br>JavaScript/TypeScript : npm install @topspinj/flora gives you the full API<br>Plain HTML, no build step : the CDN bundle registers a web component โ€“ drop a script tag on any page and write diagrams as markup.<br>React : a wrapper component if that's your stack (and judging by what LLMs reach for when you ask them to build a frontend, it's everyone's stack now)<br>Markdown docs : a rehype plugin renders Flora code fences at build time โ€“ and fails the build on broken diagrams by default.<br>Python/Jupyter : pip install florajs for Jupyter/marimo notebooks and headless SVG export<br>Blogs and platforms without scripts : the hosted /embed route works anywhere an iframe does โ€“ Ghost, Substack, Notion. Every diagram in this post is one!<br>Web browser (no install at all) : the playground renders live and encodes diagrams in shareable URLs ๐Ÿ™Œ<br>Building this thing: GitHub issues as prompts<br>Here's the part I actually want to reflect on. I don't really write TypeScript. My career technically started in React and NodeJS, but that was ten years ago โ€“ I've lived in Python and SQL ever since. Before this project, I had never published an npm package, set up a TypeScript build, or thought hard about parser design. Ten days in, I've done all three โ€“ and the Python wrapper went from empty directory to published on PyPI in under 30 minutes.<br>The workflow that made it click was GitHub issues as prompts . Instead of writing issues for future-me or hypothetical contributors, I wrote issues with the intention that an agent will pick it up. In The Case for Professional Pseudocoding, I argued that turning messy intent into precise specs is becoming the core of the job. This project was that idea taken to its logical conclusion. Not:<br>parser is broken<br>but:<br>A line the parser can't understand should be skipped whole and reported as a...

flora diagram diagrams mermaid renders write

Related Articles