A super fast and powerful state management library for JavaScript and React applications with proxy-based observables and fine-grained reactivity
npx @tessl/cli install tessl/npm-legendapp--state@2.1.0Legend State is a super fast and powerful state management library for JavaScript and React applications that prioritizes ease of use, performance, and minimal boilerplate. It provides a proxy-based observable system with fine-grained reactivity that enables components to re-render only when specifically accessed state changes, resulting in exceptional performance benchmarks.
npm install @legendapp/stateimport { observable, computed, when } from "@legendapp/state";For React integration:
import { useObservable, Reactive } from "@legendapp/state/react";For persistence:
import { persistObservable } from "@legendapp/state/persist";CommonJS:
const { observable, computed, when } = require("@legendapp/state");import { observable, computed } from "@legendapp/state";
import { useObservable } from "@legendapp/state/react";
// Create observables
const user$ = observable({
name: "Alice",
age: 30,
settings: {
theme: "dark"
}
});
// Create computed values
const displayName$ = computed(() => `${user$.name.get()} (${user$.age.get()})`);
// Observe changes
user$.onChange(() => {
console.log("User changed:", user$.get());
});
// React component
function UserProfile() {
const localUser$ = useObservable({ name: "", email: "" });
return (
<Reactive.div>
<input
value={localUser$.name.get()}
onChange={e => localUser$.name.set(e.target.value)}
/>
<p>Name: {localUser$.name.get()}</p>
</Reactive.div>
);
}Legend State is built around several key components:
Core observable creation and manipulation functions for reactive state management.
function observable<T>(value?: T): Observable<T>;
function observablePrimitive<T>(value?: T): ObservablePrimitive<T>;
function computed<T>(compute: () => T): ObservableComputed<T>;
function event(): ObservableEvent;
function observe<T>(selector: Selector<T>, reaction?: (e: ObserveEvent<T>) => any): () => void;
function proxy<T>(target: T): T;
function trackSelector<T>(selector: Selector<T>): () => T;React hooks and components for building reactive user interfaces with Legend State.
function useObservable<T>(initialValue?: T | (() => T) | (() => Promise<T>)): Observable<T>;
function useObserveEffect<T>(selector: () => T, effect: (value: T) => void): void;
function Reactive<T extends keyof JSX.IntrinsicElements>(
props: ComponentProps<T>
): JSX.Element;Comprehensive persistence system for offline-first applications with local storage and remote sync capabilities.
function persistObservable<T>(
obs: Observable<T>,
config: ObservablePersistenceConfig<T>
): void;
function configureObservablePersistence(
config: ObservablePersistenceConfig
): void;Utility functions for working with observables, including type checking, object manipulation, and path operations.
function isObservable(value: any): boolean;
function when<T>(predicate: Selector<T>, effect?: (value: T) => any | (() => any)): Promise<T>;
function whenReady<T>(predicate: Selector<T>, effect?: (value: T) => any | (() => any)): Promise<T>;
function batch(fn: () => void): void;
function beginBatch(): void;
function endBatch(): void;
function computeSelector<T>(selector: Selector<T>): T;
function getObservableIndex(obs: Observable<any>): ObservableChild<number>;
function isObservableValueReady(value: any): boolean;
function lockObservable<T>(obs: Observable<T>, value: T): void;
function mergeIntoObservable<T>(target: Observable<T>, ...sources: T[]): void;
function opaqueObject<T>(value: T): T;
function setSilently<T>(obs: Observable<T>, value: T): void;
function hasOwnProperty(obj: any, key: string): boolean;
function isArray(value: any): boolean;
function isBoolean(value: any): boolean;
function isEmpty(value: any): boolean;
function isFunction(value: any): boolean;
function isObject(value: any): boolean;
function isPrimitive(value: any): boolean;
function isPromise(value: any): boolean;
function isString(value: any): boolean;
function isSymbol(value: any): boolean;Configuration modules for enabling various Legend State features and optimizations.
function configureLegendState(config: { observableFunctions?: ObservableFunctions }): void;Core type definitions used throughout the Legend State API.
type TrackingType = undefined | true | symbol;
interface GetOptions {
shallow: boolean;
}
type Selector<T> = () => T;
type ObservableListenerDispose = () => void;
interface Observable<T> {
get(options?: TrackingType | GetOptions): T;
set(value: T | ((prev: T) => T) | Promise<T>): void;
peek(): T;
onChange(
callback: ListenerFn<T>,
options?: {
trackingType?: TrackingType;
initial?: boolean;
immediate?: boolean;
noArgs?: boolean;
}
): ObservableListenerDispose;
assign(value: T | Partial<T>): void;
delete(): void;
}
type ObservablePrimitive<T> = [T] extends [boolean]
? ObservablePrimitiveBaseFns<T> & ObservablePrimitiveBooleanFns<T>
: ObservablePrimitiveBaseFns<T>;
interface ObservablePrimitiveBaseFns<T> {
get(options?: TrackingType | GetOptions): T;
set(value: T | ((prev: T) => T) | Promise<T>): void;
peek(): T;
onChange(
callback: ListenerFn<T>,
options?: {
trackingType?: TrackingType;
initial?: boolean;
immediate?: boolean;
noArgs?: boolean;
}
): ObservableListenerDispose;
delete(): void;
}
interface ObservablePrimitiveBooleanFns<T> {
toggle(): T;
}
interface ObservableComputed<T> extends Observable<T> {
// Computed observables are read-only
}
interface ObservableEvent {
fire(...args: any[]): void;
on(callback: (...args: any[]) => void): ObservableListenerDispose;
}
interface ObserveEvent<T> {
cancel?: boolean;
value?: T;
}
interface ListenerParams<T> {
value: T;
getPrevious: () => T;
changes: Change[];
}
type ListenerFn<T> = (params: ListenerParams<T>) => void;
interface Change {
path: string[];
pathTypes: TypeAtPath[];
valueAtPath: any;
prevAtPath: any;
}
type TypeAtPath = 'object' | 'array' | 'map' | 'set';
interface ObservableFunctions {
[key: string]: any;
}
interface WithState {
state?: ObservableState;
_state?: ObservableState;
}
interface ObservableState {
isLoaded: boolean;
error?: Error;
}
interface ObservableComputedTwoWay<T, T2 = T> extends Observable<T> {
set(value: T2): void;
}
interface NodeValue {
// Internal node representation
}
interface ObserveOptions {
fromComputed?: boolean;
immediate?: boolean;
}
type ObservableChild<T> = Observable<T>;