skip to content

What is the difference between diagram-based tools and model-based ("diagrams as code") tooling such as PlantUML and Structurizr, and what do you gain and lose by adopting a single-model approach?

level: seniorimportance: should knowfreq 36%

answer

  1. Picture tools store geometry; models store identity
  2. PlantUML/Mermaid = text per diagram, versioned
  3. Structurizr = one model, many views, tags, filters
  4. Rename once → all views update
  5. Risk: over-modelling, DSL curve, auto-layout

basics

~20 s

Drawing tools store pictures, so the same service exists five times and updates get missed. Model-based tools store one definition of elements and relationships, then render multiple views from it. PlantUML is scripted-per-diagram text; Structurizr holds a real model with views.

solid answer

~50 s

A **diagram-based** tool (Visio, draw.io, Lucidchart, slides) stores shapes and coordinates: there is no shared notion that the `Orders API` box on diagram A is the same thing as on diagram B, so renaming or deleting it means manual edits everywhere, and diagrams silently diverge. **Diagrams-as-code** (PlantUML, Mermaid, Graphviz) stores text, which brings version control, pull-request review, diffs, and CI rendering — a large win — but each file is still an independent picture unless you impose conventions or shared includes (e.g. C4-PlantUML macros). **Model-based** tooling (Structurizr, and the broader modelling tradition of ArchiMate/Sparx-style tools) separates *model* from *views*: you define people, systems, containers, components, deployment nodes, and relationships once, then declare which views render which subsets. One rename updates every view; consistency is structural, not a matter of discipline. Costs: DSL learning curve, layout is harder to control than dragging, tooling lock-in, and a real risk of over-modelling. Typical pragmatic choice: Structurizr DSL (or C4-PlantUML) in the repo, rendered in CI, plus a whiteboard for thinking.

code

structurizr-dsl · 18 lines
structurizr-dsl
workspace {
  model {
    customer = person "Customer"
    shop = softwareSystem "Online Shop" {
      web  = container "Web App"     "Next.js"
      api  = container "Orders API"  "Java"
      db   = container "Order Store" "PostgreSQL" "Database"

      customer -> web "Places orders using" "HTTPS"
      web -> api      "Calls"               "JSON/HTTPS"
      api -> db       "Reads/writes orders" "JDBC"
    }
  }
  views {
    systemContext shop { include * autoLayout }
    container     shop { include * autoLayout }   // same model, second view
  }
}

go deeper

for a junior

Say that drawing tools store pictures while text-based tools store definitions that can be version-controlled and reviewed, and that a model lets one change update every diagram.

for a middle

Distinguish the three tiers, name PlantUML/Mermaid/C4-PlantUML and Structurizr, and describe the workflow: DSL in the repo, rendered in CI, reviewed in pull requests.

for a senior

Weigh the trade-offs — consistency and cheap filtered views versus DSL curve, layout control, hosting, and over-modelling — and pick per context (single team vs multi-team platform vs regulated).

for a principal

Frame it as a documentation-quality investment: where the model's source of truth lives, what is generated from ground truth versus hand-authored, CI assertions over the model, ADR linkage, ownership, and an exit strategy against lock-in.

## Three tiers of tooling ### Tier 1 — drawing tools (picture-based) Visio, draw.io/diagrams.net, Lucidchart, Figma, slide decks. You place shapes and lines; the file stores geometry. - **Pros:** zero learning curve, total layout control, great for one-off communication and for exploring in a workshop. - **Cons:** no identity — the same element appears as N unrelated shapes across N diagrams; no diff (binary or XML blobs that review tools cannot show meaningfully); no validation (you can draw an impossible or contradictory architecture); updates are manual and therefore skipped; diagrams live in wikis away from the code they describe and rot. ### Tier 2 — diagrams as code (text-based, per-diagram) PlantUML, Mermaid, Graphviz/DOT, D2. - **How it works:** you write a small script (`Container(api, "Orders API", "Java", "...")`, `api -> db : reads/writes`) and a renderer produces SVG/PNG. - **Pros:** plain text next to the code; meaningful diffs and code review; automatic layout means no fiddling; rendered in CI and embedded in docs/READMEs; Mermaid renders natively in many wikis and in GitHub markdown; **C4-PlantUML** provides macros (`Person`, `System`, `Container`, `Component`, `Rel`) so C4 semantics are expressed directly. - **Cons:** still one script per picture — element identity is by convention only, so the same container can drift between files; layout control is limited (auto-layout can produce spaghetti for dense graphs); no model-level queries or validation. ### Tier 3 — model-based (single model, many views) Structurizr (DSL, plus the Java/.NET client libraries and Structurizr Lite/on-premises renderers), plus enterprise modelling tools (Sparx EA, Archi/ArchiMate, MagicDraw) and OMG-style MDA tooling. - **How it works:** you define the **model** once — people, software systems, containers, components, deployment nodes and their relationships — and then define **views** that select and lay out subsets of it (a system-context view, a container view, a component view for one container, one or more deployment views per environment, dynamic views per scenario). - **Pros:** - **Single source of truth**: rename `Orders API` once and every view updates. - **Guaranteed consistency**: it is impossible for a relationship to exist on one view and not in the model. - **Views are cheap**: filtered/perspective views (e.g. "only elements tagged PII", "only the payment feature") come free once the model exists. - **Programmatic model building**: because the model is data, you can populate parts of it from code annotations, service registries, infrastructure-as-code, or tracing data — pushing towards diagrams that cannot drift. - **Automatable checks**: assert in CI that every container has an owner, or that nothing bypasses the gateway. - **Cons:** a DSL/metamodel to learn; layout still needs hints (Structurizr supports manual layout persistence or auto-layout via Graphviz); one more tool to host and maintain; and the classic failure mode of **over-modelling** — investing in an elaborate model that nobody reads, which is what discredited heavyweight modelling in the first place. ## Choosing - **Small team, one system, low churn:** C4-PlantUML or Mermaid in the repo. Cheapest path to versioned, reviewable, non-ambiguous diagrams. - **Many systems / many teams / long-lived platform:** a model (Structurizr DSL) is worth it — the payoff scales with the number of views and the rate of change. - **Regulated or safety-critical, or model-driven engineering:** heavier UML/ArchiMate tooling with formal metamodels and traceability. - **Always keep whiteboards** for thinking: model-based tooling is for the artefacts that must stay true, not for exploration. ## Practices that make it work 1. **Store the model with the code** (or in a docs repo referenced by it) so changes are reviewed in the same pull request. 2. **Render in CI** and publish to the docs site; fail the build if the model does not parse. 3. **Keep views few and purposeful** — one context, one container, component views only where complexity warrants, deployment per environment, dynamic per critical scenario. 4. **Tag elements** (`pii`, `external`, `deprecated`, `team-x`) so filtered views come for free. 5. **Prefer generated over hand-authored** for the lowest, most volatile levels. 6. **Link diagrams to ADRs** so a reader can get from the picture to the reasoning (Structurizr supports embedding documentation and decision records alongside the model). ## Edge cases - **Auto-layout fights you** on dense graphs; the fix is usually fewer elements per view, not manual pixel work. - **Merge conflicts** in a shared DSL file are real; split by system/feature into includable files. - **Lock-in**: mitigate by keeping the DSL text (portable, human-readable) rather than a proprietary binary model, and by exporting to open formats where supported. - **Partial adoption** works: many teams keep a model for the container/deployment levels and use ad-hoc sketches below that.

  • When is a drawing tool still the right choice?
    For thinking and for one-off communication: workshop sketches, an options comparison in a review deck, an incident timeline. Those artefacts are disposable, so identity and consistency are worthless and layout control and speed are everything. The rule is that anything expected to stay true belongs in the model.
  • How would you push diagrams closer to 'cannot drift'?
    Derive as much of the model as possible from ground truth: build the container/deployment model from infrastructure-as-code or a service catalogue, derive component relationships from static analysis or annotations, and derive dynamic views from distributed traces. Then hand-author only intent (context, target state, rationale) and add CI assertions over the model.
  • What are the main risks of adopting Structurizr or a similar model-based tool?
    Over-modelling that nobody reads; a DSL learning curve that concentrates diagram work in one person; auto-layout frustration on dense views; hosting/maintenance of the renderer; merge conflicts in a monolithic model file; and lock-in — mitigated by keeping a portable, human-readable DSL in version control.

A drawing tool is a spreadsheet where each report re-types the numbers; a model-based tool is a database with saved queries. Renaming a customer in the database fixes every report at once — in the spreadsheets you'll always miss one.

saying these in an interview costs you the question

  • "Diagrams as code" and "model-based" treated as identical — PlantUML files are still independent pictures
  • Believing a tool alone prevents drift, without CI rendering and pull-request review
  • Building an exhaustive enterprise model before anyone has asked a question it answers
  • Keeping diagrams only in a wiki or slide deck, disconnected from the code they describe
  • Assuming C4 requires Structurizr — C4 is notation- and tool-independent

context