Declarative Canvas UI for the browser, inspired by Swift — Martín Romañuk

2 min read Original article ↗

I read this post and immediately started wondering how it would look. I didn’t know that Google Spreadsheets use canvas to render their UI, or that Figma does too. Now it seems pretty obvious. A few years ago I would have stopped right there, but now we have LLM agents at our disposal.

The article mentions these 4 reasons to use it for UIs:

  • Fast
  • Control
  • Consistency
  • Portability

All of this sounds like a canvas — pun very much intended — to build multiplatform apps, for web, desktop, or mobile.

Basically, I followed the post’s advice and built WeaveKit, a declarative Canvas UI toolkit.

If you’re interested, you can check out WeaveKit. The syntax is heavily inspired by SwiftUI. It’s just syntactic sugar on top, using dslToJs().

VStack {
  Text('Hello, world')
    .font({ size: 28, weight: 700 })
}
.padding(20)

running on this very same page:

It’s possible to wire up a button and state.

Reactive example


const clicks = signal(0)

VStack {
  spacing: 10
  align: 'leading'
  Text(() => 'clicks: ' + clicks())
    .font({ size: 26, weight: 700 })
    .foreground('#fafafa')
  Button('+1', () => clicks.set(n => n + 1))
}
.padding(20)

This part wires and mount everything:

// dslToJs rewrites the blocks to plain JS; new Function puts the
// toolkit in scope. Runs once — the signal is created here, not
// per frame — and the trailing expression is returned implicitly.
const buildView = new Function(
  'Button', 'Text', 'VStack', 'signal',
  dslToJs(source).code,
)
const view = buildView(Button, Text, VStack, signal)

mount(document.getElementById('app'), createCanvasBackend(), () => view)

Give it a spin — clone WeaveKit and run the examples in your own page.