Skip to main content

Introduction

A Signal is a wrapper around a value that can notify interested consumers when that value changes. Signals can contain any value, from simple primitives to complex data structures.

A Signal's value is always read through a getter function, which allows the framework to track where the signal is used, and observe its changes.

Adopting Signals, will usually greatly simplify the design of your applications: if you have variables depending on other variables (called computed variables), variables that mutates other time (called dynamic variables, ex: front-end framework updating the DOM), or state management (ak: store).

In addition, using Signals to hold dynamic values is easier that managing them yourself: updating manually your computed variables requires more code and quickly becomes error-prone, where Signals handle it automatically.

Finally, they perfectly bridge the gap between imperative and reactive programming, providing a smooth transition between two paradigms: you get the best of both worlds, with a simplified syntax, consistent application, and all of it without sacrificing on performances.

Example

// create a writable signal
const counter = signal(0);

// create a computed signal
const isEven = computed(() => counter() % 2 === 0);

// computed properties are signals themselves
const color = computed(() => (isEven() ? 'red' : 'blue'));

// log the values of our signals, and log them again when either (or all) changes.
effect(() => {
console.log('counter', counter(), 'isEven', isEven(), 'color', color());
});

// create an observable triggered on a click on the window
fromEventTarget(window, 'click')(() => {
// update signal's value based on the current one
counter.update((currentValue) => currentValue + 1);
});

Click here to see the live demo