How Legon's Plugin Architecture Works
A developer-level tour of Legon, Lega's command-driven, plugin-composable canvas editor core, and why that architecture matters for building an AI-native design tool.

Most canvas editors are built as a single, sprawling application: one giant component tree wired directly to mouse events, keyboard shortcuts, and rendering logic. That works, until it doesn't. Add undo/redo. Add AI-driven edits. Add multi-frame documents. Every new capability tangles further into the same knot of state.
Legon, the canvas editor library underneath Lega, was built differently from day one. It borrows the plugin-and-command architecture popularized by Lexical, Meta's text editor framework, and applies it to a design canvas instead of a document. If you have never worked inside an editor built this way, the difference is worth understanding, because it is the reason Lega can let both a human and an AI model edit the same document safely.
The Core Idea: Editors Are State Machines, Not UI Trees
The foundational decision in Legon is that the canvas is not the source of truth. The editor state is. LegonEditorState is a plain, serializable representation of every layer, frame, and property in a document. The canvas, the layers panel, the properties panel, and the AI system are all just views and writers against that one state object.
This sounds obvious in the abstract, but most drag-and-drop canvas tools skip it. They let a <div>'s inline style or a shape's rendered attributes become the truth, and reconciling that with undo history or programmatic edits turns into a mess of special cases. Legon refuses that shortcut. Nothing changes the canvas directly. Everything goes through the state.
Commands: The Only Way to Change Anything
If the state is the truth, something has to be the only legitimate way to mutate it. In Legon, that is the command. A command is a small, typed, serializable description of an intent: move this layer, resize this frame, change this fill color. Every user action, every AI-driven edit, every programmatic script interaction gets translated into a command before it touches state.
This has three consequences that ripple through the entire product:
Undo/redo is free. Because every mutation is a discrete command object, the editor can maintain a full command history and step backward or forward through it without ad hoc snapshotting logic. Read more about what that means for users in Undo/Redo & History.
AI and humans share one interface. When Lega's AI generates a layout or applies a style, it does not reach into the DOM or manipulate layer objects directly. It emits the same commands a human editing session would emit. That means every safety check, every validation pass, and every undo boundary that applies to human edits applies equally to AI edits. There is no privileged, unaudited code path for AI-driven changes.
State transitions are auditable and testable. A command is a pure description of a change. You can unit test "moving layer X by (10, 20) produces state Y" without ever mounting a component or touching a canvas element. This matters enormously for a codebase that has to stay reliable while AI features expand quickly.
Plugins: Composing Behavior Without a God Object
The second half of the architecture is the plugin system. Instead of one editor component that knows about every feature, LegonComposer provides a minimal shell, and behavior is composed by mounting plugins as children:
<LegonComposer canvas={{ width: 800, height: 600, backgroundColor: '#fff' }}>
<LegonHistoryPlugin />
<LegonKeyboardShortcutsPlugin />
<MyEditorUI />
</LegonComposer>
Each plugin registers command handlers, listens for specific state transitions, or contributes rendering behavior, without needing to know about the other plugins mounted alongside it. History tracking, keyboard shortcuts, smart guides, and export are all separable concerns that can be developed, tested, and reasoned about independently.
This composability is why Lega's editor can support two rendering backends, a Canvas2D scene renderer and a legacy SVG fallback, from one compiled scene without duplicating editor logic. The plugin boundary keeps rendering strategy decoupled from state and command logic. We wrote a companion piece on the practical lessons from building that dual renderer in Building a Dual-Renderer Canvas: Lessons Learned.
Why This Matters for an AI-First Editor
An AI-native design tool has a requirement that most canvas editors were never built for: a non-human agent needs to make structured, often large, edits to a document that a human is simultaneously looking at and might want to partially undo. If your editor's only interface is "call this function that mutates internal state," you cannot safely give that access to an AI system without also handing it the ability to corrupt state, break undo history, or bypass validation.
Legon's command boundary solves this by construction. The AI adapter system that decides what to generate is a separate concern (covered in How Lega's AI Adapter System Works) from the mechanism that applies those decisions to the document. AI output gets normalized into the same typed layer and command shapes a human session produces, then flows through the identical command pipeline. That is not an accident of implementation convenience. It is the reason the architecture was chosen.
The Trade-off, Honestly
Command-based, plugin-composed architectures have a real cost: more indirection. A junior engineer's first instinct when adding a feature is often to reach directly into state, and the framework has to actively resist that instinct through code review and typed APIs. Onboarding takes slightly longer than it would with a more direct, if messier, approach.
We think that cost is worth paying. For a general overview of how this fits into Lega's broader editor design, see Legon Editor Overview and the higher-level Editor Architecture Overview. The alternative, an editor where "make this change" has more than one code path, does not survive contact with an AI system that is going to be making a large and growing share of the edits in every document.