Skip to main content

Crate leptos_store

Crate leptos_store 

Source
Expand description

§leptos-store

Enterprise-grade, type-enforced state management for Leptos.

This crate provides a structured, SSR-safe state management architecture inspired by Vuex and Pinia, translated into idiomatic Rust for Leptos.

§Core Concepts

Each store is a domain module composed of:

  1. State - Read-only externally, reactive data container
  2. Getters - Derived, read-only computed values
  3. Mutators - Pure, synchronous state mutations
  4. Actions - Synchronous orchestration with side effects
  5. Async Actions - Asynchronous orchestration

§Mutation Rules

LayerCan Write StateAsyncSide Effects
Components
Getters
Mutators
Actions
Async Actions

Only mutators may write state.

§Feature Flags

FeatureDefaultDescription
ssr✅ YesServer-side rendering support
hydrate❌ NoSSR hydration with automatic state serialization
csr❌ NoClient-side rendering only
middleware❌ NoMiddleware system, audit trail, store coordination
devtools❌ NoDevTools integration with time-travel debugging
persist-web❌ NoBrowser-based state persistence

§Choosing Features

  • CSR only (SPA): Use features = ["csr"]
  • SSR without hydration: Use default features (ssr)
  • Full SSR with hydration: Use ssr on server, hydrate on client

§Why is hydrate opt-in?

The hydrate feature adds:

  • serde and serde_json for state serialization
  • web-sys and wasm-bindgen for DOM access
  • Approximately 50KB to your WASM bundle

If you don’t need state transfer from server to client, you can skip this overhead.

§Selectors — Fine-Grained Reactivity

Selectors create memoized views into specific slices of store state. Only re-compute when their particular slice changes, preventing unnecessary re-renders.

let user_name = create_selector(&store, |s| s.user.name.clone());
let total = combine_selectors(count, discount, |c, d| c * d);
let badge = map_selector(count, |n| format!("{n} items"));
let active = filter_selector(count, |n| *n > 0);

See the selectors module for full documentation.

§Deployment Models

ModelFeatureDescription
SSRssr (default)Store created per-request on server
HydratehydrateServer renders + serializes; client picks up
CSRcsrBrowser-only, no server involvement

§Available Macros

MacroPurposeFeature
define_state!Define state structs with default values-
define_hydratable_state!Define state with serde deriveshydrate
define_action!Define synchronous action structs-
define_async_action!Define async action structs with error types-
impl_store!Implement Store trait for an existing type-
impl_hydratable_store!Implement HydratableStore traithydrate
store!Complete store definition in one macro-
selector!Batch-create multiple selectors from a store-
namespace!Define typed namespace combining multiple stores-
derive_state_diff!Generate StateDiff impl for field-level diffingmiddleware

See the macros module for detailed documentation and examples.

§Hydration Support

When building full SSR applications where state needs to transfer from server to client, enable the hydrate feature:

[dependencies]
leptos-store = { version = "0.7", default-features = false }

[features]
ssr = ["leptos-store/ssr"]
hydrate = ["leptos-store/hydrate"]

This enables:

  • HydratableStore trait for state serialization
  • provide_hydrated_store() for server-side state embedding
  • use_hydrated_store() for client-side state recovery

See the hydration module (requires hydrate feature) for implementation details.

§Example

use leptos::prelude::*;
use leptos_store::prelude::*;

// Define your state
#[derive(Clone, Debug, Default)]
pub struct CounterState {
    pub count: i32,
}

// Define your store
#[derive(Clone)]
pub struct CounterStore {
    state: RwSignal<CounterState>,
}

impl Store for CounterStore {
    type State = CounterState;

    fn state(&self) -> ReadSignal<Self::State> {
        self.state.read_only()
    }
}

// Define mutators
impl CounterStore {
    pub fn increment(&self) {
        self.state.update(|s| s.count += 1);
    }

    pub fn decrement(&self) {
        self.state.update(|s| s.count -= 1);
    }
}

Re-exports§

pub use prelude::*;

Modules§

async
Async actions support for stores.
auditmiddleware
Audit trail system for tracking state mutation history.
composition
Store composition patterns.
context
Context management for stores.
coordinationmiddleware
Cross-store reactive coordination via the middleware EventBus.
devtoolsdevtools
Devtools integration for leptos-store.
hydrationhydrate
Hydration support for SSR stores.
macros
Macros for store definition.
middlewaremiddleware
Middleware system for store actions and mutations.
persistencepersist-web or persist-idb or persist-server
Persistence adapters for store state.
prelude
Prelude module - re-exports all commonly used types and traits.
selectors
Fine-grained selector system for reactive state slices.
serverserver-actions
Server action helpers for Leptos server functions.
store
Core store traits and types.
templatestemplates
Store templates for common patterns.

Macros§

define_action
Define a synchronous action struct.
define_async_action
Define an async action struct with associated result types.
define_getter
Macro to define a getter function inside an impl block.
define_hydratable_statehydrate
Define a hydratable state struct with serde derives.
define_mutator
Macro to define a private mutator function inside an impl block.
define_state
Define a state struct with optional default values.
derive_state_diffmiddleware
Derive the StateDiff trait for a struct, enabling field-level change tracking in the audit trail system.
impl_hydratable_storehydrate
Implement the HydratableStore trait for a store type.
impl_store
Implement the Store trait for an existing type.
namespace
Define a typed namespace that aggregates multiple domain stores.
selector
Create multiple memoized selectors from a store in one declaration.
store
Define a complete store with state, getters, mutators, and actions.