Store utilities

createStore

Edit this page

Stores were intentionally designed to manage data structures like objects and arrays but are capable of handling other data types, such as strings and numbers.


Types Signature

import { createStore } from "solid-js/store"
import type { StoreNode, Store, SetStoreFunction } from "solid-js/store"
// Object initializer form
function createStore<T extends StoreNode>(
state: T | Store<T>
): [get: Store<T>, set: SetStoreFunction<T>];
// Derived store form (function initializer) — returns read-only store, no setter
function createStore<T extends StoreNode>(
fn: () => T,
initialValue?: T
): Store<T>;
type Store<T> = T; // conceptually readonly, but not typed as such

Usage

import { createStore } from "solid-js/store";
// Initialize store
const [store, setStore] = createStore({
userCount: 3,
users: [
{
id: 0,
username: "felix909",
location: "England",
loggedIn: false,
},
{
id: 1,
username: "tracy634",
location: "Canada",
loggedIn: true,
},
{
id: 2,
username: "johny123",
location: "India",
loggedIn: true,
},
],
});

Getter

Store objects support the use of getters to store derived values.

const [state, setState] = createStore({
user: {
firstName: "John",
lastName: "Smith",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
},
});

Setter (Draft-First)

In Solid 2.0, the setter callback receives a mutable draft of the store. You can directly mutate the draft -- this is the default behavior, replacing the need to wrap updates in produce.

const [state, setState] = createStore({
firstName: "John",
lastName: "Miller",
list: ["book", "pen"],
});
// Mutate the draft directly (produce-style, now the default)
setState((draft) => {
draft.firstName = "Johnny";
draft.lastName = "Milner";
draft.list.push("pencil");
});

Shallow Replacement via Return Value

If the setter callback returns a value, that value is used as a shallow replacement (diffed against the current store state), rather than applying draft mutations.

const [state, setState] = createStore({
firstName: "John",
lastName: "Miller",
});
// Returning an object performs a shallow merge/diff
setState((state) => ({ firstName: "Johnny", middleName: "Lee" }));
// Result: { firstName: 'Johnny', middleName: 'Lee', lastName: 'Miller' }

Direct Object Setter

You can also pass an object directly for a shallow merge:

setState({ firstName: "Johnny", middleName: "Lee" });
// ({ firstName: 'Johnny', middleName: 'Lee', lastName: 'Miller' })

Derived Store (Function Form)

In Solid 2.0, passing a function to createStore creates a derived store. The function is re-evaluated reactively, and the store updates automatically when its dependencies change.

import { createStore } from "solid-js/store";
import { createSignal } from "solid-js";
const [multiplier, setMultiplier] = createSignal(2);
const [base] = createStore({
items: [1, 2, 3],
});
// Derived store: automatically updates when `base` or `multiplier` change
const derived = createStore(() => ({
doubled: base.items.map((n) => n * multiplier()),
}));

storePath() Compat Helper

If you are migrating from Solid 1.x and relied on path-based setters, the storePath() helper provides backward compatibility:

import { createStore, storePath } from "solid-js/store";
const [state, setState] = createStore({
users: [
{ id: 0, username: "felix909", loggedIn: false },
{ id: 1, username: "tracy634", loggedIn: true },
],
});
// 1.x-style path setter via storePath()
setState(storePath("users", 0, "loggedIn", true));
// Equivalent draft-first setter (preferred in 2.0)
setState((draft) => {
draft.users[0].loggedIn = true;
});

To learn more about using stores check the Stores Guide, and the Store utilities section for more advanced APIs.

Report an issue with this page