miso

Platform

Internals

Internally miso uses a global event queue and a scheduler to process all events raised by components throughout the lifetime of an application. Events are processed in FIFO order, batched by the component that raised them.

  • Event queue — all actions dispatched via a Sink (from event handlers, subscriptions or io callbacks) are enqueued and drained by the scheduler.
  • Scheduler — pulls actions off the queue one batch at a time, runs update for each, collects the resulting IO and executes it. Rendering (VDOM diff + patch) is triggered after each batch.
  • Waiter — a synchronisation primitive (Miso.Concurrent) that blocks the scheduler thread until new work arrives, avoiding busy-waiting.
  • Event delegation — rather than attaching listeners to individual nodes, miso attaches a single capture and a single bubble listener to <body>. Incoming events are routed through the virtual DOM tree to the matching handler, minimising listener churn when the VDOM is patched.
  • VDOM diffing — the algorithm in Miso.Diff compares old and new View trees and emits the minimal set of DOM mutations. Keyed children significantly speed up child-list reconciliation.

The TypeScript runtime

The DOM operations live in a small TypeScript runtime (ts/ in the repository, bundled into js/miso.js). It implements the drawing context interface that renderApp lets you swap — the native backend provides an alternative implementation on top of Lynx's element API. The runtime has a bun test suite with high coverage; npm test runs it.