Introducing Flora 🌱: A Diagram Library Built With (and For) AI
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.
Why another diagram library?
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.
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.
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.
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.
That's Flora: Mermaid's syntax, better output, and a parser that bends instead of breaking.
What it looks like
Flora understands the flowchart syntax you already write:
flowchart LR
events[[Kafka: events]] --> enrich[Enrichment]
enrich --> wh[(Snowflake)]
wh --> dash([Dashboard])
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 😉)
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.
There are a few avenues to use Flora, depending on where you work:
- JavaScript/TypeScript:
npm install @topspinj/floragives you the full API - Plain HTML, no build step: the CDN bundle registers a
<flora-diagram>web component – drop a script tag on any page and write diagrams as markup. - 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)
- Markdown docs: a rehype plugin renders Flora code fences at build time – and fails the build on broken diagrams by default.
- Python/Jupyter:
pip install florajsfor Jupyter/marimo notebooks and headless SVG export - Blogs and platforms without scripts: the hosted
/embedroute works anywhere an iframe does – Ghost, Substack, Notion. Every diagram in this post is one! - Web browser (no install at all): the playground renders live and encodes diagrams in shareable URLs 🙌
Building this thing: GitHub issues as prompts
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.
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:
parser is broken
but:
A line the parser can't understand should be skipped whole and reported as a diagnostic with line and column. Never reinterpreted as extra nodes. Everything valid should still render. Add regression tests with malformed fixtures.
The issue tracker became the communication protocol. I'd queue up issues in the evening, and working through them the next day felt less like prompting and more like assigning tickets to a very fast colleague.
Then Fable showed up
On Wednesday night, an email landed in my inbox: Claude Fable 5 is now available.

Normally I'd file a model announcement away to look at "later." But this time I had a live project mid-flight – a real codebase, a groomed backlog of agent-ready issues, and a perfect excuse to see what the new model could do. Two hours after the email arrived, Fable had shipped Flora's React wrapper.
Roughly half of Flora's commit history landed in the 48 hours since. The CDN bundle, the web component, parser diagnostics, strict mode, the Python package, the hosted playground: all of it in 2 days.
But speed isn't the interesting part. Fable caught bugs I never asked it to look for, and it pushed back on my ideas. When I tried to give themes control over node spacing, it argued that a theme should change how a diagram looks, never how it's arranged (and it was right). It felt less like autocomplete and more like code review – the kind where you lose the argument and you're glad you did.
v0.1 is out 🌱
It's still early – there are rough edges, and the issue tracker is honest about them.
The best part? I get to dogfood this immediately. One of the perks of my job is that we're free to use open source tools – there's no mandated diagramming stack – so Flora is going straight into my day-to-day work. Nothing stress-tests a library like real use cases, and I'll report back on how it holds up.
If you've ever loved Mermaid but wished it looked better and broke less, give Flora a try.
Until next time ✌️