1. Interaction-Centric Modeling
Architecture should be modeled around how systems interact, not how infrastructure is deployed.
When an engineer is debugging why an order notification is delayed, they think:
- What service publishes the
order-createdevent? - What service consumes it?
- Is there a queue in between?
They do not think about which Kafka broker hosts the topic or which availability zone it lives in.
Archy diagrams answer the questions engineers actually ask during an incident, an onboarding, or a design review.
In practice: Model a Kafka topic as a node. Model an SQS queue as a node. These are the interaction surfaces that matter. The broker or cluster they live on belongs in _meta.
2. Everything Is a Node
Archy has one modeling primitive: the node.
Services, APIs, Kafka topics, queues, databases, frontends, batch jobs, external systems, human actors — all nodes. There are no special first-class types with their own schemas. Just { "id": ..., "type": ... }.
{ "id": "orders-api", "type": "service" }
{ "id": "order-created", "type": "kafka-topic" }
{ "id": "orders-db", "type": "database" }
{ "id": "customer", "type": "actor" }
New architectural concepts (new compute primitives, new storage types) become new entries in the node type registry — not new schemas.
3. Edges Describe System Behavior
Edges should say what happens between systems, not that a structural dependency exists.
| Use this | Not this |
|---|---|
calls | depends_on |
publishes | connected_to |
consumes | linked_with |
writes | references |
triggers | uses (when you mean something specific) |
A diagram filled with depends_on edges tells you topology. A diagram filled with calls, publishes, and consumes tells you behavior. The second is useful in a post-mortem. The first is not.
The full edge vocabulary:
| Edge type | Meaning |
|---|---|
calls | Synchronous RPC, REST, or gRPC call |
publishes | Producer emits events to a topic or queue |
consumes | Consumer reads events from a topic or queue |
writes | Service writes data to a store |
reads | Service reads data from a store |
streams | Continuous data flow (CDC, Kinesis, WebSocket) |
triggers | One node causes another to run (webhook, scheduler) |
uses | General-purpose fallback |
4. The Format Must Stay Human-Writable
Because Archy lives in VS Code alongside your code, the format is designed for direct editing — not export.
- Minimal boilerplate — a valid diagram is 6 lines of JSON
- Diff-friendly — adding a node or edge is one JSON object, easy to review in a PR
- Incrementally editable — type a new node and edge without restructuring anything
- Readable at a glance — a 20-node
.archyfile should be understandable without running it
No deep nesting. No required schema URLs. No lists of interfaces to define before you can reference a node.
5. Infrastructure Details Are Metadata
Information like Kafka partition counts, cluster names, cloud regions, container images, and retention policies is not part of the architecture model. It belongs in _meta.
{
"id": "order-created",
"type": "kafka-topic",
"_meta": {
"cluster": "payments-cluster",
"partitions": 12,
"retention": "7d"
}
}
This separation keeps diagrams conceptual. A diagram showing services, topics, and databases communicating is useful to a new engineer, a TPM, a PO, and an on-call engineer. A diagram where every node has 15 infrastructure fields is useful to nobody at a glance.
_meta is visible in the detail panel when you click a node. It doesn't affect how the node looks on the canvas.
6. Structure Should Be Optional
You should be able to start with three nodes and grow the diagram organically.
{
"version": "2",
"nodes": [
{ "id": "frontend", "type": "frontend" },
{ "id": "api", "type": "service" },
{ "id": "db", "type": "database" }
],
"edges": [
{ "id": "e1", "from": "frontend", "to": "api", "type": "calls" },
{ "id": "e2", "from": "api", "to": "db", "type": "writes" }
]
}
Later you add more nodes and edges. You never need to declare everything upfront. Fields like name, description, _meta, groups, and x-archy are all optional.
7. Diagrams Should Reveal System Flow
A developer looking at an Archy diagram should immediately understand:
- How requests enter the system
- How events propagate
- Where data is stored
- What reacts to what
The edge types and node types together tell the story. For example:
Customer (actor)
→ uses → Web Browser (frontend)
→ calls → API Gateway (gateway)
→ calls → Order Service (service)
→ publishes → order-created (kafka-topic)
→ consumes → Notification Service (service)
→ writes → Orders DB (database)
This is what Archy renders. The edges carry the semantics and the node types carry the visual context.
8. The Schema Must Stay Small
The entire Archy v2 format has four top-level concepts:
| Concept | Purpose |
|---|---|
nodes | What exists in the system |
edges | How things interact |
groups | How things are organized (domains, zones) |
_meta | Infrastructure and operational detail |
Everything else — display names, positions, notes, metadata — is optional enrichment on top of these four primitives. This makes Archy easy to learn and easy to extend.
Groups
Groups let you draw boundaries around sets of nodes. Two group types:
logical — a domain or team boundary (e.g. "Payments Domain", "Core Services"). Rendered as a solid-bordered region.
zone — a network or infrastructure boundary (e.g. "Internal VPC", "DMZ"). Rendered as a dashed-bordered region.
{
"id": "payments-domain",
"label": "Payments Domain",
"type": "logical",
"nodes": ["payment-service", "payments-db", "charge-topic"],
"_meta": { "team": "payments-team" }
}
Groups are purely visual — they don't affect edge routing or node behavior. When you drag a node, the group boundary updates automatically.
What belongs where
| Information | Where it goes |
|---|---|
| Service name | nodes[].name |
| What a service does | nodes[].description |
| How it talks to another service | edges[].type + edges[].label |
| Technology stack, team, compliance | nodes[]._meta |
| Latency SLAs, auth method, timeouts | edges[]._meta |
| Architecture decisions, runbook links, caveats | nodes[].notes or edges[].notes |
| Network zone, VPC, domain boundary | groups[] |
| Canvas positions | x-archy.positions (managed by editor) |