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 .excalidraw JSON (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+S saves immediately.
  • • Isolation: The Canvas WKWebView uses a non-persistent data store: no cookies, no cache shared with browser tabs.

Opening a Canvas

New Canvas tab
Cmd+Shift+K creates a new Canvas tab in the current project
Save
Cmd+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.

V
Selection
Select, move, resize, and group elements
R
Rectangle
Boxes, containers, swim lanes
D
Diamond
Decision nodes in flow charts
E
Ellipse
Circles, ovals, state nodes
A
Arrow
Directed edges between elements
L
Line
Connectors without arrowheads
P
Freehand
Annotations, callouts, quick sketches
T
Text
Labels, headings, inline notes
I
Image
Embed screenshots or reference images
E
Eraser
Remove elements without undo
  • • Cmd+A select all  ·  Cmd+G group  ·  Cmd+Shift+G ungroup
  • • Ctrl+scroll or 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:

# Export as PNG to file
$ nexion canvas export --format png --output diagram.png

# Export as SVG to stdout
$ nexion canvas export --format svg

# Export raw scene JSON
$ nexion canvas export --format json --output scene.json

Read & write the scene

Get or replace the full scene JSON:

# Print current scene JSON
$ nexion canvas get-scene

# Replace scene from file
$ nexion canvas set-scene new-diagram.excalidraw

# Replace scene from stdin
$ cat scene.json | nexion canvas set-scene -

Manipulate elements

# Append elements from a JSON file
$ nexion canvas append elements.json

# Patch existing elements by id
$ nexion canvas update-elements patches.json

# Remove elements by id
$ nexion canvas remove-elements id1 id2 id3

View control & utilities

# Zoom
$ nexion canvas zoom fit     # fit all elements
$ nexion canvas zoom reset   # 100%
$ nexion canvas zoom 1.5     # 150%

# Switch theme
$ nexion canvas theme dark

# Record an undo checkpoint
$ nexion canvas snapshot

# Persist to disk immediately
$ nexion canvas save

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.

$ nexion canvas show-dialog --title "Sprint planning" --width 1200 --height 800

# Pre-load an existing scene
$ nexion canvas show-dialog --initial-scene draft.excalidraw --read-only

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"
output?: string (path)
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?,
width?, height?, readOnly?,
theme?, saveButtonTitle?,
cancelButtonTitle?
Open floating dialog. Returns {cancelled, scene?}

Raw socket example

# Export canvas as PNG via raw socket
$ echo '{"jsonrpc":"2.0","id":1,"method":"canvas.export","params":{"format":"png","output":"/tmp/canvas.png"}}' \
  | nc -U ~/.nexion/nexion.sock
{"jsonrpc":"2.0","id":1,"result":{"path":"/tmp/canvas.png","format":"png"}}

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:

export-canvas.js
nexion.palette.register({
  id:    'canvas.export-to-note',
  title: 'Canvas: Export and attach to note',
  permissions: ['canvas.read', 'notes.write'],
  run() {
    nexion.canvas.export('png', function(dataURL) {
      if (!dataURL) return;
      // dataURL is a base64 PNG - save to a temp path first
      const path = `/tmp/canvas-${Date.now()}.png`;
      nexion.fs.writeDataURL(path, dataURL, function(ok) {
        if (!ok) return;
        nexion.notes.attach(path);
        nexion.notify('Canvas exported and attached to 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.

1
Sketch
Draw your architecture, data model, or feature flow on the Canvas tab.
2
Export
Run nexion canvas export --format png --output /tmp/diagram.png from the terminal inside Nexion.
3
Reference
Right-click the exported file in Finder and insert it as an @path reference directly into your agent prompt.
4
Prompt
The AI agent receives the diagram as context alongside your code: no manual copying or describing needed.

Attribution

Canvas is powered by Excalidraw and React, both bundled inside the app. Full attribution is listed on the Acknowledgements page.