March 25, 2026

Lukasz Paciorkowski

Lukasz Paciorkowski

Founder

How we built real-time collaboration on a 7-layer canvas

"Figma for architecture" sounds simple until you try to build it on a layered semantic model with two notation standards. Here are the failure modes of the obvious approaches and the design that finally works.

Real-time multi-user collaboration on a 7-layer ArchiMate canvas

Real-time multi-user editing across a full 7-layer ArchiMate canvas, with BPMN process flows on the same canvas, with no merge conflicts and no "you need to refresh, someone else changed something" — that's the bar. "Figma for architecture" is the shorthand. The hard part isn't visible from the outside; this post is about why the obvious approaches don't work and what design does.


Why this is harder than collaborative documents

If you've built anything collaborative on a normal document model — a shared text doc, a spreadsheet, a Figma canvas of boxes and lines — the standard toolkit is CRDTs (conflict-free replicated data types) or operational transforms. Two users type at once, the system reconciles the edits, everyone sees a consistent result. Solved problem.

ArchiMate isn't a normal document. The thing that makes it hard is that it's not really a flat graph of boxes and arrows — it's a layered semantic model where elements at one layer have meaning defined by their relationships across other layers. A "business actor" element isn't just a labeled box; it carries semantic weight that's resolved against the business-layer rules. When you delete a business actor, you're not just removing a box — you're potentially orphaning every business-service relationship that depended on it, possibly cascading down through application services and into technology infrastructure.

So when User A says "delete this business actor" and User B simultaneously says "add an application service that derives from that actor's role in the upstream value chain," the system has to do more than CRDT merge. It has to know what's semantically valid in ArchiMate, surface the conflict in a way that makes sense to a human, and let the two users resolve it without losing either intent.

Now add BPMN. BPMN is its own semantic universe — gateways, message flows, pool/swimlane participants, with rules about which element types can connect to which others, none of which line up with ArchiMate's rules. We wanted both on the same canvas, both editable simultaneously, both consistent with their own standards.

That's the problem space. Below are the failure modes of the obvious approaches.


Why "treat it as a flat graph" fails

The obvious first approach: pretend ArchiMate and BPMN are both just typed graphs of nodes and edges. Use a CRDT library over the graph. Wrap the standard validation as a post-merge check that flags inconsistencies after the fact.

This works fine for one or two users editing a single layer. It collapses the moment several architects open different views simultaneously and start moving cross-layer elements around.

Here's a specific failure mode worth understanding. Imagine a capability in the business layer being renamed by one user. Almost simultaneously another user moves the same capability into a different value-stream container at the strategy layer. A naive CRDT merges both edits — the capability now has the new name AND lives in the new container. Sounds fine. But the ArchiMate spec says that capability's name is also the label that appears on the upstream strategy-layer relationships. Those relationships didn't get updated. They still show the old name. The model is internally inconsistent and no one notices until a downstream validator runs.

When the post-merge validator finally catches it, the warning it surfaces is something like "naming inconsistency" — which neither user can interpret. They were working in different layers and have no idea their edits collided.

You can't validate post-merge — by the time the merge happens, the semantic context that explains the conflict is gone.

Why "lock cross-layer relationships" also fails

The next intuition is to fix that by locking cross-layer relationships during edits. The idea: if a user is editing a business-layer element that has relationships to other layers, those relationships get a soft lock — other users can still see them, but if they try to edit something that depends on the locked element, they get a notification.

This doesn't deadlock, exactly, but it generates so many false positives that people stop trusting the notifications. Every minor label tweak triggers "User X is editing a related element" banners on other people's screens. Worse, the locks aren't fine-grained enough — locking a business actor effectively locks every downstream relationship, which means editing high-traffic elements becomes serialized in practice. Real-time collaboration that's actually serial collaboration isn't what was promised.

The deeper lesson here: the conflicts aren't usually at the element level. They're at the semantic intent level. Two users editing the same element are often making complementary edits, not conflicting ones — if you understand what each user is trying to accomplish, you can merge them. The lock-based approach is too coarse and gives up before trying to be smart.


What does work

The design we shipped uses three ideas together. None of them are individually novel — the combination is.

01

Per-layer CRDT with cross-layer semantic anchors.

Each ArchiMate layer (and each BPMN process) has its own CRDT state. Edits within a layer use standard merging — fast, conflict-free, well-understood. The cross-layer relationships are represented as anchors rather than as direct references. An anchor knows what element it points to, what semantic property it depends on (e.g., "name," "data classification," "owner"), and what to do if that property changes.

When a user renames a capability, the system traverses the anchors that point to it. For each anchor, it checks: does the renaming affect what this anchor cares about? If yes, the anchor's owning relationship updates atomically. If no, nothing happens. Cross-layer changes propagate where they should and stay quiet where they shouldn't.

02

Intent-aware merge for elements.

When two users edit the same element, the system looks at what changed, not just that something changed. If one user renamed the element and another moved it to a different container, those are independent intents — both are applied, no conflict surfaced. If both users renamed it but to different names, that's a true conflict; the system surfaces it inline on both screens with both names visible, and lets either user accept either version.

This is significantly more code than CRDT-as-text-merge, but it eliminates the "the model is silently wrong" failure mode that the flat-graph approach suffers.

03

BPMN as a typed sub-canvas with explicit ArchiMate bindings.

Don't try to make BPMN and ArchiMate live in the same flat graph. Instead, treat BPMN processes as typed sub-canvases hosted within ArchiMate business-layer process elements. The BPMN canvas has its own internal validation rules (per the BPMN spec). The binding back to ArchiMate is explicit: a BPMN message-flow knows it's bound to an ArchiMate business interaction, and changes to one propagate to the other through the same anchor mechanism used for cross-layer ArchiMate.

This sounds obvious in retrospect — keep the two standards in their own consistent worlds, give them a bridge — but the design pull is always toward "unification." Unified turns out to mean "both standards' invariants are constantly violated." Separated-with-bridge means each standard stays coherent and the bridge handles translation explicitly.


What "it works" feels like

The bar for collaborative tools that work isn't just functional — it's about invisibility. In a good collaborative environment, you stop noticing the collaboration mechanism. You're just working, and the tool stays out of the way. The Figma comparison isn't about the visual style; it's about that invisibility.

Cursors move at the same time. Edits land in the same instant. Nothing conflicts, nothing locks, nothing freezes. It feels unremarkable — which is exactly the point.

What's still hard

A few things worth being honest about because the demo doesn't show them:

  • Very large models with many simultaneous editors still have latency we'd like to remove. When the model has thousands of elements and a dozen people are editing across all seven layers, the cross-layer anchor traversal can briefly stall. We have a plan; it isn't fully shipped.
  • Undo across users is a partially-solved problem. Personal undo (your edit, your undo) works well. "Undo this collaborative change" is conceptually harder and we're still iterating.
  • Branch-and-merge workflows for major architecture changes — the kind you'd want before a big refactor of the business layer — aren't part of real-time collab. They live in a separate model-versioning system. We may collapse the two eventually; for now they're separate tools.

I list these because too many engineering write-ups claim everything works and then quietly omit the parts that don't. Better to say what's still hard than pretend.


What this means for EA teams

For teams that have done architecture modeling in tools that forced single-author workflows, the practical implication is straightforward: the model isn't a serial single-author artifact anymore. Multiple architects can work on the same model at the same time, in different layers, with no fear of stepping on each other's work. The model isn't a document anyone owns — it's a shared resource the team maintains together.

That changes a few things:

  • Reviews happen in the model, not in screenshots. When someone proposes a change, the reviewer opens the canvas and sees it in context. No more PDF exports.
  • Onboarding new architects is faster. They can pair on the canvas with a senior architect for a day and see how decisions get made in real time.
  • The model stays current. When updating it is cheap and unblocked, it actually happens. The stale-diagram problem mostly goes away because updates aren't a project — they're a side effect of normal work.

That last point is the one I care about most. The most expensive thing in EA isn't the modeling — it's the gap between what the model says and what the architecture actually is. Closing that gap requires making the model trivially easy to update. Real-time collaboration is one of several pieces of that.

If you're building something similar, hopefully this saves you the obvious mistakes.