Most engineering teams have a diagram problem. Architecture diagrams live in Lucidchart or Google Drawings, disconnected from the code they describe. When the system changes, the diagrams do not. Within months, the "official" architecture diagram shows services that no longer exist and omits the three new ones that handle most of the traffic.
Diagrams as code solves this by treating diagrams the same way you treat source code: store them in version control, review changes in pull requests, render them automatically, and deploy them alongside your documentation.
What Is Diagrams as Code?
Diagrams as code is the practice of defining diagrams using a text-based syntax instead of a visual editor. Rather than dragging shapes onto a canvas and saving the result as a binary file, you write a short text description and a tool renders it into an image.
Here is a simple example. Instead of opening a drawing tool, you write:
A rendering engine turns this into a clean, styled diagram. The text file is what you commit to your repository. The rendered image is a build artifact, generated on demand.
This approach brings several fundamental benefits:
- Version control -- Every change to a diagram is a diff in your Git history. You can see who changed what, when, and why.
- Code review -- Diagram changes go through pull requests, just like code changes. Reviewers can comment on specific lines.
- Automation -- CI/CD pipelines can render diagrams, validate syntax, and publish them to documentation sites automatically.
- Consistency -- The rendering engine applies consistent styling. No more diagrams with mismatched fonts, colors, and arrow styles.
- Proximity to code -- Diagrams live in the same repository as the systems they describe, so they are more likely to be updated when the code changes.
Comparing the Tools
Three tools dominate the diagrams-as-code space: Mermaid.js, PlantUML, and D2. Each has strengths and trade-offs.
| Feature | Mermaid.js | PlantUML | D2 |
|---|---|---|---|
| Language | JavaScript | Java | Go |
| Runtime | Browser or Node.js | JVM required | Single binary |
| GitHub native | Yes | No | No |
| Diagram types | 13+ | 15+ | Flowcharts, sequences |
| Syntax | Concise, Markdown-like | Verbose, keyword-heavy | Declarative, minimal |
| Styling | Themes + inline styles | Skinparams | CSS-like theming |
| Learning curve | Low | Medium | Low |
Mermaid.js is the most widely adopted, primarily because of its native support in GitHub, GitLab, Notion, and Obsidian. It runs in the browser with zero dependencies, making it the easiest to integrate into documentation sites. If your team already uses GitHub or GitLab, Mermaid is the path of least resistance.
PlantUML has the largest diagram type catalog and the most mature UML support. However, it requires a Java runtime, which adds friction to CI/CD pipelines and local development setups. It remains popular in enterprise environments with established Java toolchains.
D2 is the newest entrant, designed from the ground up for modern workflows. It produces clean, aesthetically pleasing output and has a simple syntax, but its diagram type coverage is narrower than Mermaid or PlantUML.
Recommendation: For most teams, Mermaid.js offers the best balance of ease of adoption, platform support, and diagram variety. It is what we use and recommend throughout this blog.
Storing Diagrams Alongside Code
The first step in adopting diagrams as code is deciding where the diagram files live. The best practice is to store them in the same repository as the code they describe, using a predictable directory structure.
Recommended File Structure
Use the .mmd extension for Mermaid files. Some teams store the rendered SVG or PNG files alongside the source; others generate them in CI and only commit the source. Both approaches work. Committing rendered images is simpler (images work in GitHub README files without a build step), while generating them in CI keeps the repository cleaner.
Linking Diagrams in Documentation
Reference your diagrams from README files and documentation using standard Markdown image syntax:
If you are using GitHub, you can skip the image file entirely and embed Mermaid directly in Markdown. The diagram renders inline when viewed on GitHub.
CI/CD Integration
Automating diagram rendering in your CI/CD pipeline ensures that published documentation always matches the source files. Here is a GitHub Actions workflow that renders Mermaid diagrams on every push:
The @mermaid-js/mermaid-cli package provides the mmdc command, which renders Mermaid files to SVG, PNG, or PDF from the command line. The workflow only runs when diagram source files change, keeping build times short.
Validation in Pull Requests
You can also add a validation step that checks whether diagram source files contain valid Mermaid syntax, catching errors before they merge:
Review Workflows
One of the most powerful aspects of diagrams as code is that diagram changes go through the same review process as code changes. When an engineer opens a pull request that modifies the system architecture, the architecture diagram should change in the same PR.
What a Good Diagram Review Looks Like
- The diff is readable. Because diagram source is text, reviewers see exactly which nodes and connections changed. Adding a new service shows up as two or three added lines, not a binary blob.
- The rendered preview is available. If your CI pipeline renders diagrams and posts them as PR comments or deploys a preview site, reviewers can see both the source diff and the visual result.
- Changes are atomic. A PR that adds a new microservice should update both the code and the architecture diagram. This prevents drift between diagrams and reality.
Enforcing Diagram Updates
Consider adding a section to your PR template that prompts authors to update diagrams when relevant:
This is a lightweight nudge that keeps diagrams from going stale.
Team Adoption Strategies
Introducing diagrams as code to a team requires more than installing a tool. Here are strategies that have worked in practice.
1. Start with One Diagram
Do not try to diagram every system at once. Pick the one diagram that would save the most time -- usually the high-level architecture diagram that new hires need during onboarding. Create it in Mermaid, commit it to the repository, and link it from the README. Let the team see the value before asking them to adopt the practice broadly.
2. Lower the Barrier to Edit
Not everyone on the team will be comfortable writing Mermaid syntax from memory. Provide easy on-ramps:
- Link to the SimpleMermaid editor in your contributing guide so people can draft diagrams visually before committing the source.
- Include a syntax cheat sheet in the repository.
- Add VS Code extension recommendations for Mermaid preview to your workspace settings.
3. Make Diagrams Part of Design Reviews
When proposing a new feature or system change, require a diagram as part of the design document. This is not a bureaucratic hurdle -- it is a thinking tool. Drawing the diagram often reveals missing components, circular dependencies, or unnecessary complexity before any code is written.
4. Celebrate Diagram PRs
When someone updates a diagram alongside a code change, call it out in code review. Positive reinforcement normalizes the practice and encourages others to follow suit.
5. Designate Diagram Owners
For critical diagrams (architecture, deployment, data model), assign ownership the same way you assign code ownership. Use a CODEOWNERS file to require review from the diagram owner when source files change.
The Long-Term Payoff
Teams that adopt diagrams as code consistently report three outcomes: diagrams stay up to date because they are modified in the same pull request as the code, new team members onboard faster because visual documentation actually reflects the current system, and design discussions become more productive because everyone is working from a shared, accurate picture.
The investment is small -- a few text files in your repository and a CI step to render them. The return is documentation that evolves with your system instead of decaying beside it.
Start Diagramming as Code
Draft your first diagram in the SimpleMermaid editor, then commit the source to your repository.
Open the Editor
Buy Me A Coffee