The Problem Bausteinsicht Solves

Architecture documentation goes stale. That’s not a matter of opinion, it’s practice. You draw a nice C4 diagram, the system keeps evolving, and three months later the picture no longer matches reality. Text-based tools like Structurizr or LikeC4 solve the problem from one side: text lives in Git, is versionable, diffable, reviewable. But you lose direct visual editability.

Bausteinsicht tries to hold onto both sides at once: the model lives as a JSONC file in the repository, draw.io is the visual frontend — and synchronization runs in both directions.

The Data Model: Three Formats, One Source of Truth

Internally, Bausteinsicht works with three formats at once:

FormatRole

architecture.jsonc

The model — source for elements, relationships, views

architecture.drawio

The draw.io XML — multiple pages, one per view

Go structs internally

Runtime representation for sync logic and CLI output

The JSONC model has three main sections: specification defines the allowed element types and relationship kinds; model contains the concrete elements with an optional children tree for hierarchies; views controls which elements appear in which diagram. Here’s a minimal example:

{
  "specification": {
    "elements": {
      "system":    { "notation": "Software System", "container": true },
      "container": { "notation": "Container" }
    },
    "relationships": {
      "uses": { "notation": "uses" }
    }
  },
  "model": {
    "shop": {
      "kind": "system", "title": "Online Shop",
      "children": {
        "api": { "kind": "container", "title": "REST API", "technology": "Go" },
        "db":  { "kind": "container", "title": "Database", "technology": "PostgreSQL" }
      }
    }
  },
  "views": {
    "containers": {
      "title": "Container View",
      "scope": "shop",
      "include": ["shop.*"]
    }
  }
}

Bidirectional Synchronization: The Actually Hard Part

The sync command is the heart of it. It has to detect changes from both directions and merge them — without silently dropping conflicts and without destroying layout information the user set by hand.

Bausteinsicht sync process

Concretely: if you add a new element in the JSONC, sync creates the corresponding node in the draw.io XML. Conversely, if you move a node in draw.io and save, sync reads the new position and writes it back into the model. What doesn’t get overwritten: manually set positions and sizes that don’t originate from the model. That’s the merge problem, and it isn’t trivial.

Another feature is relationship lifting. If a relationship exists between two elements that are both not directly visible in a view, Bausteinsicht automatically lifts the connector to the next visible parent element. That keeps views clean without removing relationships from the model.

The CLI: Complete, LLM-Ready

The CLI was built from the start to be usable not just by humans but also by AI agents. Every command supports --format json, which delivers machine-readable output on stdout and errors as structured JSON on stderr.

CommandWhat it does

init

Creates an example model + template

sync

Bidirectional synchronization JSONC ↔ draw.io

validate

Checks model consistency, outputs errors/warnings

watch

Continuous sync on file changes

add element

Add an element to the model via CLI (LLM-friendly)

add relationship

Add a relationship via CLI

export

PNG/SVG export via the draw.io CLI

export-diagram

Generate PlantUML-C4 or Mermaid-C4 from views

export-sequence

Sequence diagrams as PlantUML or Mermaid

export-table

Element attributes as an AsciiDoc or Markdown table

The --format json flag on every command was especially useful for my Claude Code workflows: I could query model state programmatically and feed in issues directly as structured changes, without text parsing.

My Contribution: Beta, Bugs, and 33 Issues

I was there for the first release as a beta tester — trying out the tool, finding edge cases, contributing small fixes. What’s instructive about that: you learn a tool’s limits before you build features for it.

After that, I systematically created GitHub issues — feature requests, UX considerations, missing export formats, CLI ergonomics. 33 issues, each with a clear scope. I took the next step with Claude Code: using the issues as a work basis, iterating in watch mode, implementing changes directly in the repository. In about two days, all of them were implemented as pull requests.

Statistics: 33 issues

What the experiment showed: the bottleneck isn’t writing code, it’s clear thinking beforehand. An issue with an unambiguous scope and acceptance criteria works excellently with Claude Code. A vague idea without context doesn’t. The quality of the input determines the quality of the output — that holds for AI-assisted development just as much as for any other kind of delegation.

Tutorial: Step by Step Through All the Features

I’m accompanying the release of Bausteinsicht with a 23-part tutorial series — from the first model to health score, workspace setup, and LLM workflows. A new part every day, starting 2026-06-11.

Try It Out

curl -Lo bausteinsicht.tar.gz \
  https://github.com/docToolchain/Bausteinsicht/releases/latest/download/bausteinsicht_linux_amd64.tar.gz
tar xzf bausteinsicht.tar.gz && sudo mv bausteinsicht /usr/local/bin/

bausteinsicht init
bausteinsicht sync

More information and documentation: https://github.com/docToolchain/Bausteinsicht