Canvas
Canvas is a built-in whiteboard and diagram editor inside every Nexion project tab. Powered by Excalidraw, it gives you an infinite hand-drawn canvas to sketch architecture diagrams, wireframes, flow charts, or quick notes: all without leaving your workspace.
Overview
Canvas runs in an isolated WKWebView with Excalidraw, React 18, and ReactDOM bundled locally: no internet connection required and no data is sent remotely.
-
•
File format: Standard
.excalidrawJSON (version 2). Compatible with the Excalidraw web app: open, share, or commit to Git like any other file. - • Autosave: Changes are persisted automatically with an 800 ms debounce after each edit. Untitled canvases (not yet saved to disk) are excluded from autosave.
-
•
Unsaved indicator: A dot appears in the tab header when there are unsaved changes.
Cmd+Ssaves immediately. - • Isolation: The Canvas WKWebView uses a non-persistent data store: no cookies, no cache shared with browser tabs.
Opening a Canvas
Cmd+Shift+K creates a new Canvas tab in the current projectCmd+S saves the active canvas when a Canvas tab is focused
Canvas files can also be opened from Finder by double-clicking any .excalidraw file. On close, Nexion prompts to Save or Discard if there are unsaved changes.
Drawing Tools
All standard Excalidraw tools are available. Shapes render in a hand-drawn style designed to keep diagrams informal and easy to iterate on.
- •
Cmd+Aselect all ·Cmd+Ggroup ·Cmd+Shift+Gungroup - •
Ctrl+scrollor pinch: zoom ·Space+drag: pan - •
Cmd+Shift+F: fit all elements into view - •
Cmd+Z/Cmd+Shift+Z: undo / redo (full history)
CLI
The nexion canvas subcommand exposes all canvas operations from the terminal. Every command accepts an optional --tab-id UUID flag to target a specific tab; without it, the active canvas tab is used.
Export
Render the canvas to a file or print to stdout:
Read & write the scene
Get or replace the full scene JSON:
Manipulate elements
View control & utilities
Floating dialog
Open a standalone canvas dialog: useful for plugins or scripts that need a quick sketch without opening a full tab. Returns the scene JSON on save, exits silently on cancel.
IPC & Socket
The canvas.* methods are available on the Nexion Unix socket (~/.nexion/nexion.sock) via JSON-RPC 2.0. All parameters are optional unless noted. Every method returns {"ok": true} on success or an error object on failure.
Methods
| Method | Params (besides tab_id) | Description |
|---|---|---|
canvas.save |
- | Persist active canvas to disk |
canvas.getScene |
- | Return scene as JSON string in {scene} |
canvas.setScene |
scene: string |
Replace entire scene from JSON string |
canvas.appendElements |
elements: string|array |
Add elements to current scene |
canvas.updateElements |
patches: array of {id, …} |
Patch existing elements by id |
canvas.removeElements |
ids: array of strings |
Delete elements by id |
canvas.export |
format: "png"|"svg"|"json" |
Render and export. Without output returns payload in response. |
canvas.zoom |
value: "fit"|"reset"|number |
Control zoom level |
canvas.snapshot |
- | Record an undo checkpoint |
canvas.theme |
theme: "light"|"dark" |
Switch canvas theme |
canvas.showDialog |
initialScene?, title?, |
Open floating dialog. Returns {cancelled, scene?} |
Raw socket example
See the CLI docs for the full framing protocol and authentication details.
Plugin API
Plugins access Canvas through the nexion.canvas namespace. Methods are split across three permission gates: canvas.read, canvas.write, and canvas.dialog. Synchronous methods return a boolean; async methods use a callback.
| Method | Permission | Notes |
|---|---|---|
nexion.canvas.getScene(cb) |
canvas.read |
cb receives scene JSON string or null |
nexion.canvas.export(format, cb) |
canvas.read |
"png" → data URL · "svg" → XML · "json" → string |
nexion.canvas.setScene(json) |
canvas.write |
Sync - returns boolean |
nexion.canvas.appendElements(json) |
canvas.write |
Sync - returns boolean |
nexion.canvas.updateElements(json) |
canvas.write |
Sync - patches by id, returns boolean |
nexion.canvas.removeElements(json) |
canvas.write |
Sync - json is array of id strings |
nexion.canvas.setZoom(value) |
canvas.write |
"fit" · "reset" · numeric string |
nexion.canvas.snapshot() |
canvas.write |
Record undo checkpoint, sync |
nexion.canvas.save(cb) |
canvas.write |
cb receives (ok: bool, error: string|null) |
nexion.canvas.setTheme(theme) |
canvas.write |
"light" or "dark", sync |
nexion.canvas.showDialog(opts, cb) |
canvas.dialog |
cb receives scene JSON (saved) or null (cancelled) |
Example plugin
A Command Palette action that exports the canvas as PNG and attaches it to the project note:
See the Plugin Development docs for a full reference of available namespaces and permission keys.
A Drawing in a Window of Its Own
Move to New Window sends a canvas, whether it is a tab or a pane beside a terminal, to a plain window of its own: handy on a second screen while you work in the first. The editor is moved rather than reopened, so the scene, the undo history and where you were zoomed all come across, and none of those survive a reload from the file. Closing the window brings it back where it came from. A drawing that is not a file on disk yet cannot be moved: it would have nowhere to come back to if its tab were closed while it was out.
Using Canvas with AI Agents
Because the canvas lives in the same window as your terminal, you can sketch a diagram and immediately hand it to an AI agent as context: no window switching, no screenshot hunting.
nexion canvas export --format png --output /tmp/diagram.png from the terminal inside Nexion.@path reference directly into your agent prompt.Attribution
Canvas is powered by Excalidraw and React, both bundled inside the app. Full attribution is listed on the Acknowledgements page.