Coauthor of D2 here. Lately I've been noodling on the idea of expanding the animation capabilities. I think out loud a bit here, and if you have thoughts, would love to hear them:
I know this is a big request, but lately I've been using LLMs to quickly draft and showcase architecture decision. I mainly fallback to mermaid, but I am curious if d2 would be more flexible? I usually endup visualizing anyway with drawio. I am curious if there are plans on creating a more user friendly interface (mcp, or tool calling feature) with llms.
First of all, thanks for your work on D2, it is the coolest of them all IMHO. I would definitely use animations because management loves shiny things and if they are happy I get my salary bumped.
I have recently made a solution for dynamically codifying the network layout of AWS accounts with D2. D2 was the only solution that was allowing to render a lot of objects without having to fight the engine with tons of hints. My only complaint was/is that the sdk/d2lib was very under-documented, so initially I started off with generating text as a map before realizing that there is a better way that is barely used. It took me some time to figure out how to use the lib for the trickier parts.
Hi Alixander! I started using D2 just a couple months ago -- the first time I had to design a system at work. I'm really happy with it -- I was amazed how easy it was to pick up.
TBH, I don't think these fancy animations are necessary. If I want to call attention to a certain box or arrow in the diagram, I would rather turn it red than have anything moving.
I think diagrams are opinionated. I’d like to show animations instead of just colors. Data flow for example. Yes arrows help, but animations help better. It is all about personal preference. There is no right or wrong.
What is the purpose of those animations? If I could use them in a presentation where I click through a diagram adding things as i click and their connections being animated for highlight then sure. I don’t really like the example where the text changes in you link, the whole diagram jumping around just because a text changes seems like something that would be annoying. So I guess you would need to render everything and keep some things hidden until activated?!
As a side not, I would love a proper Swimlane-diagram. I think you have all the building blocks with your ability to nest things in flowcharts, just need to force-align some boxes in different swimlanes and align the lanes themselves (and probably a lot more behind the scenes).
The purpose is to make use of a dimension of the visual space previously unused to make diagrams more expressive.
Even if it's something simple like a node turning from green to red to convey it's shutting down. Maybe something like that before animations would be a text saying, "this node will shut down now", which takes reading/zooming into text.
I also think it can, if used well, result in diagrams that ⋆⋆spark joy⋆⋆. People like to see diagrams like that, even if it's not more utilitarian. I think sketch mode is an example of this. It changes the font to an objectively less readable one, yet I often hear people make all their D2 diagrams in sketch mode.
I'm a bit surprised at the first "cool slop" example, I'd expect a "more tangible" (by way of animation) data flow visualization to be useful rather than fluff. Though since it's not dynamic (it's not based on live data or anything), maybe that's why it'd be superfluous?
On the example animation not all paths are taken, so that is one bit of extra information that the animation does provide. Though even if it was fully identical, I do find it considerably easier to see where the data is moving based on dots tracing out a path than I do by scanning for small arrows in a massive diagram, hence my confusion on this. Fair point though.
I have been looking at things like D2 and Penrose, trying to wrap Python around them to make it a bit easier to script up diagrams based on data.
Working through the problem I realize I probably would have a better time with something like Haskell but I do think the lower the barrier to entry is for drawing up stuff with these tools the more people will reach for programmatic diagramming to help debug and explain things.
The biggest problem with most of the declarative tools like D2,dot,mermaid etc is that they tend to not really offer "declare, then tweak" workflows. You can of course generate some SVG and then tweak it in Inkscape, but sometimes you just want to move something a bit after layout, constraints be damned.
Penrose makes that easier, at the cost of ... I guess everything else being weirder and randomized.
Looking at the syntax, I wonder how close one could get to it in a "normal" programming language.
x -> y: hello world
declares a connection between two
shapes, x and y, with the label,
hello world
When I read this, I see this Python line in my mind:
connect('x', 'y', 'hello world')
This is of course a lot longer. The reason is that D2 seems to rather use operators than functions. So another approach could be
'x' * 'y' + 'hello world'
This would be possible to implement if the language supports overloading the __add__ and __mul__ functions of the str class. Python does not support it though. So I guess one would have to put at least one instance of a custom class into the mix. Say 'scene', then one might be able to achieve the above with this line:
scene + 'x' * 'y' + 'hello world'
Meaning "Put a connection between x and y with label 'hello world' into the scene".
Hmm.. also not very close to the D2 syntax. So a DSL for diagrams seems to be warranted.
In Scala you can do it, because you can define your own operators (which are nothing but method names), and you can extend types you don't control. You are a bit constrained by the operator precedence rules, but it's usually good enough.
It's bad practice to make DSLs left and right, obviously. But when one is warranted, you can.
Not all "normal languages" (or even "dynamic scripting languages") are created equal. While I wouldn't want to aim for something equivalent to the whole d2 syntax as an internal DSL in Ruby, if you wanted to just create edges with optional labels with a syntax where "bare" edges are:
x >> y
and edges with labels are:
x >> y << "hello world"
you can do it like this:
class Diagram
def initialize
@nodes = Hash.new { |h, k| h[k] = Node.new(self, k) }
@edges = {}
end
def node(name)
@nodes[name]
end
def add_edge(edge)
@edges[edge.from_node] ||= {}
@edges[edge.from_node][edge.to_node] = edge
end
def all_edges
@edges.values.flat_map(&:values)
end
def interpret &block
interpreter = D2.new(self)
interpreter.instance_eval(&block)
self
end
def to_s
all_edges.map(&:to_s)
end
def inspect
to_s
end
end
class D2
def initialize(diagram = nil)
@diagram = diagram || Diagram.new
end
def method_missing(name, *args)
@diagram.node(name)
end
end
class Node
def initialize(diagram, name)
@diagram = diagram
@name = name
end
def >>(other_node)
Edge.new(self, other_node).tap do |edge|
@diagram.add_edge(edge)
end
end
def to_s
@name
end
def inspect
"Node(#{to_s})"
end
end
class Edge
def initialize(from_node, to_node, label = nil)
@from_node = from_node
@to_node = to_node
@label = label
end
def <<(label)
@label = label
end
def from_node
@from_node
end
def to_node
@to_node
end
def to_s
"#{@from_node.to_s} -> #{@to_node.to_s}" + (@label ? ":#@label" : "")
end
def inspect
"Edge(#{to_s})"
end
end
And use it like this:
irb(main):090:0> d = Diagram.new
=> []
irb(main):091:1* d.interpret {
irb(main):092:1* x >> y << "hello, world!"
irb(main):093:1* y >> z << "goodbye, cruel world!"
irb(main):094:0> }
=> ["x -> y:hello, world!", "y -> z:goodbye, cruel world!"]
OF course, this only supports a trivial subset of the functionality, and only "renders" it to a text form more like the original d2 syntax. But it does create an object model from the DSL in the Diagram class for which you could build a renderer.
In particular we'll have a DAG and then add nodes and edges to it, and then remove some and so on... It would be nice to visualize these changes. We currently use graphviz, but it's not "stable" so a diagram jumps around a lot when we look at snapshot to snapshot...
If (1) we could guarantee some kind of stability and (2) if we could even animate the transitions, that would be incredibly useful for visualization.
Love d2, using it for years. I use it whenever someone asks me to create a visualisation. And I regularly tell people about d2 trying to push it internally haha
Enterprise is way too expensive though. And I can't natively render it anywhere. So I'm limited to only personal use.
3000usd / year for a single TALA license is... Well, not justifiable. And I'm not sure how much d2 studio is on top...
I'd love to test TALA though, but even the personal license at 120usd is steep for drawing some stuff.
Just giving a helm chart or system description to an llm and having it one shot a perfect diagram which code I can easily view and edit is also a big gamechanger for me
Sucks to not have it just render natively anywhere, I think confluence cloud can do it. But I think the add on is a paid addon.
D2 has been around for a while (and has been posted here before) but still surprisingly unknown. It's so much better than mermaid – giving them a boost with this post!
last time i was installing mermaid with npm, noted that installation lasts too long. i checked and found that it is installing headless chrome under the hood...
I chose D2 as for our AI's "generate diagram" tool in https://zo.computer and it works quite well. I think the fact that D2 is more expressive than Mermaid is a useful property when doing AI-aided diagram generation.
D2 has a lot of merits but there’s little that sells it over PlantUML or Mermaid - I do feel like diagrams-as-code is still waiting for a killer program that makes everything else obsolete.
I’m forever chasing that dragon. In the meantime I still recommend D2 if PUML is feeling a bit stale.
- d2 is a standalone executable compiler, I once tried mermaid-cli (mmdc) but couldn't get it to work properly plus anything I need to install with npm scares the hell out of me
- ASCII rendering: I love rendering to ASCII which I can copy-paste around.
But I do use mermaid a lot embedded in other programs (e.g Obisidian). The selection of different diagram types is amazing.
I don't know exactly but none of the diagram building languages I've used have been a great experience. I guess they just feel "rough in the hands" somehow to me. There's always some point of frustration I get to with the layout systems. They're essential for quickly visualizing graph structures and such but even smaller hand authored ones end up feeling unwieldy too. Can't put it in to works but it feels like there could be a major improvement beyond what even D2 studio offers, when it comes to the language and workflow around it.
> I guess they just feel "rough in the hands" somehow to me.
I'd be curious to know if Ilograph is among the languages you've tried and if you feel the same way (I'm the author). Making it feel good to edit (the opposite of "rough in the hands"?) is an explicit goal, and to that end there is an IDE with context-aware autocomplete.
https://github.com/terrastruct/d2/discussions/2677
I have recently made a solution for dynamically codifying the network layout of AWS accounts with D2. D2 was the only solution that was allowing to render a lot of objects without having to fight the engine with tons of hints. My only complaint was/is that the sdk/d2lib was very under-documented, so initially I started off with generating text as a map before realizing that there is a better way that is barely used. It took me some time to figure out how to use the lib for the trickier parts.
TBH, I don't think these fancy animations are necessary. If I want to call attention to a certain box or arrow in the diagram, I would rather turn it red than have anything moving.
As a side not, I would love a proper Swimlane-diagram. I think you have all the building blocks with your ability to nest things in flowcharts, just need to force-align some boxes in different swimlanes and align the lanes themselves (and probably a lot more behind the scenes).
Even if it's something simple like a node turning from green to red to convey it's shutting down. Maybe something like that before animations would be a text saying, "this node will shut down now", which takes reading/zooming into text.
I also think it can, if used well, result in diagrams that ⋆⋆spark joy⋆⋆. People like to see diagrams like that, even if it's not more utilitarian. I think sketch mode is an example of this. It changes the font to an objectively less readable one, yet I often hear people make all their D2 diagrams in sketch mode.
The urge to add silly stuff like this vs working on v2 of sequence diagram that has much more demand is often tempting.
Working through the problem I realize I probably would have a better time with something like Haskell but I do think the lower the barrier to entry is for drawing up stuff with these tools the more people will reach for programmatic diagramming to help debug and explain things.
The biggest problem with most of the declarative tools like D2,dot,mermaid etc is that they tend to not really offer "declare, then tweak" workflows. You can of course generate some SVG and then tweak it in Inkscape, but sometimes you just want to move something a bit after layout, constraints be damned.
Penrose makes that easier, at the cost of ... I guess everything else being weirder and randomized.
https://docs.d2studio.ai/tour/freehand
Hmm.. also not very close to the D2 syntax. So a DSL for diagrams seems to be warranted.
The '-' sign is interpreted as a unary minus, which is simply discarded.
The '<' symbol is handled by the '__lt__' overload of the Node class.
The '|' operator has precedence over '<' in Python, so the edge label is stored in the right-hand side node.
That being said, I will haunt you if you actually use this in production.
It's bad practice to make DSLs left and right, obviously. But when one is warranted, you can.
For example here you could have
In particular we'll have a DAG and then add nodes and edges to it, and then remove some and so on... It would be nice to visualize these changes. We currently use graphviz, but it's not "stable" so a diagram jumps around a lot when we look at snapshot to snapshot...
If (1) we could guarantee some kind of stability and (2) if we could even animate the transitions, that would be incredibly useful for visualization.
If this is possible, I'd love to hear about it!
It's a hack but might be good enough.
And tool tips / links: https://d2lang.com/tour/interactive/
Those two make a huge difference for me.
Enterprise is way too expensive though. And I can't natively render it anywhere. So I'm limited to only personal use.
3000usd / year for a single TALA license is... Well, not justifiable. And I'm not sure how much d2 studio is on top...
I'd love to test TALA though, but even the personal license at 120usd is steep for drawing some stuff.
Just giving a helm chart or system description to an llm and having it one shot a perfect diagram which code I can easily view and edit is also a big gamechanger for me
Sucks to not have it just render natively anywhere, I think confluence cloud can do it. But I think the add on is a paid addon.
https://d2lang.com/examples/elk/
I like ELK's output better sometimes too, e.g. the Golang Queue example. Choice is good
[1] D2 (text to diagram tool) now supports ASCII renders:
https://news.ycombinator.com/item?id=44954524
In other words, you can have one D2 file that generates `step1.png,` `step2.png`, and `step3.png`. Useful for PowerPoint presentations!
Not my project but no need for an mcp I'd think
I’m forever chasing that dragon. In the meantime I still recommend D2 if PUML is feeling a bit stale.
- d2 is a standalone executable compiler, I once tried mermaid-cli (mmdc) but couldn't get it to work properly plus anything I need to install with npm scares the hell out of me
- ASCII rendering: I love rendering to ASCII which I can copy-paste around.
But I do use mermaid a lot embedded in other programs (e.g Obisidian). The selection of different diagram types is amazing.
I feel similarly about charting libraries.
I'd be curious to know if Ilograph is among the languages you've tried and if you feel the same way (I'm the author). Making it feel good to edit (the opposite of "rough in the hands"?) is an explicit goal, and to that end there is an IDE with context-aware autocomplete.