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:
bashgit 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:
tsximport { 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:
csshtml,
body,
#root {
height: 100%;
}
#root {
display: flex;
place-items: center;
justify-content: center;
color: #fff;
background-color: #131311;
}
Adapt the structure
-
Install Zustand in your React project:
bashnpm install zustand -
Replace
Storewith the state and actions your feature owns. Keep actions beside the state they update. -
Create the store at module scope with
create, as the starter does. This gives components a stable hook to call. -
In each component, select only the state or actions it renders or invokes. For example,
useStore((state) => state.count)returns the selected number, whileuseStore((state) => state.inc)returns the action. -
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?