This project (and others like it) are graphviz wrappers - they do some really cool stuff to emit styled .dot files that look better than writing and rendering raw gv.#
Allowing specification in Python offers very little advantage - in theory you think, hey, I've got hi-lighting, autocompletion, and so on from an IDE. It'll play nice in VCS. Maybe I can interrogate orchestration layers and so on to produce dynamic views.
In practice diagrams are produced by folks who might not want to use or learn python [or golang, their other implementation]. Instead a lean purpose-build DSL, maybe even an extension of graphviz dot, is easier and more portable for some audiences to pick up.
Secondly, we can't JUST graft a DSL front-end onto these tools because the styled components are baked into the project.
My personal experience with layout engines is that they work OK for very small architecture diagrams, but become ugly or inelegant at useful scales.
I (and the teams I've worked with) settle on draw.io, either the desktop app, or committed as part of confluence, as the best way to describe intent/design - and rendering graphviz with a style up top for anything dynamic.
Would welcome seeing a true extension to the dot language that can unlock reasoning engines (like to do threat modeling) and render-time styling.
I have a love/hate relationship with diagrams, and diagrams-as-code-things (plantuml, mermaid, etc). As a programmer, I find myself trying to turn everything in to a software project: everything must be version control-able. Same with these diagramming solutions -- except I nearly never know what I want the digram to look like, when I start "writing" it. This means I nearly always end up on something like lucid.app just sketching out the solution, and thinking to myself that I'll turn it in to a beautiful diagram with one of the earlier solutions, later -- that never happens. So now I have a diagram I can link to (yay), but can't version control (boo).
Then, I discovered excalidraw[1]: it lets me sketch like lucid, but isn't nearly as polished or robust: you can throw together simple shapes, draw lines between them, and the lines stick to the shapes, so you can move them around and the lines move too. You can also group things together, and draw freehand, and also include text -- what more do you need?
The cool thing about excalidraw is that you can share your drawings, and export them as SVG files -- yay! I can version them again. You can also self-host it, which is a massive plus in my book.
I've been mostly using the VS Code Excalidraw plugin. Any file with name ending on `.excalidraw.svg` or `.excalidraw.png` is an Excalidraw-editable image of the respective format. This means you can save it alongside your markdown docs and embed them directly, but also edit the exact same file on the IDE.
Big Excalidraw fan and I had no idea you could do that...this might be the version controllable solution I've been looking for. Also have given up trying to get mermaid and other solutions to work well.
Is your concern about committing a binary object that is difficult to diff or not being able to recreate/edit the diagram.
Particularly in the latter cases, most of these tools embed the machine readable diagram inside of the PNG. So you can just open the PNG inside of draw.io or excalidraw (if it was created by that tool) and edit the diagram. This is because the plain text file is embedded.
It’s great that lots of tools are going this way. Notably, if you’re doing image generation with Stable Diffusion or Flux, you can just drag a PNG from ComfyUI into the ComfyUI window and get the same whole workflow. It’s a great learning tool.
As for diffs? Well, that’s hard - even if you were diffing the “source” text files for excalidraw or plantUML, a lot can change that makes it nearly impossible to understand. When all that really happened might’ve been a small styling change and moving a node.
Yeah, the most important part of versioning should be the code used to create the diagram, IMO. The result files, whether SVG or PNG, should be packaged as a "release", if you were to use Github.
Excalidraw seems to boil down the important parts of Miro into an even neater and user friendly package. And it seems really modular and have a really interesting API as well. You can use it as a react component for example.
> you can share your drawings, and export them as SVG files -- yay! I can version them again
Out of curiosity, does anyone know of a drawing tool -- like Excalidraw, Lucid or Draw.io -- that has the option of exporting diagrams to code, i.e. something like PlantUML or Mermaid?
Not a diagram tool, but can be used like one, since it converts Python functions into nodes that you can connect to each other and export the resulting layout as images (PNG, SVG, SVG inside an HTML page) or as plain Python code: https://github.com/IndiePython/nodezator
full disclosure: I'm the creator and maintainer of the tool (but this is no advertising, as I released it to the public domain since day 1)
I’ve finally found a happy middle at work where I version control the markdown based “user manual” and API specs/docs, but the design pages, rich with graphs and diagrams are going to live on the corporate wiki and require that I just learn to be disciplined to keep them up to date.
Surely I can just do that and not everything has to be… I dunno what to call it… that thing where us programmers love to see every human process problem as requiring a technical solution.
I'd end up with something like this if I ever had the time. Instead of a corporate wiki, though, I'd probably use something like sphinx to compile PDF files, and store them on the public workspace.
Do you know how excalidraw compares to draw.io? I've used draw.io in the past, but see excalidraw mentioned quite a bit too. I'm not good enough at using draw.io to be against switching for future projects.
The concepts of internal DSLs and external DSLs is relevant here. The article is an internal, to Python, DSL. It runs in the language the tool is written in. Mermaid is an external DSL. You can’t build a Mermaid renderer in Mermaid. For diagrams I’d rather have an external DSL or a macro system than an internal DSL because it looks cleaner IMO. But it’s nice to have syntax highlighting already working in internal DSLs.
Is this a recent addition? I recall attempting to do this some years ago, failing, and putting the tool out of my mind as a result. Maybe I was doing something wrong.
> In practice diagrams are produced by folks who might not want to use or learn python [or golang, their other implementation]. Instead a lean purpose-build DSL, maybe even an extension of graphviz dot, is easier and more portable for some audiences to pick up
This is so absolutely ludicrously absurdly wrong that it's comical.
No one wants to learn a new programming language. Cf. all of the old algol languages that are still around and all their "replacements" that are no longer around.
Some people (not even a majority) are willing to learn a new language if compelled by force or incentive. Diagramming is absolutely not enough incentive to learn a new language.
I agree with both of you, but I still don't want to use Python to generate my diagrams.
Diagrams are a visual thing. I prefer a visual designer. I can send that to some random nontechnical person for a presentation and they can edit them, etc.
I find with things like this, it works pretty well until you want to do something off the beaten path, then it's a pain where you're trying to figure out how to get it to render like you want it to.
Reminds me of the ole "just move it 2px to the right" in the CSS of yesteryear
> This is so absolutely ludicrously absurdly wrong that it's comical.
Quite the hyperbole, but I do agree that python isn't so wrong of a choice, but the problem is diagrams eventually interact with non-technical people and that's where it gets tricky.
I LOVE mermaid, d2, but at somepoint I hand the diagrams off to someone who knows nothing about markdown and honestly they shouldn't have to know it to interact with a diagram.
All these "diagrams as code" are great for an isolated group. I can pump them out WAY faster than manual drawing programs (draw.io, etc), but then run into the iterop wall w/ other teams.
I'd LOVE a place that could be like AWS's graphical editor that sort of goes in between the two. It's a hard problem I 100% agree and would require yet another DSL, ugh.
I upvoted you for the hyperbole but absolutely don't agree.
People who don't want to learn a new special purpose language are basically saying that 'I've got a hammer and everything is a nail' is fine, which is (to your point) absurd. Languages are tools, use tools to solve problems the tools were designed to solve.
Where I do agree is what you haven't said clearly: it isn't obvious what problems 'diagrams as code' solve. The idea is cool and I've used plantuml with some success, but in the end the diagram is supposed to be consumed visually (including changes - to preserve spatial relationships between versions).
I love python and I found diagrams fine but after tried for a few time , it comes down to me that diagrams as code only good for diagrams that are already sketched out on how it would look like in design tools like draw.io . Diagrams need a Visual editor. Designing using code is very hard to visualize how it will look like by just looking at code and running , editing , looking back is not fun.
Since code provides easy versioning and search and replace , refactoring is easy , what we need is visual editor that generates code and so we can keep that code versioned in github.
This is incredibly cool! I've been using Neo4j to hack something like this together but the UI on this is amazing. I honestly believe that tools like this should be as fundamental to IT as double entry bookkeeping is to accounting and CAD is to engineering and blueprints are to construction.
At a glance this looks pretty nice for people like me who already know python, hate doing things manually, and have to make and update diagrams sometimes.
Sure it’s probably not worth learning python for, but it is a python library, it’s for pythonistas, not everyone.
If you decide to try the visual language DRAKON (https://drakon-editor.sourceforge.net/) you will notice that it always produces non-ugly diagrams by literally not allowing you to draw anything ugly. It has some basic rules how to compose the diagrams but once you get the concept - everyone will love your diagrams. Here are a few examples of my diagrams - https://postimg.cc/gallery/Z4SbScg
I quite like PlantUML, even for add a simple diagram to an email discussion which has become to long.
My colleagues however like the idea but don't want to learn the syntax.
So I build a simple add-on to our internal mail system that, when invoked, scrapes the email and runs it against a fine tuned Llama 3.1 8b model which then generates a PlantUML diagram from natural language.
If the input isn't of an appropriate nature to be converted to a diagram or vague it will not do this.
What I have found is that now at least 50% of the team have used this feature once since go-live.
In many cases not all though, the immediately returned image is not 100% correct but there is a nice integrated way to edit and render which is now causing many to get familiar with the syntax whereas before they couldn't be bothered.
Overall it's been a nice, relatively cheap way to get GenAI to actually help us at work.
I use Github Copilot with PlantUML. I use PlantUML comments to describe what I want the diagram components to show and then the syntax is written for me. I can then edit it pretty easily and iteratively.
Not really for obvious reasons but I can try to explain.
So like many other orgs we use email heavily to get stuff done.
Like many orgs we have numerous teams that are required to co-ordinate together to get this stuff done.
A lot of the time there is some sequencing to the actions that needs to happen by these teams in a certain way to ensure we get this stuff done properly if at all.
So many emails could be interpreted like workflows ... A needs to validate with B then provide to C who then has to get confirmation from D.
There are more emails than I thought where something like PlantUML can help peoples understanding of the situation and also surface up potential areas of disagreement or misalignment quicker and also sometimes emails get so long that new entrants to the chain (via cc) would benefit from a quick visual summary.
This is the only diagramming language I end up actually using. And even then I usually end up redoing everything in OmniGraffle after I’ve roughed out a draft.
its layout engine is the real magic for me, it allows complex diagrams that are just unreadable in graphviz or mermaid. a concise DSL and animation support are bonuses too
LLM's are well-trained on Mermaid. Gemini specifically is fantastic as a 'diagram assistant'. I was able to create this diagram and a ton of other such diagrams quite easily with Gemini and Mermaid's live editor: https://nshkr.com/SecureSphere-Overview-20241102.png
Sometimes I feel they are even too much trained on Mermaid. I prefer graphviz but claude very often output a mermaid diagram even if I gave a valid graphviz example in my prompt.
I've been using the same, but with Chatgpt. Multiple iterations are needed to get what I want though. Cool trick is that you could import Mermaid using drawio.
Mermaid is fantastic for diagramming architecture. A little quirky, but not too bad.
If you're using GitHub it's supported in any markdown file, and therefore accessible to any other dev with repo access. No permissions issues, edits can go through code review, and no dependencies necessary.
Interesting decision to implement a DSL in a programming language when the output is a static data structure. Seems more complex than writing the structure directly as YML or JSON (or a custom language like Mermaid or DOT).
I can see the point of DSLs where the output is used by other code (e.g. builder pattern, LINQ). But this seems like overhead compared with the alternative?
I'm biased, but I think it's a bad decision. Programming languages are for writing, well, programs. Programs execute, accept input, have state, and all manner of other things that just don't apply to diagrams. Diagramming in a programming language is just weird.
This is a program that executes and produces an output. It also has state - every step of executing that DSL is creating and manipulating a piece of state that builds up a declarative description of what the final output should look like.
The other thing you list, input, is optional. I write programs that don't take any input all the time. Monte Carlo simulation, for example. The entire demoscene is largely devoted to creating incredibly sophisticated programs that don't take any input. Postscript is a full, Turing-complete language whose primary purpose is to create programs that generally don't take any input
Programs that produce diagrams should be (and are) written in a programming language. They accept input, execute, and produce output. Diagrams themselves do not execute and have state (unless they are interactive[0]). There's a difference.
Be aware the poster has a history of being very active on posts related to diagramming tools to discourage his competitors' solutions and/or promote his own tool without disclosing affiliation.
Recipes absolutely should be written in code. If I could view source, copy the recipe yaml, and paste into my personal recipe manager app, it would be much more convenient.
Screenplays... are already written in code, partly. If they weren't, they'd include quotation marks and "she said" after every line.
I think the counter-point to that would be that if you're writing infrastructure as code, and your architects are using a specific language anyways (Python in this case), it makes more sense for data governance and editing reasons to just keep things in the existent ecosystem and not worry about having to procure another license.
Vs. Cooking or Writing which aren't coding practices unto themselves.
You can do it, certainly, but it is overkill. It also limits your potential editors to people who know Python and are willing to install it on their machine. In contrast to Python (or other programming languages), a language like YAML or JSON can be learned in minutes by just about anyone.
One of the areas I think diagrams as code could really improve in is the potential to add rendering rules. For instance: these (sub) groups must be equally sized, these boxes must be aligned vertically, etc.
Bonus points: an interface where you enter your diagram code and where a random set of 9 renders is shown with a different rendering rule added. You can go through this step multiple times by just clicking the diagram you think looks best. After a couple of iterations you have a diagram that is fairly fixed (avoiding the complete re-render problem when making changes) and beautiful.
Bonus points 2: make it also an editor where you can configure these rules in the GUI. When changing the rules in the diagram this is reflected in the 'view' part of the code.
Agreed, there's a lot missing here. Been using it a few hours now and here's a few problems with Diagram:
Pros:
- Some nice conceptual overlap with imperative programming. In theory could be very powerful.
- It comes with a nice set of product icons. This was the main draw for me TBH, I wish MermaidJS had these built in.
Cons:
- Having to regenerate each time you make a change. Needs a better UX, as you say. MermaidJS and others have nice web GUIs that react to changes, Diagram at best I can have side by side with my code editor and I manually regen with each change.
- Only outputs PNGs with white background? Why not transparent? Edit: You can change output format, and looks like there is a way to override some graphviz settings to achieve transparent background.
- Lots of rendering glitches, for edges in particular that seem to vanish at random.
- Justification is random - sometimes things center, sometimes they go to the top, sometimes the bottom, etc.
- Direction is completely broken. Clusters have a direction param that is entirely decorative as far as I can tell. It is impossible to tell what direction a set of items will end up having based on the code alone.
- Ordering is broken. You can group items with Python lists - cool! - but for some horrific reason Diagram ignores the list order and displays the items ordered by label alphabetically. Wtf? Edit: On further investigation this might actually just be reversing the list from the expected order? Hard to tell since direction is generally unpredictable.
I'm sure there are more positives, but the gaps have been so glaring and frustrating that I cannot imagine using this regularly in its current state.
from diagrams import Diagram
from diagrams.aws.compute import EC2
with Diagram("Simple Diagram"):
EC2("web")
This has a very odd API. It's using (abusing?) context managers and contextvars to do weird spooky things that you could just as easily do with ordinary objects or functions.
Depends how it's implemented. It seems very similar to Apache Airflow in API, and similar to the many Argo Workflows Python wrappers.
This pattern when implemented with context vars in the context managers is a pretty nice way to reduce the boilerplate, without the downsides of traditional globals. The state can be safely contained to just the with block.
Usually these types of APIs also allow usage without it, using the context vars only to populate arguments not explicitly provided.
it's using context managers to manage context i.e. state that is there but isn't needed to be referenced by code directly. it's the whole point. you can do it all with just functions or objects (doesn't matter, functions are objects in Python anyway) by design, context managers are there for DRY purposes.
Oh heck yes, this is absolutely my jam. I loathe digging around in Visio/LucidChart/etc because I am an absolute perfectionist with OCD-enhanced symmetry mandates, which is just a mouthy way of saying I spend way too much time obsessing over placement details and line thickness instead of just diagramming the dang architecture.
Bonus points it's running via Python, which gives me a reason to fire it up and kill two birds with one stone (I'm a PowerShell junkie, so my relationship to Python thus far has been "reluctantly professional").
A problem I find with all of these is how can I render and publish the results somewhere on our corporate infra for everyone to see? And then, how do I ensure that the diagram-as-code in the repository is synced with that published render?
For example, at $work we use Confluence for documentation - I just don't see any of the solutions mentioned in this thread as being compatible with deploying diagrams to confluence, or indeed any type of CMS. It seems that at a minimum you need some bespoke docs rendering pipeline in every repository which spits our rendered docs and diagrams to some other platform?
We have a few workflows at work that use the confluence api to publish pages with dynamic content. It's not super convenient, but was easy enough to set up.
We're not using diagram-as-code though. Most of our diagrams are embedded into the confluence page or copied from somewhere else.
Throwing in an (almost exhaustive) list of online (+ few cli based) text to diagram tools that i keep updating whenever I see a relevant tool here on HN. There are not many tools like these. There are quite a few in the list, but when you try to find something for a specific purpose you will see there are not many for your specific needs (at least in they way you might expect).
Nice collection. Do you have a recommendation for flowcharts, or more specifically for state charts? I’d like to be able to generate a DSL from a workflow engine with the current state and history of execution of a workflow instance and then display it to my users. I.e. something like temporal.
Try https://flowchart.fun I had very productive time with it on a project where I needed to understand the flow of a complex process. It takes tab delimited list as input. It's super fast/easy to make flow charts using this (upto a point of course)
I loved this when I started using it. It does work very well to a certain extent. At some point the diagrams became too large and the arrows overlap started to be really inconvenient.
I heard that likec4.dev is a good alternative for this, but I have no hands on experience with it.
I think that this, and C4 style diagrams are about as advanced as it is possible to get for the “diagram I need to add to my docs”.
The problem is that a picture really is worth a 1,000 words.
If the picture is going to be worth including, then the picture is probably worth a KB of typing. That’s a lot and can go horribly wrong - esp for what is basically a whiteboard diagram
Don’t get me wrong - graphviz for showing relationships between modules in a project, matplotlib for pretty much anything and “real maths graphs” - that’s all vital but is a different skill set and different intention to this kind of whiteboard but in code.
I think sometimes we have to admit, just draw the darn thing and take a photo.
This looks great, and I am glad that there is a "Generic" set of nodes. I'm always a bit uncomfortable about architecture diagrams that lean too heavily into the names/icons of the specific cloud platforms that they use... i.e. describing WHICH AWS/Azure/GCP tech is being used rather than concern for WHAT or WHY those components are there for, which is much more important! It doesn't look like the edges between the nodes are labelled with any useful information either in this case.
Yeah, just about every diagram you see online commits these sins. Probably because companies that create detailed diagrams don't make them public. What's left is mostly diagrams by tech companies (e.g. cloud providers) created specifically to promote the technologies themselves.
> NetBox functions as the source of truth for your network infrastructure. Its job is to define and validate the intended state of all network components and resources. NetBox does not interact with network nodes directly.. This separation of duties enables the construction of a robust yet flexible automation system.
> Each file represents a discrete physical device type (e.g. make and model). These definitions can be loaded into NetBox instead of creating new device type definitions manually.
> Device images in PNG format and arranged by manufacturer. Each file represents front and rear of a physical device type (e.g. make and model). These images [based on vendor visio stencils] can be loaded into NetBox to obviate the need to create device images.
I've been using LLMs to draw diagrams in PlantUML for over a year now. I assume other people have been doing the same with GraphViz because PlantUML uses GraphViz as a library.
This seems like a great idea, but it seems to overwrite a lot of native python that would make this more flexible.
With some quick playing around, I don't see a way to parameterize is. Ie. If I want to show a different amount of workers in your example[1] if I am creating a dev or prod diagram. It would be really nice to be able pre-define certain parts of the diagram and add as desired.
Looks like you should be able to use regular python variables to do that or eg call a function that returns the right list of workers depending on the environment type.
If the obvious way is what you tried then yeah, the library should be changed to support this.
What are the alternatives for diagrams? Would an ascii diagram be better? I'm not sure if screen readers would ignore all of the random characters or not.
I'm assuming just a text description would be better, but I don't know what other options are available.
Apple has gotten really good at text selection in images. I can take a screenshot of a webpage and then select the text in the screenshot, or I could take a photo of a sign and select the text in the sign.
Do you know if there is anything similar for screen readers?
For screen reader accessibility, isn’t text a better option? If I were working with an engineer who uses a screen reader, I’d document heavily in text. Good practice anyway, since diagrams aren’t great at depth.
I personally would rather create a .drawio file visually and keep that under version control. Sure, the diffs aren’t that meaningful, but that’s what commit messages are for.
This is code to diagram, not diagram as code. I was hoping to see a tool that takes diagram sketches and outputs, e.g., Terraform. That would treat a diagram as code.
The phrase "A as B" tends to imply that "A" came temporally and causally first, then "B" was generated from "A" somehow. "B" is some kind of view, summary or transform of "A".
So I read "diagram as code", as that we have a diagram, and we are going to interpret it as code. We start with a diagram, and get code. A lot of visual programming type projects are in fact, diagrams as code.
Similar to the traditional text as (isomorphic to the) code (it is transformed into).
But "code as diagram", is what we have here. We are viewing the code, which came first, as a diagram which summarizes it. In a lossy but useful way. The diagram cannot be executed, so there is no diagram (acting) as code.
In SaaS we’re really saying “A used as/for B”, not “A represented as B”. IaC fits your definition. I suppose that descriptive linguistics says that all of these contradictory uses are valid and their meaning is picked up through context. I still (stubbornly?) feel that my usage is a little more logical than others, though.
“Starring Gene Hackman as Royal Tenenbaum”—this means that Gene Hackman portrays Royal Tenenbaum, not vice versa
I've never found one of these that works for more than simple diagrams. No matter which I've tried, once the diagram has more than a few nodes the layout goes wacky and you have to write so much additional code to hack it back into a sane layout.
Then your code is a mess and the results are fragile.
I'd love to find a diagram as code software that works well, but unfortunately PlantUML, Mermaid, D2 have all had the same issues
I believe that the problem here is that there isn't an agreed-upon answer to a fundamental question:
>What does an algorithm look like?
The problem is expressiveness of such a diagram is bounded by the size of a screen or a sheet of paper, and once one starts to scroll, or can't see the entire flow at a glance, things get complicated.
The node/wire programming folks have this a bit rougher to the point that there are sites such as:
I prefer to work visually, but not sure if that's actually valid --- unfortunately https://www.blockscad3d.com/editor/ doesn't support all of OpenSCAD and https://github.com/derkork/openscad-graph-editor has problems with a stylus (I have to leave the Windows Settings app open to toggle stylus behaviour which is enough friction that I don't use it as much as I would otherwise).
I had a reasonable experience with Diagrams previously. I have always been somewhat of a sucker for the theoretical potential for diagrams as code. As a Diagram is generated programatically - it can also be generated dynamically - for example reflecting API responses. As I remember there is reasonable support in Python based Static Site generators - I think we used Sphinx without much issue.
These tools are neat and handy for simple diagrams. Love mermaid.
For more complex diagrams, where explainer notes are beneficial, I find hand tweaked diagrams can not be beaten (my go to is draw.io)
If a simple DaC diagram is 1000 words, then a hand tweaked diagram is 10,000. And that 10,000 pays off. The bang for buck payoff is there. Of course, other considerations like maintainability etc etc
Regarding diagrams as code, the diagrams Haskell package is also worth a look. My goto "drawing" tool, as I wrote a Braille backend for it, which now lets me raster lots of stuff as Unicode Braille.
Allowing specification in Python offers very little advantage - in theory you think, hey, I've got hi-lighting, autocompletion, and so on from an IDE. It'll play nice in VCS. Maybe I can interrogate orchestration layers and so on to produce dynamic views.
In practice diagrams are produced by folks who might not want to use or learn python [or golang, their other implementation]. Instead a lean purpose-build DSL, maybe even an extension of graphviz dot, is easier and more portable for some audiences to pick up. Secondly, we can't JUST graft a DSL front-end onto these tools because the styled components are baked into the project.
My personal experience with layout engines is that they work OK for very small architecture diagrams, but become ugly or inelegant at useful scales.
I (and the teams I've worked with) settle on draw.io, either the desktop app, or committed as part of confluence, as the best way to describe intent/design - and rendering graphviz with a style up top for anything dynamic.
Would welcome seeing a true extension to the dot language that can unlock reasoning engines (like to do threat modeling) and render-time styling.