Introduction to Zustand

A deep dive into the small, fast, and scalable state management library for React.
11/28/2025
frontend 3 min read
Introduction to Zustand

What is Zustand?

Zustand is a small, fast, and scalable state management library for React. It allows you to create a global store (state) that can be accessed from any component in your application.

Why Zustand?

Developers choose Zustand because it solves the complexities of state management with very little friction. Here are the key advantages:

  • No Boilerplate: Unlike Redux, there are no reducers, dispatchers, or action types variables. You just write functions to change state.
  • No Providers: You do not need to wrap your app in a <Provider> (like you do with Context or Redux). The state exists globally outside the component tree.
  • Performance (Selective Re-renders): This is the biggest win. With React Context, if one piece of the context changes, often every component using that Context re-renders. With Zustand, components only re-render if the specific piece of state they are "listening" to changes.
  • Async Handling: It handles async actions (fetching data) out of the box without needing middleware like Thunk or Saga.
  • Flexible: It works with plain JavaScript, does not enforce a rigid structure, and can even be used outside of React components.

When to use Zustand?

Use useState if: The state is local to a single component or just shared between a parent and child.

Use Zustand if:

  • You have "global" state (e.g., User Authentication, Dark Mode, Shopping Cart, Notifications).
  • You are currently using Context API but facing performance issues (unnecessary re-renders).
  • You want a global state solution that takes less than 5 minutes to set up.
  • You want to avoid "Prop Drilling" (passing data down through 10 layers of components).

Use Redux if: You are working on a massive enterprise app where strict architectural patterns, rigid traceability, and time-travel debugging are strict team requirements.

Example Code: Counter App

1. store.js (Where the logic lives)

import { create } from "zustand";

const useStore = create((set) => ({
  count: 0,
  increase: () => set((state) => ({ count: state.count + 1 })),
  decrease: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}));

export default useStore;

2. App.js (The UI Component)

import React from "react";
import useStore from "./store";

function App() {
  // 1. Get data from the store
  // Zustand allows us to select only the specific variables we need
  const count = useStore((state) => state.count);
  const increase = useStore((state) => state.increase);
  const decrease = useStore((state) => state.decrease);
  const reset = useStore((state) => state.reset);

  return (
    <div style={{ padding: "20px" }}>
      <h1>Count: {count}</h1>
      <button onClick={decrease}> - </button>
      <button onClick={reset}> Reset </button>
      <button onClick={increase}> + </button>
    </div>
  );
}

export default App;