Tom Donohue Tom Donohue

Creating nice diagrams in code with

How to create nice-looking diagrams in an open, shareable, Git-friendly format

Creating nice diagrams in code with

Tags: Comments

Can I just say that I FLIPPING LOVE DIAGRAMS AS CODE. I’ve long had dreams about being able to do everything in code.

All of these things really excite me (a bit weird, I know):

  • book publishing as code (did this! wrote my book using Asciidoctor)

  • presentations as code (tried this, using Reveal.js, and it’s fabulous)

  • infrastructure as code (Ansible!)

  • pipelines-as-code (uh-oh, Jenkinsfiles 😩)

But the one thing that has always eluded me has been diagrams as code. I tried Graphviz but, let’s be honest, it’s primarily designed for graphs, and not really the kind of diagrams you would share at your next team meeting or fun party.

PlantUML is a good option if you want diagrams that fit a particular template (sequence diagrams, class diagrams, and so on).

What about other kinds of diagrams? Network diagrams, system diagrams, architecture diagrams?

I don’t think there is a tool that can generate complex but nice-looking diagrams from pseudo-code. Yet.

But what if….there was a decent offline diagramming tool, that saves in a sensible text-based format (SVG), with an accompanying command-line interface so you can easily generate bitmaps for sharing.

Well, I finally discovered it. It’s (formerly! I’d heard about the web-based version, but I didn’t know that there is also a version for the desktop. It’s a cross-platform app developed in Electron, and you can run it on Windows, Mac and Linux.

Drawio Desktop on GitHub
Drawio Desktop on GitHub Desktop runs entirely locally. No web access is required, it doesn’t require an account, or fetching anything remotely. It has all the main features you’d expect for creating diagrams, including built-in shapes and themes. It’s really great, and it’s open source.

I’ve used it for a couple of projects now and I really like it. It meets my criteria of open source, looks good and actually works ✅.

So now time for an example.

My workflow for creating diagrams with Desktop

Here’s my personal workflow for using We’ll create a trendy app / boring architecture diagram as SVG, add the source to a Git repo, and then build a PNG file so it can be shared over email, or included in another doc.

  1. Install drawio.

    🍏 On Mac - via Homebrew:

    brew cask install drawio

    🐧 On Fedora - download the latest RPM package from the drawio-desktop’s GitHub Releases page, then install using rpm:

    sudo rpm -i<version>.rpm
  2. Start Desktop and create your diagram using the UI:

    The drawio Desktop user interface
    Creating a nonsensical flow chart in Drawio (other diagrams are available)
  3. Export it as an SVG (File > Export As > SVG).

    Note: It isn’t mandatory to use SVG here, you could just save the .drawio file (the default), but I prefer to use SVG, because it is a more widely-used format.

  4. Commit the SVG into your Git repository if you like (probably a good idea):

    git add mydiagram.svg
    git commit -m "Made a diagram!"
  5. If you need the diagram in PNG format, you can use the drawio command-line tool to generate it for you.

    🍏 On Mac - use the binary inside the package. This example will scale the diagram to 250%, and output to PNG:

    /Applications/ \
        -x -f png --scale 2.5 -o published-diagram.png mydiagram.svg

    🐧 On Linux, just use the drawio binary:

    drawio -x -f png --scale 2.5 \
        -o published-diagram.png mydiagram.svg

    Now you have your SVG as a high-res PNG, which you can use anywhere! (The image doesn’t look great here, but that’s because it’s been resized for web)

    Viewing a drawio diagram exported as a PNG
    Diagram exported as a PNG
  6. If you’re using the generated diagram in a document (like a Markdown or Asciidoctor document), then just regenerate the diagram whenever you build your PDF.

    For example, when I’m writing an Asciidoctor document, I create a build script like this, which generates the image first, then builds my PDF:

    # Update the PNG renders of the diagrams
    drawio -x -f png --scale 2.5 \
        -o images/architecture.png images/architecture.svg
    # Generate my Asciidoc PDF from code
    bundle exec asciidoctor-pdf \
        -a pdf-fontsdir="./fonts/;GEM_FONTS_DIR" \

    Then I just run this script whenever I want to build the PDF for sharing.

  7. Whenever you need to update the diagram, just open the SVG in Desktop and make your changes. Then rebuild using the command-line, or your build script.

Now reap the rewards of version-controlled, easily-collaborated diagrams! 💕

What else can do?

There’s a bunch of options you can pass to the command-line tool. For more info, check out the command-line help for drawio:

$ drawio --help
Usage: drawio [options] [input file/folder]

  -V, --version                      output the version number
  -c, --create                       creates a new empty file if no file is passed
  -k, --check                        does not overwrite existing files
  -x, --export                       export the input file/folder based on the given options
  -r, --recursive                    for a folder input, recursively convert all files in sub-folders also
  -o, --output <output file/folder>  specify the output file/folder. If omitted, the input file name is used for output
                                     with the specified format as extension
  -f, --format <format>              if output file name extension is specified, this option is ignored (file type is
                                     determined from output extension, possible export formats are pdf, png, jpg, svg,
                                     vsdx) (default: "pdf")
  -q, --quality <quality>            output image quality for JPEG (default: 90)
  -t, --transparent                  set transparent background for PNG
  -e, --embed-diagram                includes a copy of the diagram (for PNG format only)
  -b, --border <border>              sets the border width around the diagram (default: 0)
  -s, --scale <scale>                scales the diagram size
  --width <width>                    fits the generated image/pdf into the specified width, preserves aspect ratio.
  --height <height>                  fits the generated image/pdf into the specified height, preserves aspect ratio.
  --crop                             crops PDF to diagram size
  -a, --all-pages                    export all pages (for PDF format only)
  -p, --page-index <pageIndex>       selects a specific page, if not specified and the format is an image, the first
                                     page is selected
  -g, --page-range <from>..<to>      selects a page range (for PDF format only)
  -h, --help                         display help for command


What do you think? You can use Markdown in your comment. To write code, indent each line with 4 spaces.