I spent the better part of three weekends building a complete Wardley Map diagram type for mermaid-js, the popular text-to-diagram library. It was thorough. It was modular. It was tested. And by the time I opened the PR, someone else had already merged theirs.
Here’s what happened, and why I’d do it all again.
Why Wardley Maps?
If you’re not familiar, Wardley Maps are strategy diagrams created by Simon Wardley. They plot components of a value chain along two axes: visibility (how visible something is to the user) and evolution (how mature something is, from genesis to commodity). They’re incredibly useful for making build-vs-buy decisions, understanding technology landscapes, and communicating strategic positioning.
There’s no great text-based way to create them. OnlineWardleyMaps exists but it’s a standalone tool. Mermaid supports dozens of diagram types (flowcharts, sequence diagrams, Gantt charts, radar diagrams) but Wardley Maps had been an open feature request since 2020, labeled “Approved” and “Contributor needed.”
So I built it.
What I Built
The implementation covered the full Wardley mapping standard:
- Component types: standard circles, anchor diamonds, market double-circles, ecosystem triple-circles
- Edge types: dependency, flow, and constraint links with annotations
- Evolution arrows: dashed arrows showing where components are heading, with optional rename support
- Pipelines: horizontal bars grouping sub-components along the evolution axis
- Inertia indicators: visual bars showing resistance to change
- Build/buy/outsource badges: sourcing strategy indicators on components
- Notes and annotations: numbered callouts and freestanding text
- PST overlays: pioneers/settlers/town planners area shading
- Custom axis labels: configurable evolution stage names
The architecture followed mermaid’s own patterns closely. A Langium grammar with 19 parser rules, a modular renderer split into 6 focused files, proper integration with mermaid’s theme system across all five themes, and schema-driven configuration with no hardcoded fallbacks.
90 tests. Zero regressions across mermaid’s full 3,772-test suite. Every feature visually verified in the browser.
The Plot Twist
When I went to open the PR against upstream, GitHub told me there were merge conflicts. Not the “someone edited a shared config file” kind. The “someone merged an entirely different implementation of the same feature” kind.
While I was polishing, the mermaid maintainers had merged a Wardley Map implementation into develop. Different architecture, different syntax, different coordinate system. That’s open source. Sometimes you’re building the same thing in parallel without knowing it.
I closed my PR.
What I Took Away
The work wasn’t wasted. Here’s why:
I understand Wardley mapping deeply now. Not just the syntax, but the semiotics. Why anchors are different from components, what inertia really means in a mapping context, how pipelines represent evolutionary spread. Building a renderer for something forces you to understand it at a level that reading about it never does.
I understand mermaid’s architecture. Langium grammars, Chevrotain lexers, the theme variable pipeline, how getConfig() flows from schema to render time. Next time I contribute to mermaid, there’s zero ramp-up.
The code quality bar was right. No fallbacks, modular renderer, comprehensive tests, proper theme integration. That’s the standard I want to hold for anything I put into open source.
Claim the work early. This is the obvious tactical lesson. I should have filed an issue before spending three weekends on it. I knew this. I just got excited and dove in.
What’s Next
There are other diagrams that don’t exist in mermaid yet. Cynefin frameworks, for one. Zero issues, zero PRs, zero existing work. And unlike Wardley Maps, there’s no standard text DSL for Cynefin diagrams anywhere. That’s a genuine first-mover opportunity.
But this time, I’m filing the issue first.
The code lives on the feature/wardley-map-diagram branch if anyone wants to see what a thorough mermaid diagram implementation looks like.