Skip to content
D
Documentation

Start from the Zustand starter

how-to
2 min readUpdated

Use the React starter when you want a running example before adapting Zustand to your own application. It creates one store, selects state and an action in a component, and renders a counter that changes when you click +1.

Run the starter

The starter uses React 18, Vite, TypeScript, and Zustand. Run it from a clone of the Zustand repository:

bash
git clone https://github.com/pmndrs/zustand
cd zustand
pnpm install
cd examples/starter
pnpm install
pnpm dev

Open the local address printed by Vite. You see the Zustand mascot, the heading Zustand Starter, the initial count 0, and a +1 button. Each click increments the displayed count.

You can also open the starter in StackBlitz. Read the starter source when you want to compare the running example with its files.

Use the same structure in a small app

This complete entry point keeps the store at module scope, selects the count and action separately, and mounts a working counter:

tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { create } from 'zustand'

type Store = {
  count: number
  inc: () => void
}

const useStore = create<Store>((set) => ({
  count: 0,
  inc: () => set((state) => ({ count: state.count + 1 })),
}))

function Counter() {
  const count = useStore((state) => state.count)
  const inc = useStore((state) => state.inc)

  return (
    <main>
      <p>Count: {count}</p>
      <button type="button" onClick={inc}>
        +1
      </button>
    </main>
  )
}

const root = document.getElementById('root')!

createRoot(root).render(
  <StrictMode>
    <Counter />
  </StrictMode>,
)

The page initially shows Count: 0 and a +1 button. Clicking the button calls inc, and the rendered count increases.

The starter's layout also depends on its global stylesheet. Keep this file when copying the example, or replace it with your application's layout styles:

css
html,
body,
#root {
  height: 100%;
}

#root {
  display: flex;
  place-items: center;
  justify-content: center;
  color: #fff;
  background-color: #131311;
}

Adapt the structure

  1. Install Zustand in your React project:

    bash
    npm install zustand
    
  2. Replace Store with the state and actions your feature owns. Keep actions beside the state they update.

  3. Create the store at module scope with create, as the starter does. This gives components a stable hook to call.

  4. In each component, select only the state or actions it renders or invokes. For example, useStore((state) => state.count) returns the selected number, while useStore((state) => state.inc) returns the action.

  5. Render the selected state and pass the selected action to the relevant event handler. The mounted component then shows the current store value, and the action changes that value through set.

The starter's complete result is a mounted React application with a store-backed counter. Adapt the Store type, the object passed to create, and the component markup while keeping this boundary between store logic and rendered UI.

Was this page helpful?

Start from the Zustand starter — zustand · GPT-5.6 Luna