A small, fast and scalable state management solution for React applications using simplified flux principles
Core functionality for creating and managing state stores in both React and vanilla JavaScript environments.
Creates a React-integrated store with hook-based API that automatically triggers re-renders when subscribed state changes.
/**
* Creates a React-integrated store with hooks API
* @param initializer - Function that creates the initial state and actions
* @returns UseBoundStore that can be called as a hook
*/
function create<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(
initializer: StateCreator<T, [], Mos>
): UseBoundStore<Mutate<StoreApi<T>, Mos>>;
function create<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(
initializer: StateCreator<T, [], Mos>
) => UseBoundStore<Mutate<StoreApi<T>, Mos>>;Usage Examples:
import { create } from "zustand";
// Simple counter store
interface CounterState {
count: number;
increment: () => void;
decrement: () => void;
reset: () => void;
}
const useCounterStore = create<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// Using in React component
function Counter() {
const { count, increment, decrement, reset } = useCounterStore();
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<button onClick={reset}>Reset</button>
</div>
);
}
// Async actions
interface UserState {
users: User[];
loading: boolean;
fetchUsers: () => Promise<void>;
}
const useUserStore = create<UserState>((set, get) => ({
users: [],
loading: false,
fetchUsers: async () => {
set({ loading: true });
try {
const response = await fetch('/api/users');
const users = await response.json();
set({ users, loading: false });
} catch (error) {
set({ loading: false });
}
},
}));Creates a vanilla store that works without React, providing imperative access to state management.
/**
* Creates a vanilla store without React integration
* @param initializer - Function that creates the initial state and actions
* @returns StoreApi with imperative methods
*/
function createStore<T, Mos extends [StoreMutatorIdentifier, unknown][] = []>(
initializer: StateCreator<T, [], Mos>
): Mutate<StoreApi<T>, Mos>;
function createStore<T>(): <Mos extends [StoreMutatorIdentifier, unknown][] = []>(
initializer: StateCreator<T, [], Mos>
) => Mutate<StoreApi<T>, Mos>;Usage Examples:
import { createStore } from "zustand/vanilla";
// Vanilla store creation
const store = createStore<CounterState>((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
reset: () => set({ count: 0 }),
}));
// Imperative usage
console.log(store.getState().count); // 0
store.getState().increment();
console.log(store.getState().count); // 1
// Subscribe to changes
const unsubscribe = store.subscribe((state, prevState) => {
console.log('Count changed from', prevState.count, 'to', state.count);
});
// Later: unsubscribe()The StateCreator type defines the function signature for initializing store state and actions.
/**
* Function type for creating store state and actions
* @param setState - Function to update store state
* @param getState - Function to read current store state
* @param store - Full store API for advanced usage
* @returns Initial state object with actions
*/
type StateCreator<
T,
Mis extends [StoreMutatorIdentifier, unknown][] = [],
Mos extends [StoreMutatorIdentifier, unknown][] = [],
U = T
> = ((
setState: Get<Mutate<StoreApi<T>, Mis>, 'setState', never>,
getState: Get<Mutate<StoreApi<T>, Mis>, 'getState', never>,
store: Mutate<StoreApi<T>, Mis>
) => U) & { $$storeMutators?: Mos };setState Usage:
// Partial updates (recommended)
set((state) => ({ count: state.count + 1 }));
// Object merge updates
set({ loading: false });
// Complete replacement (use carefully)
set(newState, true);getState Usage:
const useStore = create((set, get) => ({
count: 0,
doubleCount: () => {
const currentCount = get().count;
set({ count: currentCount * 2 });
},
getCountPlusOne: () => get().count + 1,
}));Core interface provided by all Zustand stores, available in both React and vanilla environments.
/**
* Core store interface with state management methods
*/
interface StoreApi<T> {
/** Update store state with partial or complete replacement */
setState: SetStateInternal<T>;
/** Get current store state */
getState: () => T;
/** Get initial store state */
getInitialState: () => T;
/** Subscribe to state changes */
subscribe: (listener: (state: T, prevState: T) => void) => () => void;
}
type SetStateInternal<T> = {
_(
partial: T | Partial<T> | { _(state: T): T | Partial<T> }['_'],
replace?: false
): void;
_(state: T | { _(state: T): T }['_'], replace: true): void;
}['_'];Helper types for extracting state and working with store APIs.
/**
* Extract state type from store API
*/
type ExtractState<S> = S extends { getState: () => infer T } ? T : never;
/**
* Utility type for middleware composition
*/
type Mutate<S, Ms> = number extends Ms['length' & keyof Ms]
? S
: Ms extends []
? S
: Ms extends [[infer Mi, infer Ma], ...infer Mrs]
? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs>
: never;
/**
* Base interface for store mutators (extended by middleware)
*/
interface StoreMutators<S, A> {}
type StoreMutatorIdentifier = keyof StoreMutators<unknown, unknown>;Install with Tessl CLI
npx tessl i tessl/npm-zustand