# @wrnexus/reactive > Tiny, type-safe reactive primitives (signals) with zero dependencies. Part of the **WrNexus** framework — an SSR-first, Bun-native full-stack web framework. ## Overview `@wrnexus/reactive` is the seed of WrNexus's reactivity layer: a minimal `signal` primitive that holds a value, notifies subscribers when it changes, and hands back an unsubscribe function. It is deliberately small and framework-agnostic — it powers nothing on its own, but is shaped so client islands (and later the `.wrn` compiler's `state` blocks) can build reactive bindings on top of it. Reach for it when you need observable state without pulling in a full reactivity library. ## Installation ```bash bun add @wrnexus/reactive ``` > Private package — the machine must be authenticated to the `wrnexus` npm org > (a read token in `~/.npmrc`). Requires **Bun** (Node is not supported). ## API The package has a single entry point (`.`) exporting one function and three types. ### `signal(initial: T): Signal` Creates a reactive signal seeded with `initial`. Returns a `Signal`: | Member | Signature | Description | | ----------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------- | | `get` | `(): T` | Read the current value. | | `set` | `(next: T): void` | Write a new value. Subscribers run **only when the value actually changes** (compared with `Object.is`). | | `update` | `(fn: (current: T) => T): void` | Apply a function to the current value; equivalent to `set(fn(get()))`. | | `subscribe` | `(fn: Subscriber): Unsubscribe` | Register a subscriber; returns a function that removes it. | ### Types ```ts type Subscriber = (value: T) => void; type Unsubscribe = () => void; interface Signal { get(): T; set(next: T): void; update(fn: (current: T) => T): void; subscribe(fn: Subscriber): Unsubscribe; } ``` Notes on semantics: - **No-op updates are skipped.** `set` compares the incoming value to the current one with `Object.is`; identical values do not notify subscribers. - **Safe unsubscribe during notification.** Subscribers are iterated over a copy of the subscriber set, so a subscriber may call its own (or another's) unsubscribe while a notification is in flight. ## Usage ```ts import { signal } from "@wrnexus/reactive"; const count = signal(0); count.get(); // 0 // Subscribe; the returned function unsubscribes. const off = count.subscribe((value) => { console.log("count is now", value); }); count.set(1); // logs: count is now 1 count.set(1); // no-op — value unchanged, no notification count.update((n) => n + 1); // logs: count is now 2 off(); // stop listening count.set(3); // nothing logged ``` Typed signals infer `T` from the initial value, or can be annotated explicitly: ```ts import { signal, type Signal } from "@wrnexus/reactive"; const user: Signal<{ name: string } | null> = signal(null); user.set({ name: "Ada" }); ``` ## Requirements / Notes - **Bun-only.** Distributed as TypeScript source (`main`/`exports` point at `src/index.ts`); consume it under Bun, which runs `.ts` directly. - **Zero dependencies.** The only runtime API used is the standard `Object.is`. - Foundational primitive for WrNexus client islands and the forthcoming `.wrn` compiler `state` blocks.