What is Reactive Values?
A lightweight and extensible JavaScript & TypeScript library for managing reactive values and computed dependencies. Designed for projects that need reactivity without relying on heavy frameworks.
The count
signal value is
The doubleCount
computed value is
const count = signalValue(0);
const doubleCount = computedValue(() => count() * 2, [count]);
count.effect((val) => {
const htmlElement = document.querySelector('#reactiveCounter')!;
htmlElement.innerHTML = `${val}`;
});
doubleCount.effect((val) => {
const htmlElement = document.querySelector('#computedCounter')!;
htmlElement.innerHTML = `${val}`;
});
A lightweight and extensible JavaScript & TypeScript library for managing reactive values and computed dependencies. Designed for projects that need reactivity without relying on heavy frameworks.
npm install reactive-values
Module | Description |
---|---|
Listener<T> |
A function that reacts to value changes |
SignalValue<T> |
Interface for signal values with set , and effect methods
|
ComputedValue<T> |
Interface for computed values with effect method |
signalValue(initialValue, options?) |
Creates a reactive value with deep equality, batching, and listener support |
computedValue(compute, deps, options?) |
Creates a derived value that updates automatically when dependencies change |
deepEqual(a, b) |
Performs deep equality checks between complex values |
type Listener<T> = (value: T) => void;
A function that runs whenever the reactive value changes. Useful for syncing UI, triggering side effects, or propagating state.
interface SignalValue<T> {
() => T;
set: (value: T) => void;
effect: (listener: (value: T) => void) => (() => boolean);
}
()
: Returns the current value..set(value)
: Updates the value and notifies listeners if it changed..effect(listener)
: Registers a listener and immediately invokes it. Returns a function to remove
the listener.
signalValue(initialValue, { asyncEffect: true });
signalValue(initialValue, { asyncUpdates: true });
signalValue(initialValue, { asyncEffect: true, asyncUpdates: true });
interface ComputedValue<T> {
() => T;
effect: (listener: (value: T) => void) => (() => boolean);
}
()
: Returns the current value..effect(listener)
: Registers a listener and immediately invokes it. Returns a function to remove
the listener.
computedValue(initialValue, { asyncEffect: true });
computedValue(initialValue, { asyncUpdates: true });
computedValue(initialValue, { asyncEffect: true, asyncUpdates: true });
import { signalValue } from 'reactive-values';
const count = signalValue(0, { asyncEffect: false, asyncUpdates: true });
count.effect(val => console.log('Count:', val));
count.set(1);
count();
import { signalValue, computedValue } from 'reactive-values';
const firstName = signalValue('Jhon');
const lastName = signalValue('Doe');
const fullName = computedValue(
() => `${firstName.get()} ${lastName.get()}`,
[firstName, lastName],
{ asyncEffect: false, asyncUpdates: true }
);
fullName.effect((name) => console.log('Full name:', name));
fullName(); // Show the value
import { deepEqual } from 'reactive-values';
const isEqual = deepEqual({ a: 1 }, { a: 1 }); // true
import { signalValue, computedValue } from 'reactive-values';
const price = signalValue(100);
const quantity = signalValue(2);
const total = computedValue(() => price.get() * quantity.get(), [price, quantity], {
asyncEffect: false,
asyncUpdates: true
});
total.effect(val => console.log('Updated total:', val));
price.set(120); // "Updated total: 240" (batched async)
quantity.set(3); // "Updated total: 360" (batched async)
Reactive Values provides a clean foundation for building reactive systems in TypeScript. It emphasizes simplicity, modularity, and flexibility—perfect for custom UI logic, state management, or animation triggers.