Solution · Canvas

Give every idea room to connect.

Shape ideas into a board, move through it with the keyboard, then export SVG or PNG. Your app owns persistence, image hosting and collaboration transport.

Status: in development

Isometric infinite canvas with sticky notes, frames and connectors built from cubes

Sketch a launch plan

Try this

  • Select a shape, then move it with the arrow keys or the move controls.
  • Add a priority note or select two shapes and connect them.
  • Undo an edit, open View source, and Reset the starting example.

Use Reset to return to the starting example.

ExploreTalk to twelve customersTest the first prototypeDecideChoose the beta scopeWrite the quality barBuildBuild the betaPrepare the release
Launch plan canvas preview
  • Explore (Frame)
  • Talk to twelve customers (Sticky note)
  • Test the first prototype (Sticky note)
  • Decide (Frame)
  • Choose the beta scope (Sticky note)
  • Write the quality bar (Sticky note)
  • Build (Frame)
  • Build the beta (Sticky note)
  • Prepare the release (Sticky note)
  • Connector from Test the first prototype (Sticky note) to Choose the beta scope (Sticky note)
  • Connector from Write the quality bar (Sticky note) to Build the beta (Sticky note)

0 shapes selected

Launch plan canvas loaded. Select a shape or use the canvas controls.

ExploreTalk to twelve customersTest the first prototypeDecideChoose the beta scopeWrite the quality barBuildBuild the betaPrepare the release
Launch plan canvas
  • Explore (Frame)
  • Talk to twelve customers (Sticky note)
  • Test the first prototype (Sticky note)
  • Decide (Frame)
  • Choose the beta scope (Sticky note)
  • Write the quality bar (Sticky note)
  • Build (Frame)
  • Build the beta (Sticky note)
  • Prepare the release (Sticky note)
  • Connector from Test the first prototype (Sticky note) to Choose the beta scope (Sticky note)
  • Connector from Write the quality bar (Sticky note) to Build the beta (Sticky note)

Canvas shapes

Select a shape. Use the arrow keys to move it, or hold the selection toggle to choose two shapes to connect.

If the interactive demo cannot load, use the static preview above.

What a canvas can do

Turn scattered ideas into a clear board

Arrange shapes, notes, images, frames and groups, then connect them with straight, elbow or curved lines. Snapping transforms and reversible operations keep each edit in the board history.

  • Draw
Isometric canvas of sticky notes, frames and elbow connectors assembling from violet cubes

Keep every shape within keyboard reach

Move through shapes in reading order, or use the shape tree to find a shape or connector. Focus and edits stay visible and are announced as you work.

  • Keyboard and tree navigation
Isometric canvas with one focused shape and a shape-tree of small cards built from cubes

Keep shared boards in step

The document sync adapter validates each batch and applies the same canvas rules on every replica. Your app supplies the transport; Texuli does not host a realtime service.

  • Local collaboration
Two identical isometric canvas boards linked through a glass sync tile of cubes

Carry the board into SVG or PNG

Export escaped SVG or render a PNG in the browser. Text stays text in the SVG output, and image URLs follow the URL policy.

  • Export
A wide whiteboard with lilac and orange sticky cubes, shapes and dashed connector arrows

From shape model to SVG or PNG.

  1. Model

    Define shapes and connectors as validated data with reversible operations.

    Package: @texuli/canvas

  2. Edit

    Edit on a canvas with pan, zoom, snapping and transforms.

    Package: @texuli/canvas

  3. View

    Show a read-only canvas with its structure as text and a shape tree.

    Package: @texuli/canvas

  4. Sync

    Sync replicas through the document adapter; your app supplies transport.

    Package: @texuli/canvas

  5. Export

    Export SVG or browser-rendered PNG; image URLs follow the URL policy.

    Package: @texuli/canvas

Canvas is built from @texuli/canvas, on texuli, @texuli/document, @texuli/core, @texuli/deck and @texuli/drag.

Solution

Canvas

Packages

  • L4@texuli/canvasCanvas model, editor, viewer, sync and exportSubpaths: ./model · ./editor · ./viewer · ./sync · ./export

Built on

  • L3texuli (Styled components)
  • L1@texuli/document (Document engine)
  • L0@texuli/core (Texels and the URL policy)
  • L0@texuli/deck (Deck model and engine)
  • L0@texuli/drag (Drag engine)
Five-stage isometric pipeline from a shape model through edit, view and sync to an export card

Build with Canvas

Start with a canvas

Install

pnpm add @texuli/canvas

Create a canvas

import { applyCanvasOps, createCanvas } from '@texuli/canvas/model';

const canvas = createCanvas({ title: 'Launch plan' });
const added = applyCanvasOps(canvas, [
  {
    op: 'add',
    shape: { id: 'ship', type: 'sticky', x: 0, y: 0, width: 160, height: 160, text: 'Ship' },
  },
]);

if (added.ok) {
  console.log(added.doc.shapes.length);
}

Load untrusted JSON

import { loadUntrustedCanvas } from '@texuli/canvas/model';

const result = loadUntrustedCanvas({
  "format": "texuli-canvas",
  "formatVersion": 1,
  "meta": {
    "title": "Launch plan",
    "locale": "en"
  },
  "grid": 8,
  "shapes": [
    {
      "id": "ship",
      "type": "sticky",
      "x": 0,
      "y": 0,
      "width": 160,
      "height": 160,
      "text": "Ship the Northwind beta",
      "color": "yellow"
    }
  ],
  "connectors": []
});

if (result.ok) {
  console.log(result.canvas.shapes.map((shape) => shape.id));
}

Edit with CanvasEditor

<script lang="ts">
  import { CanvasEditor } from '@texuli/canvas/editor';
  import { loadUntrustedCanvas } from '@texuli/canvas/model';
  import '@texuli/tokens/base.css';

  const loaded = loadUntrustedCanvas({"format":"texuli-canvas","formatVersion":1,"meta":{"title":"Launch plan","locale":"en"},"grid":8,"shapes":[{"id":"ship","type":"sticky","x":0,"y":0,"width":160,"height":160,"text":"Ship the Northwind beta","color":"yellow"}],"connectors":[]});
  let canvas = $state.raw(loaded.ok ? loaded.canvas : null);
</script>

{#if canvas}
  <CanvasEditor bind:canvas />
{/if}

Verified by apps/website/tests/solutions/canvas-quickstart.test.ts

Recipes

For agents

Agents emit a canvas as data through the canvas catalog id. The host app checks it with validateDraft and the canvas check before painting; the remote MCP server refuses canvas nodes. The packages are in development.

  • canvascanvas: In development

    Catalog component that carries a whole canvas in its canvas prop.

  • validateDraftvalidateDraft: In development

    Catalog check; canvas nodes pass only with the checkCanvas hook from the canvas host.

  • skills/texuli/blueprints/SKILL.mdskills/texuli/blueprints/SKILL.md: In development

    Skill stage J: forms, canvases, sheets and data sources as agent data.

Platforms

  • Web

    Web: In development

    Svelte 5 packages published on npm (pre-1.0).

  • Compose Desktop

    Compose Desktop: Planned

    Kotlin Multiplatform renderer on the JVM, built in this repository.

  • Android

    Android: Planned

    Native renderer target.

  • iOS

    iOS: Planned

    Native renderer target.

How the native renderer works

Start building with Canvas

An embeddable whiteboard with shapes, connectors and export.

A low horizon of stacked cubes rising to one glowing pearl cube under a wide open skyA low horizon of stacked cubes rising to one glowing pearl cube under a wide open sky