Mini Jotai AtomsLoading saved progress…

Mini Jotai Atoms

An atom is the smallest unit of state: a token you create once and read or write through a store, while derived atoms compute their value from other atoms and stay in sync automatically. This is the model behind Jotai — atoms are stateless tokens, and a store holds every atom's actual value so the same atom can be shared across independent stores. You build a tiny version of it: atom to declare state, and createStore to read, write, and subscribe.

Signature

type Atom = object; // an opaque, stateless token — holds no value of its own

const miniJotaiAtoms: {
  // atom(initialValue)  → primitive atom
  // atom(read)          → derived atom, read = (get) => computedValue
  // atom(read, write)   → writable derived atom (optional)
  atom(readOrInitial: unknown, write?: Function): Atom;

  createStore(): {
    get(atom: Atom): unknown;                 // current value (init on first read)
    set(atom: Atom, value: unknown): void;    // update a primitive / run a write fn
    sub(atom: Atom, cb: () => void): () => void; // subscribe; returns unsubscribe
  };
};

Examples

const { atom, createStore } = miniJotaiAtoms;

const count = atom(0); // primitive atom
const doubled = atom((get) => get(count) * 2); // derived atom

const store = createStore();
store.get(count); // 0
store.get(doubled); // 0
store.set(count, 5);
store.get(doubled); // 10 — recomputed from count
const count = atom(0);
const store = createStore();

const unsub = store.sub(count, () => console.log('changed'));
store.set(count, 1); // logs "changed"
store.set(count, 1); // same value — logs nothing
unsub();
store.set(count, 2); // logs nothing — unsubscribed

Notes

  • Atoms are stateless tokensatom() returns an opaque token; every value lives in the store, so one atom used in two stores holds two independent values.
  • Derived atoms track dependencies — a derived atom's read function calls get(otherAtom); the store records those reads and recomputes only when one of them changes, returning a cached value otherwise.
  • set notifies dependents — setting a primitive notifies subscribers of that atom and of every derived atom whose value changed because of it.
  • No change means no notification — setting an atom to its current value, compared with Object.is, notifies nobody.
  • A shared node recomputes once — if two derived atoms read the same third atom, that third atom is computed once and cached, even in a diamond.
  • Out of scope — async atoms, batching several sets into one notify, cycles between atoms, and React bindings.

FAQ

How is a derived atom different from a primitive atom?
A primitive atom holds an initial value and is changed with set. A derived atom has no value of its own — it computes one from other atoms through its read function, and the store recomputes it only when a dependency it read has changed.
Why does state live in the store instead of on the atom?
Keeping atoms stateless lets the same atom be reused across independent stores without their values leaking into each other — for example one store per request on a server.
When does a subscriber get notified?
When you set an atom it depends on and the resulting value actually changes. Setting an atom to its current value, or changing an unrelated atom, notifies nobody.
Loading editor…