Tutorial

Tutorial

Learn the library step by step.

1. Import

import { signal, derive, effect } from "@cyftec/signal";

Expected result:

  • the library imports cleanly
  • the three primitives are available immediately

2. Create State

const count = signal(0);
console.log(count.value); // 0
count.value = 1;
console.log(count.value); // 1

What changed:

  • `signal()` stores mutable state
  • `.value` reads and writes the current value

3. Read From State

const name = signal("Ada");
console.log(`Hello, ${name.value}`); // Hello, Ada

Expected result:

  • output reads the current signal value directly

4. Derive State

const count = signal(2);
const doubled = derive(() => count.value * 2);
console.log(doubled.value); // 4

What changed:

  • `derive()` computes new state from existing state
  • the result stays in sync automatically

5. React To Changes

const count = signal(0);

effect(() => {
  console.log(count.value); // 0
});

count.value = 1; // 1

Expected result:

  • the effect runs once immediately
  • it runs again after the update

6. Combine Signals

const first = signal("Ada");
const last = signal("Lovelace");
const fullName = derive(() => `${first.value} ${last.value}`);

effect(() => {
  console.log(fullName.value); // Ada Lovelace
});

7. Pattern to Prefer

  • Use `signal()` for mutable source data
  • Use `derive()` for computed values
  • Use `effect()` for logging, DOM updates, and integration points

8. Mental Model

source signal
derive()
effect()

Use this when you want the shortest path from state to UI.

9. Equality Short-Circuit

const count = signal(1);

effect(() => {
  console.log(count.value); // 1
});

count.value = 1; // no log

Expected result:

  • the effect does not re-run for the same value

10. Dispose When Done

const count = signal(0);
const logger = effect(() => {
  console.log(count.value); // 0
});

logger.dispose();
count.value = 1; // no log

Expected result:

  • the disposed effect does not run again after the next update cycle

11. Arrays And Objects

const items = signal([1, 2, 3]);
items.push(4);

const user = signal({ name: "Ada", age: 36 });
user.set({ age: 37 });

Expected result:

  • array helpers update the array signal
  • object `set()` performs a shallow merge