ADR-002: Choice of Implementation Language
Status
Accepted
Context
Bausteinsicht needs an implementation language for its CLI tool. The tool must:
-
Parse and generate JSON (architecture model, decided in ADR-001)
-
Parse and generate draw.io XML (mxGraph format)
-
Provide bidirectional synchronization between JSON model and draw.io XML
-
Offer CLI commands and a watch mode
-
Be easy for LLMs to generate code for (agentic coding)
-
Be easy to distribute to developers and architects
Constraints
-
JavaScript/Node.js is excluded due to security concerns with npm package managers
-
Target audience: developers and software architects with mixed language backgrounds
-
LLM-assisted development (agentic coding) is a key workflow
Evaluated Options
Option A: Go — Reference
A statically compiled language producing single-binary CLIs. Rich ecosystem for CLI tools (Cobra), XML processing (beevik/etree), and even dedicated mxGraph support (emicklei/mxgraph).
-
Single binary deployment — no runtime required
-
Cobra CLI framework (used by kubectl, gh, terraform, hugo)
-
encoding/jsonwith compile-time type safety via struct tags -
beevik/etreefor flexible XML manipulation (similar API to Python’s ElementTree) -
emicklei/mxgraph— dedicated Go package for writing mxGraph XML -
fsnotifyfor cross-platform file watching -
Near-instant startup (< 10ms)
-
No install-time code execution in Go modules (better supply chain security)
-
LLMs generate consistent Go code due to language simplicity and explicit patterns
-
Downside: more verbose than Python, learning curve for new Go developers
Option B: Python
A dynamically typed scripting language with batteries-included standard library.
-
xml.etree.ElementTreein standard library for XML processing -
jsonin standard library, Pydantic for schema validation -
Typer/Click for CLI framework
-
watchdogfor file watching -
Large LLM training corpus
-
Downside: requires Python runtime installation
-
Downside: packaging and distribution complexity (pipx, uv, virtual environments)
-
Downside: 50-300ms startup overhead
-
Downside: PyPI allows post-install script execution (supply chain attack surface)
-
Downside: no compile-time type checking without additional tooling
Option C: Kotlin/JVM
A JVM language with excellent XML/JSON tooling and potential Structurizr library integration.
-
Most mature XML/JSON libraries in the ecosystem (Jackson, JAXB, DOM4J)
-
Clikt CLI framework with idiomatic Kotlin DSL
-
Could directly import Structurizr’s Java library
-
Downside: JVM cold-start 200-500ms minimum
-
Downside: GraalVM native image needed for acceptable CLI UX (complex build, 90s+ compile)
-
Downside: GraalVM may fail with OOM on standard CI runners
-
Downside: split development/production model (JVM for dev, native for distribution)
Weighted Pugh Matrix
Rating scale: -1 = worse than reference, 0 = same as reference, +1 = better than reference
Reference option: A (Go)
| Criterion | Weight | A: Go (Ref) | B: Python | C: Kotlin/JVM |
|---|---|---|---|---|
Distribution simplicity |
5 |
0 |
-1 |
-1 |
LLM code generation quality |
5 |
0 |
0 |
-1 |
JSON processing (typed) |
4 |
0 |
-1 |
0 |
XML processing (draw.io) |
4 |
0 |
0 |
+1 |
CLI framework maturity |
4 |
0 |
0 |
0 |
Startup time |
3 |
0 |
-1 |
-1 |
Supply chain security |
3 |
0 |
-1 |
0 |
Learning curve |
3 |
0 |
+1 |
0 |
File watching |
2 |
0 |
0 |
0 |
Existing library ecosystem |
2 |
0 |
0 |
+1 |
Weighted Results
| Criterion | A: Go (Ref) | B: Python | C: Kotlin/JVM |
|---|---|---|---|
Distribution simplicity (×5) |
0 |
-5 |
-5 |
LLM code generation quality (×5) |
0 |
0 |
-5 |
JSON processing (×4) |
0 |
-4 |
0 |
XML processing (×4) |
0 |
0 |
+4 |
CLI framework maturity (×4) |
0 |
0 |
0 |
Startup time (×3) |
0 |
-3 |
-3 |
Supply chain security (×3) |
0 |
-3 |
0 |
Learning curve (×3) |
0 |
+3 |
0 |
File watching (×2) |
0 |
0 |
0 |
Existing library ecosystem (×2) |
0 |
0 |
+2 |
Total |
0 |
-12 |
-7 |
Decision
Option A: Go
Go provides the best overall fit for Bausteinsicht:
-
Single binary distribution: Developers download one file and are productive. No runtime installation, no package manager, no virtual environments.
-
LLM-friendly: Go’s simplicity (small language spec, explicit error handling, one way to do things) produces consistent, reviewable code when generated by LLMs. This directly supports the agentic coding workflow.
-
Compile-time type safety for JSON: The architecture model schema is enforced by Go structs. Schema changes are caught at compile time, not at runtime.
-
Dedicated mxGraph library:
emicklei/mxgraphprovides purpose-built Go support for the exact XML format we need. -
Proven CLI ecosystem: Cobra powers kubectl, gh, terraform, and hugo. The pattern is battle-tested and well-understood.
-
Supply chain security: Go modules never execute code at install time, reducing the attack surface compared to pip/npm.
The learning curve for a developer new to Go is an acceptable trade-off. Go’s simplicity means LLMs can assist effectively during the learning process itself.
Consequences
Positive
-
Near-instant CLI startup enables responsive interactive workflows
-
Cross-compilation to all platforms from a single build machine
-
Strong ecosystem of developer CLI tools as reference implementations
-
Go’s explicit style produces self-documenting code
-
go testprovides built-in testing framework with no additional dependencies
Negative
-
More verbose code compared to Python (mitigated by LLM assistance)
-
Go’s error handling requires explicit
if err != nilpatterns (verbose but clear) -
Team members unfamiliar with Go need onboarding time
-
Go’s XML standard library (
encoding/xml) has known limitations for dynamic attributes (mitigated by usingbeevik/etree)
Risks
-
If the Go mxGraph library (
emicklei/mxgraph) proves insufficient, we fall back tobeevik/etreefor raw XML manipulation — no vendor lock-in -
If Go’s learning curve proves too steep, the JSON-based architecture (ADR-001) means the CLI could be reimplemented in another language without changing the model format
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.