n nisli
GitHub

Signals

Signals are nisli’s reactive primitive. A signal holds a value; anything that reads it re-runs when it changes — and nothing else does.

signal

Create state with signal(initial). Read and write through .value.

import { signal } from '@nisli/core';

const count = signal(0);
count.value;        // 0
count.value = 5;    // notifies readers

computed

computed() derives a read-only signal. It is lazy and cached — it recomputes only when a dependency changes.

import { signal, computed } from '@nisli/core';

const count = signal(2);
const doubled = computed(() => count.value * 2);
doubled.value;      // 4

effect

effect() runs a side effect and re-runs when any signal it read changes. Dependencies are tracked automatically — no dependency arrays.

import { signal, effect } from '@nisli/core';

const count = signal(0);
effect(() => console.log('count is', count.value));
// logs "count is 0" now, and again on every change

Inside html`` templates you read signals implicitly — ${count}, no .value needed. The template subscribes and updates exactly the binding that changed.