# diagram-as-code

Generate AWS diagrams from YAML — Go CLI with web frontend and draw.io export.

- URL: https://fernando.moretes.com/open-source/diagram-as-code

- Markdown: https://fernando.moretes.com/open-source/diagram-as-code/guide.md?lang=en

- GitHub: https://github.com/fernandofatech/diagram-as-code

- Homepage: https://dac.moretes.com

- Language: Go

- Topics: architecture, diagram-as-code, moretes, portfolio

- Stars: 1

- Forks: 0

- Updated: 2026-05-16T02:43:37Z

---

diagram-as-code is a Go CLI that converts YAML files into AWS architecture diagrams, with extensions I added on top of the upstream fork: native draw.io export, a Monaco-powered web frontend hosted on Vercel, and a public package for embedding in external tools.

## What it is and why it exists

This repository is a fork of [awslabs/diagram-as-code](https://github.com/awslabs/diagram-as-code), maintained by me as part of the architecture portfolio at [fernando.moretes.com](https://fernando.moretes.com). The original project solves a real problem: architecture diagrams typically live in visual tools disconnected from code — Lucidchart, manual draw.io, PowerPoint — and go stale fast. By describing infrastructure in versionable YAML, the diagram becomes an engineering artifact like any other: reviewed in PRs, tested in CI, tracked in Git.

The upstream already delivered the CLI and compliance with AWS visual guidelines. What I added in this fork:

- **Native draw.io export** via `--drawio` flag, implemented entirely in Go (`internal/ctl/drawio.go`), with no external binary dependency for the serverless case.
- **Web frontend** hosted at [dac.moretes.com](https://dac.moretes.com), with a Monaco editor, live preview, built-in templates, and download in PNG or draw.io — no local install required.
- **Serverless backend** via Vercel Functions, running the same Go binary as the CLI behind the API.
- **Public `pkg/diagram` package** for embedding diagram generation in other Go tools, IaC pipelines, or AI agents.

The result is a tool that works both in the terminal and in the browser, keeping YAML as the single source of truth.

## Fork highlights

- Pure Go CLI — no headless browser, Graphviz, or external image library dependencies.
- Native draw.io export (`--drawio`) implemented in Go, keeping `.drawio` as the source of truth for further editing.
- Web frontend at [dac.moretes.com](https://dac.moretes.com) with Monaco editor, ready-made templates, and direct download — nothing to install.
- CI/CD-friendly: runs in a container, accepts automation flags (`-f`, `--verbose`), and integrates with IaC pipelines.
- Public `pkg/diagram` package for embedding in external tools, AI agents, or drawing GUIs.
- CloudFormation template support (`--cfn-template`) and reverse YAML generation from existing stacks (`--dac-file`).

## How the pieces connect

The same Go core serves both the local CLI and the serverless backend of the web frontend.

### 👤 Author / User

- Engineer (terminal) (user)
- Visitor (browser) (user)

### 📄 Input

- YAML diagram file (data)
- CloudFormation template (data)

### 💻 CLI (Go binary — awsdac)

- awsdac cmd/awsdac (compute)
- Diagram engine internal/ctl (compute)
- draw.io exporter drawio.go (compute)
- pkg/diagram (public API) (compute)

### ☁️ Vercel (Web)

- Web editor dac.moretes.com (frontend)
- Vercel Function cmd/api-dev (compute)

### 📦 Output

- PNG diagram (storage)
- .drawio file (storage)

### Flows

- user_cli -> yaml: writes
- user_cli -> cfn: provides
- yaml -> cli: input
- cfn -> cli: --cfn-template
- cli -> core: processes
- core -> drawio_pkg: --drawio
- core -> png: generates
- drawio_pkg -> drawio: exports
- pkg -> core: embeds
- user_web -> frontend: edits YAML
- frontend -> api: POST /generate
- api -> core: invokes
- api -> frontend: returns PNG/.drawio
- frontend -> user_web: download

## Installation and usage

1. **Install via npm (recommended — all platforms)** — Requires Node.js 14+. Downloads the correct binary for your OS and CPU automatically.
```bash
npm install -g awsdac
awsdac --version
```

2. **Install via Go (requires Go 1.21+)** — ```bash
go install github.com/fernandofatech/diagram-as-code/cmd/awsdac@latest
```

3. **Build from source** — ```bash
git clone https://github.com/fernandofatech/diagram-as-code.git
cd diagram-as-code
make build   # produces ./awsdac (or awsdac.exe on Windows)
```
Prerequisites: Go 1.21+ · Node.js 18+ (web frontend only)

4. **Generate a PNG diagram** — ```bash
awsdac examples/alb-ec2.yaml
# default output: output.png

awsdac my-architecture.yaml -o my-diagram.png
```

5. **Export to draw.io** — ```bash
awsdac examples/alb-ec2.yaml --drawio -o output.drawio
```
The `.drawio` file can be opened in draw.io desktop or web for further editing.

6. **Generate diagram from a CloudFormation template** — ```bash
awsdac my-stack.yaml --cfn-template -o infra-diagram.png
```
This feature is in beta. Use `--dac-file` to generate the intermediate YAML and inspect it before rendering.

7. **Use the web frontend (no install)** — Visit [dac.moretes.com](https://dac.moretes.com), pick a built-in template (ALB+EC2, VPC+NAT, ALB+AutoScaling, Multi-Region) or paste your own YAML, select the output format (PNG or draw.io), and click download.

_Minimal YAML example — ALB in front of two EC2 instances_

```yaml
# examples/alb-ec2.yaml (simplified)
Diagram:
  Title: ALB + EC2
  Resources:
    ALB:
      Type: AWS::ElasticLoadBalancingV2::LoadBalancer
      Direction: right
      Children:
        - EC2a
        - EC2b
    EC2a:
      Type: AWS::EC2::Instance
    EC2b:
      Type: AWS::EC2::Instance
```

## How it works internally

The `awsdac` binary reads the input YAML file and deserializes it into an internal graph structure. Each node corresponds to a typed AWS resource (EC2, ALB, VPC, etc.) defined in definition files that map CloudFormation types to icons and visual metadata compliant with the [AWS icon guidelines](https://aws.amazon.com/architecture/icons). The engine automatically computes group positions and sizes — no manual coordinates in the YAML.

For PNG output, the engine renders directly in Go using the standard image library — no Chromium, no Graphviz, no OS-level dependencies. This is what makes the binary suitable for Alpine containers and headless CI pipelines.

For draw.io output, the pipeline in `internal/ctl/drawio.go` serializes the same internal graph to draw.io's XML format, including embedded assets (`drawio_assets.go`). The resulting `.drawio` file is editable in draw.io desktop or web, which is useful when the generated diagram needs manual tweaks before publishing.

The local dev server (`cmd/api-dev`) replicates the Vercel Function handler locally, allowing you to test the backend without the Vercel CLI. The TypeScript/React frontend on Vercel consumes that same API, POSTing the YAML and receiving the diagram binary back for direct browser download.

The separation between `internal/ctl` (rendering logic) and `pkg/diagram` (public API) is intentional: it lets external Go tools import the package without depending on the CLI's internal details.

> **Maintainer note:** I maintain this fork primarily to demonstrate IaC tooling integration with automated visual documentation generation. The web frontend at [dac.moretes.com](https://dac.moretes.com) is the fastest entry point for anyone who wants to experiment without installing anything. For CI pipeline use, npm installation (`npm install -g awsdac`) is the most portable route across Linux, macOS, and Windows. CloudFormation support (`--cfn-template`) is still in beta — it works for simple stacks, but complex diagrams may need manual adjustments to the generated YAML.

## Frequently asked questions

### Is this fork compatible with the upstream awslabs/diagram-as-code?

Yes. Any YAML valid for the upstream works here. The extensions (--drawio, pkg/diagram, web frontend) are additive and do not break the existing interface.

### Can I use this for non-AWS diagrams?

Yes, with caveats. The engine supports custom definition files via --override-def-file, which lets you define non-AWS resources. The --allow-untrusted-definitions flag is required for definitions outside the official repository.

### Does the web frontend send my YAML to any server?

Yes — the YAML is POSTed to the Vercel Function that runs the Go binary. There is no persistence: the diagram is generated and returned immediately, with no storage. For sensitive data, use the local CLI.

### How do I test the API backend locally without the Vercel CLI?

Use the included dev server: `go run ./cmd/api-dev`. It replicates the Vercel Function handler on localhost.

## Who this is for

This project is useful for engineers and architects who already version infrastructure as code and want to keep architecture diagrams in the same workflow — reviewed in PRs, generated in CI, tracked in Git. The CLI is sufficient for most automation cases. The web frontend at [dac.moretes.com](https://dac.moretes.com) is the fastest path to experiment or to share diagrams with stakeholders who don't have a dev environment. The draw.io export is the differentiator when the diagram needs manual editing after generation — for example, for presentations or technical documentation that requires fine visual adjustments. It is not a tool for highly customized diagrams with complex layouts; for that, manual draw.io or Lucidchart are still more flexible. The value is in automation, versioning, and integration with IaC pipelines.

## References

- [fernandofatech/diagram-as-code — GitHub](https://github.com/fernandofatech/diagram-as-code)
- [dac.moretes.com — Web frontend (live)](https://dac.moretes.com)
- [awslabs/diagram-as-code — Upstream repository](https://github.com/awslabs/diagram-as-code)
- [AWS Architecture Icons — Guidelines](https://aws.amazon.com/architecture/icons)
- [Introduction Guide — doc/introduction.md](https://github.com/fernandofatech/diagram-as-code/blob/main/doc/introduction.md)

## Links

- [GitHub repository](https://github.com/fernandofatech/diagram-as-code)
- [Homepage](https://dac.moretes.com)
