Stores

createOptimisticStore

The store equivalent of createOptimistic. Writes inside an action transition are tentative — they show up immediately but auto-revert (or reconcile to the action's resolved value) once the transition finishes.

Use this for optimistic UI on collection-shaped data. For single-value optimistic state, prefer createOptimistic.

  • Plain form: createOptimisticStore(initialValue).
  • Derived form: createOptimisticStore(fn, seed, options?) — a projection store whose authoritative value is recomputed by fn and whose optimistic overlay reverts after each transition.

options.key defaults to "id"; specify it only when your data uses a different identity field (e.g. { key: "uuid" } or { key: t => t.slug }). Restating the default just adds noise.


Import

import { createOptimisticStore } from "solid-js";

Type signature

function createOptimisticStore<T extends object = {}>(
store: NoFn<T> | Store<NoFn<T>>
): [get: Store<T>, set: StoreSetter<T>];
function createOptimisticStore<T extends object = {}>(
fn: (store: T) => void | T | Promise<void | T> | AsyncIterable<void | T>,
store: Partial<T> | Store<NoFn<T>>,
options?: ProjectionOptions
): [get: Refreshable<Store<T>>, set: StoreSetter<T>];

Return value

[store: Store<T>, setStore: StoreSetter<T>]


Examples

const [todos, setTodos] = createOptimisticStore<Todo[]>([]);
// Mutation: optimistic add, then in-place reconcile to the saved row.
const addTodo = action(function* (text: string) {
const tempId = crypto.randomUUID();
setTodos((t) => {
t.push({ id: tempId, text, pending: true });
});
const saved = yield api.createTodo(text);
setTodos((t) => {
const i = t.findIndex((x) => x.id === tempId);
if (i >= 0) t[i] = saved;
});
});
// Return form: filter is the natural shape for removal.
const removeTodo = action(function* (id: string) {
setTodos((t) => t.filter((x) => x.id !== id));
yield api.removeTodo(id);
});

Refreshable

Brand applied to values that participate in the refresh() re-run protocol. Accessors receive this handle internally; projected stores expose it through their public return type so user-defined hooks that wrap createOptimisticStore / createProjection / projection-form createStore can have their return types inferred without leaking the internal $REFRESH symbol into public type signatures (TS4058).

type Refreshable<T> = T & { readonly [$REFRESH]: any };
Last updated: 7/4/26, 6:21 PMEdit this pageReport an issue with this page