Skip to content

HeadlessCanvasThe handles are DOM elements

A canvas editor engine for design tools, whiteboards, diagram editors and annotation UIs. Shapes render to canvas; selection UI is DOM you style with CSS. MIT licensed, no watermark, no framework required.

Level 1 — the stock controls, unmodified

Why the controls are not painted into the canvas

Konva and Fabric draw selection handles into the canvas alongside the artwork. Two consequences follow, and neither can be worked around from application code: the handles cannot be restyled with CSS, and assistive technology cannot see them at all.

HeadlessCanvas splits the two layers:

┌─────────────────────────────────────┐
│  DOM overlay  — selection, handles  │  ← your CSS, your markup, keyboard accessible
├─────────────────────────────────────┤
│  Canvas       — shapes, images      │  ← fast rendering, no UI drawn here
└─────────────────────────────────────┘

tldraw shares this architecture but is not open source: production use requires a licence key, the watermark must stay unless you buy a commercial licence, and every downstream user of your project needs their own. HeadlessCanvas is MIT.

RenderingControls UIStyleable with CSSScreen-reader accessibleLicence
HeadlessCanvasCanvasDOMYesYesMIT
Konva.jsCanvasCanvasNoNoMIT
Fabric.jsCanvasCanvasNoNoMIT
tldrawDOM/SVGDOMYesPartialNot open source
ExcalidrawCanvasDOMIt is an app, not a reusable libraryMIT

Install

sh
npm install @headless-canvas/core @headless-canvas/ui
ts
import { Editor } from '@headless-canvas/core'
import { createDefaultControls } from '@headless-canvas/ui'
import '@headless-canvas/ui/styles.css'

const editor = new Editor({ container: document.querySelector('#app')! })
createDefaultControls(editor)

editor.createShape({ type: 'rect', x: 40, y: 40, width: 160, height: 110 })

That is the whole setup. Getting started covers the rest.

Released under the MIT License.