← All @molecule/* packages · App templates

@molecule/app-state-jotai

Provider bond · state · App (browser) · v1.0.1 · Apache-2.0

Jotai state provider for molecule.dev

npm install @molecule/app-state-jotai

npm · Source on GitHub · Implements @molecule/app-state

How it works

@molecule/app-state-jotai is a provider bond on the app (browser) side: it implements the state core interface (@molecule/app-state) with a concrete vendor or library behind it.

Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.

import { setProvider, createStore } from '@molecule/app-state'
import { provider } from '@molecule/app-state-jotai'

setProvider(provider)

const store = createStore({ initialState: { count: 0 } })
store.subscribe((state) => console.log(state.count))
store.setState((s) => ({ count: s.count + 1 })) // shallow-merged

Works with: @molecule/app-state

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Jotai state provider for molecule.dev.

Implements the StateProvider interface from @molecule/app-state on Jotai atoms, plus atom helpers (createAtom, createDerivedAtom, createWritableDerivedAtom) and a shared defaultStore for advanced use.

Quick Start

import { setProvider, createStore } from '@molecule/app-state'
import { provider } from '@molecule/app-state-jotai'

setProvider(provider)

const store = createStore({ initialState: { count: 0 } })
store.subscribe((state) => console.log(state.count))
store.setState((s) => ({ count: s.count + 1 })) // shallow-merged

Type

provider

Installation

npm install @molecule/app-state-jotai @molecule/app-state jotai

API

Interfaces

Atom

interface Atom<Value> {
  toString: () => string
  read: Read<Value>
  debugLabel?: string
  /**
   * To ONLY be used by Jotai libraries to mark atoms as private. Subject to change.
   * @private
   */
  debugPrivate?: boolean
  /**
   * Fires after atom is referenced by the store for the first time
   * This is an internal API and subject to change without notice.
   */
  INTERNAL_onInit?: (store: Store) => void
}

AtomWithAccessors

Atom with accessor functions.

interface AtomWithAccessors<T> {
  atom: PrimitiveAtom<T>
  get: (store: JotaiStore) => T
  set: (store: JotaiStore, value: T | ((prev: T) => T)) => void
}

JotaiStoreConfig

Extended store config for Jotai-specific options.

interface JotaiStoreConfig<T> extends StoreConfig<T> {
  /**
   * External Jotai store to use.
   */
  jotaiStore?: JotaiStore
}

StateProvider

State provider interface that all state management bond packages must implement. Provides the store creation factory.

interface StateProvider {
  /**
   * Creates a new store.
   */
  createStore<T>(config: StoreConfig<T>): Store<T>
}

Store

Reactive state container with getState, setState, subscribe, and destroy.

All state management providers must implement this interface.

interface Store<T> {
  /**
   * Gets the current state.
   */
  getState(): T
  /**
   * Sets the state (partial or via updater function).
   */
  setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
  /**
   * Subscribes to state changes.
   * Returns an unsubscribe function.
   */
  subscribe(listener: StateListener<T>): () => void
  /**
   * Destroys the store and cleans up subscriptions.
   */
  destroy(): void
}

StoreConfig

Configuration for creating a store (initial state, optional name, and middleware chain).

interface StoreConfig<T> {
  /**
   * Initial state value.
   */
  initialState: T
  /**
   * Optional name for debugging.
   */
  name?: string
  /**
   * Optional middleware functions.
   */
  middleware?: StoreMiddleware<T>[]
}

Types

GetState

Get state function type.

type GetState<T> = () => T

JotaiStore

Jotai store type.

type JotaiStore = ReturnType<typeof createJotaiStore>

PrimitiveAtom

type PrimitiveAtom<Value> = WritableAtom<Value, [SetStateAction<Value>], void>

SetState

Function to update store state with a partial object or updater function.

type SetState<T> = (partial: Partial<T> | ((state: T) => Partial<T>)) => void

StateListener

Callback invoked whenever store state changes.

type StateListener<T> = (state: T, prevState: T) => void

StoreMiddleware

Store middleware function. Wraps the set function to intercept state updates (e.g. for logging, persistence, or devtools).

type StoreMiddleware<T> = (set: SetState<T>, get: GetState<T>) => SetState<T>

Functions

atom(read, write)

function atom(
  read: Read<Value, SetAtom<Args, unknown>>,
  write: Write<Args, Result>,
): WritableAtom<Value, Args, Result>

combineAtoms(atoms)

Combine multiple atoms into a single derived atom whose value is an object with the resolved values of all input atoms.

function combineAtoms(atoms: T): Atom<{ [K in keyof T]: T[K] extends Atom<infer V> ? V : never }>
  • atoms — A record of named atoms to combine.

Returns: A derived atom whose value is an object with the resolved values of all input atoms.

createAsyncAtom(asyncFn)

Create an async atom whose value is fetched asynchronously.

function createAsyncAtom(asyncFn: () => Promise<T>): Atom<Promise<T>>
  • asyncFn — An async function that returns the atom's value.

Returns: A Jotai atom whose value is a Promise, resolved when accessed via useAtom or store.get.

createAtom(initialValue)

Creates a primitive atom with get/set functions.

function createAtom(initialValue: T): AtomWithAccessors<T>
  • initialValue — The starting value for the atom.

Returns: An AtomWithAccessors containing the raw Jotai atom plus get(store) and set(store, value) helpers.

createAtomFamily(createInitialValue)

Create an atom family — a factory function that returns cached atoms keyed by parameter. Each unique parameter value creates a new atom with its own state.

function createAtomFamily(createInitialValue: (param: P) => T): (param: P) => AtomWithAccessors<T>
  • createInitialValue — A factory function that creates the initial value for a given parameter.

Returns: A parameterized factory function that returns cached AtomWithAccessors instances keyed by parameter.

createDerivedAtom(read)

Create a read-only derived (computed) atom whose value is derived from other atoms.

function createDerivedAtom(read: (get: <V>(atom: Atom<V>) => V) => T): Atom<T>
  • read — A function that receives get and derives a value from other atoms.

Returns: A read-only Jotai Atom whose value is computed from the read function.

createJotaiStore()

function createJotaiStore(): INTERNAL_Store

createJotaiStoreInstance()

Creates a new Jotai store instance for atom state management.

function createJotaiStoreInstance(): INTERNAL_Store

Returns: A fresh Jotai store that can be used with store.get(), store.set(), and store.sub().

createPersistentAtom(key, initialValue, storage)

Creates an atom with localStorage persistence.

function createPersistentAtom(key: string, initialValue: T, storage?: Storage): AtomWithAccessors<T>
  • key — The localStorage key to persist under.
  • initialValue — The default value if nothing is stored.
  • storage — The Storage backend to use (defaults to localStorage).

Returns: An AtomWithAccessors that automatically persists to storage on set.

createProvider()

Creates a Jotai-based StateProvider for use with setProvider() from @molecule/app-state.

function createProvider(): StateProvider

Returns: A StateProvider that creates Jotai-backed stores.

createStore(config)

Creates a Jotai-backed Store implementing the molecule state interface. Wraps a Jotai atom with getState, setState (with partial merge), subscribe, and optional middleware.

function createStore(config: JotaiStoreConfig<T>): Store<T>
  • config — Store configuration with initial state, optional middleware, and optional Jotai store instance.

Returns: A Store with getState/setState/subscribe/destroy methods.

createWritableDerivedAtom(read, write)

Create a writable derived atom with both computed read and custom write logic.

function createWritableDerivedAtom(
  read: (get: <V>(atom: Atom<V>) => V) => T,
  write: (
    get: <V>(atom: Atom<V>) => V,
    set: <V>(atom: PrimitiveAtom<V>, value: V) => void,
    ...args: Args
  ) => void,
): Atom<T> & { write: typeof write }
  • read — A function that receives get and derives a value from other atoms.
  • write — A function that receives get, set, and args to update underlying atoms.

Returns: A writable derived Jotai atom with both read and write capabilities.

Constants

defaultStore

The default shared Jotai store instance used across the application.

const defaultStore: INTERNAL_Store

provider

Default Jotai state provider instance.

const provider: StateProvider

Core Interface

Implements @molecule/app-state interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/app-state'
import { provider } from '@molecule/app-state-jotai'

export function setupStateJotai(): void {
  setProvider(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-state ^1.0.1

Runtime Dependencies

  • @molecule/app-state

  • jotai

  • subscribe listeners receive the SAME object for state and prevState (Jotai does not track previous values) — do not diff state against prevState with this bond; if change-detection by comparison matters, keep your own snapshot or use the zustand/redux bonds, which deliver a real previous state.

  • setState shallow-merges partial objects (or updater results) into the current state — molecule Store semantics, not a replace.

  • Each createStore() gets its own private Jotai store unless you pass jotaiStore in the config; use the exported defaultStore (or createJotaiStore()) to share one store with app-level atoms/useAtom.