Home Docs Download About Contact
Download

Signals

Fine-grained reactive state, from UI bindings to data flow.

Language Updated 2026-08-01 Edit this page

Signals are Prism’s reactive primitive. A signal is declared once, fired with emit, and handled with on — exactly the handlers registered for that signal run, nothing else. No diffing, no virtual DOM, no full re-render.

The basics

signal CountChanged(value: int);

on CountChanged(value) {
    println(value);
}

fn main() {
    emit CountChanged(0);
    emit CountChanged(1);
}

Declare a signal once, subscribe with on, and fire it with emit. That is the entire reactive surface in v0.1.0.

Carrying data

A signal can carry several values at once. Handlers receive them in order:

signal NameChanged(first: str, last: str);

on NameChanged(first, last) {
    println(first + " " + last);
}

fn main() {
    emit NameChanged("Ada", "Lovelace");
}

Computed/derived signals are not in v0.1.0 — recompute in the handler instead.

Effects

An on handler is the effect mechanism — it runs every time the signal fires:

signal FullChanged(value: str);

on FullChanged(value) {
    println(value);
}

There is no watch in v0.1.0. Handlers are the subscription: this is what makes Prism UI updates cheap — an update is an emit, and only the handlers registered for that signal run.

Signals in UI

PrismX widgets declare signals that the app loop reacts to:

class Counter {
    Label countLbl = {
        text = "Clicked 0 times"
    }
    Button incBtn = {
        text = "Increment"
        onPress: {
            Signal onIncrement()
        }
    }
}

When the button is pressed it emits onIncrement; a handler updates the label with setText(id, …). Widget text is a property, updated from the signal handler.

Note: signals are not threads — but they are thread-safe to use. emit from any thread schedules the dependent handlers on the thread that owns the UI.

Batch updates

A batch is just emitting both signals in sequence — there is no batch keyword in v0.1.0:

signal ThemeChanged(value: str);
signal AccentChanged(value: str);

on ThemeChanged(value) { println(value); }
on AccentChanged(value) { println(value); }

fn main() {
    emit ThemeChanged("dark");
    emit AccentChanged("violet");
}

Next: Memory safety.