Before touching Zustand, you need to master modern JavaScript, React hooks, and understand the difference between local state, global state, and server state. This episode sets up a Vite project, installs zustand, and verifies your first installation.

Welcome to the Learning Zustand series! This series will take you from the most basic store concept all the way to production-grade architecture in Zustand — modern state management for React that is small, boilerplate-free, and used by thousands of projects worldwide. There are 23 episodes in total, arranged into six phases: pre-requisites, core concepts, middleware, advanced integration, scaling, and production readiness.
Before touching zustand, there are some core skills and software you must have. Why do these prerequisites matter? Because Zustand is built on React's mental model: hooks, re-renders, and the component lifecycle. Without that foundation, the concepts of selectors, subscriptions, and transient updates will feel like a black box.
Episode 0 is your roadmap: we will make sure you have the core skills, set up a Vite project, install Zustand, and do your first verification. Once this episode is done, the rest of the series can be followed comfortably.
Zustand is a JavaScript/TypeScript library, so you must be comfortable with modern syntax: destructuring, arrow functions, async/await, and template literals. Here are examples of patterns you will keep using:
const { count, increment } = useStore()
const doubled = count * 2
const message = `Total: ${count}`
const fetchData = async () => {
const res = await fetch('/api/user')
return res.json()
}Destructuring like const { count, increment } = useStore() is the pattern that appears most often throughout the entire series. If destructuring, arrow functions, and async/await are not yet smooth, take some time to practice first.
The React hooks you must master: useState for local state, useEffect for side effects, and useContext for sharing values between components. It is also important to understand the Context re-render problem: when a context value changes, all components using useContext re-render, including those that don't read the value that changed.
const [count, setCount] = useState(0)
const { theme } = useContext(ThemeContext)Understanding this weakness of Context will motivate why Zustand exists — the details are covered in episode 1. useState(0) and useContext(ThemeContext) are the foundations you will compare against the Zustand API later.
Before choosing a state management tool, you must be able to classify state:
Zustand is best suited for client-side global state. Server state should be handled by TanStack Query or SWR — the full comparison is in episode 12.
Make sure Node.js version 18 or newer is installed on your system. You may use npm or bun — both are fully supported by this project.
node -v
npm --versionThe output of node -v must show version 18.0.0 or higher. npm --version shows the npm version, and you can replace npm with bun if you prefer. Both package managers will be used interchangeably throughout the series.
Use an editor with full TypeScript support — VS Code is the most common choice. Don't forget two important browser extensions: React DevTools for component inspection and Redux DevTools for debugging Zustand (enabled via the devtools middleware in episode 10).
Vite is the fastest way to start a React project for learning. Open your terminal and run:
npm create vite@latest belajar-zustand -- --template react-ts
cd belajar-zustand
npm installThe react-ts template is chosen because the entire series uses TypeScript. After npm install finishes, your project is ready to have Zustand installed. If you already have a Next.js project, the installation steps are identical.
With the project ready, install the core library:
npm i zustandThe installed version is v5.x — at the time of writing this series, the latest stable version is 5.0.14 (May 2026). If you're using bun, the command is bun add zustand. There are no additional peer dependencies besides React, so the installation is very light.
Create a src/stores/ folder, then write your first counter store:
import { create } from 'zustand'
export const useCounter = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}))In the App.jsx component, call the store:
import { useCounter } from './stores/counter'
export default function App() {
const count = useCounter((s) => s.count)
const increment = useCounter((s) => s.increment)
return <button onClick={increment}>Klik: {count}</button>
}useCounter((s) => s.count) is the use of a selector — the component only reads the slice it needs. If the button shows an increasing number on every click, your installation is successful and the environment is ready to use.
Tip
Open React DevTools and look at the Components tab: you won't find a Provider anywhere. Zustand doesn't need a Provider, an advantage we will break down in episode 2.
Here's a recap of what you prepared in episode 0:
If anything is still missing, stop here and complete it before continuing. A strong foundation will make the next 22 episodes feel far lighter.
In episode 0 you laid the groundwork for the entire series: mastering the core JavaScript and React skills, understanding state classification, setting up a Vite project, installing Zustand v5, and verifying your first working store.
Key takeaways:
npm i zustand or bun add zustand.In the next episode we will discuss the history, background, and why you need Zustand — from the evolution of prop drilling toward Context and boilerplate-heavy Redux, the birth of Zustand by the pmndrs team, to the problems it solves. Make sure your environment is ready, because your Learning Zustand journey has only just begun!