Getting Started
StateLoom is a universal state management SDK for JavaScript and TypeScript. It provides a signal-based reactive core with three paradigm adapters -- Store, Atom, and Proxy -- and framework adapters for React, Vue, Solid, Svelte, and Angular.
Why StateLoom?
- One core, any paradigm: Choose the mental model that fits your team -- Zustand-like stores, Jotai-like atoms, or Valtio-like proxies. Switch or mix without rewriting your app.
- Framework-agnostic: The reactive core runs anywhere JavaScript runs. Framework adapters are thin bridges, not heavy abstractions.
- Composable middleware: Add persistence, devtools, tab sync, and undo/redo via a standard middleware interface.
- Tiny core:
@stateloom/coretargets ~1.5 KB gzipped with zero platform dependencies.
Architecture at a Glance
Choose Your Paradigm
StateLoom offers three paradigm adapters. Each wraps the same signal-based core but provides a different API style:
| Store | Atom | Proxy | |
|---|---|---|---|
| Package | @stateloom/store | @stateloom/atom | @stateloom/proxy |
| Mental model | Single object with actions | Composable bottom-up atoms | Direct mutation |
| Inspired by | Zustand | Jotai | Valtio |
| Best for | Feature-scoped state with actions | Fine-grained, composable state | Rapid prototyping, mutable-style |
| Middleware | Yes | No | No |
| TypeScript | Inferred from initializer | Inferred from atom type | Inferred from object shape |
Not sure which to choose?
Start with Store. It covers most use cases, supports middleware (persistence, devtools, tab sync), and is the most familiar pattern for developers coming from Zustand or Redux. You can always add atoms or proxies alongside it later.
Installation
Install the core package plus your chosen paradigm and framework adapter:
# Core + Store + React
pnpm add @stateloom/core @stateloom/store @stateloom/react# Core + Store + React
npm install @stateloom/core @stateloom/store @stateloom/react# Core + Store + React
yarn add @stateloom/core @stateloom/store @stateloom/reactReplace @stateloom/react with your framework adapter (@stateloom/vue, @stateloom/solid, @stateloom/svelte, or @stateloom/angular). You can also use the core directly without any framework adapter -- see Vanilla JS.
Quick Start: Signals (Core)
Signals are the fundamental reactive primitive. No paradigm adapter needed:
import { signal, computed, effect } from '@stateloom/core';
const count = signal(0);
const doubled = computed(() => count.get() * 2);
effect(() => {
console.log(`Count: ${count.get()}, Doubled: ${doubled.get()}`);
return undefined;
});
count.set(1); // logs: Count: 1, Doubled: 2
count.set(5); // logs: Count: 5, Doubled: 10Quick Start: Store
Stores combine state and actions in a single object:
import { createStore } from '@stateloom/store';
const counterStore = createStore((set) => ({
count: 0,
increment: () => set((s) => ({ count: s.count + 1 })),
decrement: () => set((s) => ({ count: s.count - 1 })),
reset: () => set({ count: 0 }),
}));
counterStore.getState().increment();
console.log(counterStore.getState().count); // 1Quick Start: Atom
Atoms are small, composable pieces of state:
import { atom, derived } from '@stateloom/atom';
const countAtom = atom(0);
const doubledAtom = derived((get) => get(countAtom) * 2);Quick Start: Proxy
Proxies let you write state with regular mutations:
import { observable, observe } from '@stateloom/proxy';
const state = observable({ count: 0, name: 'Alice' });
observe(() => {
console.log(`${state.name}: ${state.count}`);
});
state.count++; // logs: Alice: 1Framework Guides
Choose your framework to see a complete integration guide:
| Framework | Guide | Example App |
|---|---|---|
| Vanilla JS/TS | Vanilla JS | examples/vanilla-js/ |
| React + Vite | React + Vite | examples/react-vite/ |
| Next.js (SSR) | Next.js | examples/nextjs-ssr/ |
| Vue 3 | Vue | examples/vue-vite/ |
| SolidJS | SolidJS | examples/solid-vite/ |
| Svelte | Svelte | examples/svelte-vite/ |
| Angular | Angular | examples/angular/ |
| Astro | Astro | Coming soon |
Migrating from Other Libraries
StateLoom's paradigm adapters are designed to be familiar:
| Coming from | Use | Key differences |
|---|---|---|
| Zustand | @stateloom/store | Same createStore(set => ...) API. Middleware uses an array instead of function wrapping. |
| Jotai | @stateloom/atom | Same atom() / derived() pattern. derived replaces Jotai's atom with a read function. |
| Valtio | @stateloom/proxy | Same observable() / snapshot() API. observe() replaces subscribe(). |
| Redux/RTK | @stateloom/store | Replace slices with stores. No reducers needed -- use set() directly. |
| Pinia | @stateloom/store | Replace defineStore with createStore. Actions are in the same object. |
Next Steps
- Core API Reference --
signal(),computed(),effect(),batch(),scope() - Store API Reference --
createStore(), middleware, selectors - Atom API Reference --
atom(),derived(), atom families - Proxy API Reference --
observable(),snapshot(),observe() - Architecture Overview -- Full dependency graph and layer design