Skip to content
Agents tracked: 440 Downloads (7d): 202M down 19.5% GitHub stars: 10.4M Releases (7d): 607 Agent status: 3 with issuesSince last limit reset: Claude 28d · Codex 0d Updated Oct 21, 2026

Async actions in Zustand

Zustand actions can be async functions. They call set when they are ready, and can read the current state with get.

All Zustand examples Zustand: usage and stats

Async actions in Zustand: screenshot of the example below running
The code below, running in Chromium on our server (Oct 12, 2026). Press Run to see it live and change it.

How it works

  1. Write an async action. loadFishies is an async function. It sets status to "loading", waits 1.2 seconds as a stand-in for a request, then calls set again with the list. [1]
  2. Read state inside the action. The store creator receives get as a second argument. get().loads reads the current counter so each load is numbered. [1]
  3. Show the status in React. The component selects status and fishies, starts a load in useEffect, and disables the button while loading. [1]

Run and edit it

It runs in your browser, in a sandboxed frame that cannot see this site; the packages load from esm.sh only after you press Run.

import { useEffect } from 'react'
import { create } from 'zustand'

const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

const useFishStore = create((set, get) => ({
  fishies: [],
  status: 'idle',
  loads: 0,
  // An async action: call set whenever the data is ready
  loadFishies: async () => {
    set({ status: 'loading' })
    await wait(1200) // stand-in for a slow request
    const loads = get().loads + 1 // read current state with get()
    set({ fishies: ['salmon', 'tuna', 'trout'].map((f) => `${f} (load ${loads})`), status: 'done', loads })
  },
}))

const colors = { idle: '#9aa0ad', loading: '#f5b84a', done: '#5fd38d' }

export default function App() {
  const fishies = useFishStore((state) => state.fishies)
  const status = useFishStore((state) => state.status)
  const loadFishies = useFishStore((state) => state.loadFishies)

  useEffect(() => { loadFishies() }, [loadFishies])

  return (
    <div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#111', fontFamily: 'system-ui, sans-serif' }}>
      <div style={{ background: '#1c1f26', color: '#e8eaf0', padding: 26, borderRadius: 14, width: 400, boxSizing: 'border-box' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <h2 style={{ margin: 0, fontSize: 20 }}>Fish market</h2>
          <span style={{ color: colors[status], fontWeight: 700, fontSize: 13 }}>{status}</span>
        </div>
        <ul style={{ minHeight: 90, paddingLeft: 20, lineHeight: 1.7 }}>
          {status === 'loading' ? <li style={{ color: '#9aa0ad' }}>loading...</li> : fishies.map((f) => <li key={f}>{f}</li>)}
        </ul>
        <button
          onClick={loadFishies}
          disabled={status === 'loading'}
          style={{ padding: '9px 16px', border: 0, borderRadius: 8, background: '#f5b84a', color: '#1a1a1a', fontWeight: 600, cursor: 'pointer', opacity: status === 'loading' ? 0.5 : 1 }}
        >
          Reload
        </button>
      </div>
    </div>
  )
}
Ctrl/⌘ + Enter runs

Free for signed-in members, with a daily limit. Describe the change in plain words; the new code runs only in your browser.

The list loads on its own; press Reload to run the async action again and watch the status change. Code written by AgentGid [1].

Checked Oct 12, 2026: it starts without errors in Chromium with zustand 5.0.15, react 19.3.0, react-dom 19.3.0. Needs WebGL.

More Zustand examples

Creating a store in Zustand Updating state from inputs in Zustand Using a Zustand store outside components Updating nested state in Zustand

Sources

  1. Zustand README (GitHub)

Explanations written by AgentGid from the official docs; the numbers in brackets point here. The code marked "written by AgentGid" is ours and free to copy.

Building something with Zustand? Ask AgentGid →