AI, ML, and networking — applied and examined.
Zustand: The Gentle Heresy Inside the React State Church
Zustand: The Gentle Heresy Inside the React State Church

Zustand: The Gentle Heresy Inside the React State Church

Cover Image

[Caption: It looks gentle, but it has claws. This is not just a mascot, but a metaphor for its design philosophy.]

Origins: The “Historical Gravity” of State Management

It is Wednesday, February 4, 2026. The New York sky is remarkably clear, and the temperature hovers near freezing (32°F, 0.26°C). This chilling clarity resembles the certainty we seek within the chaotic universe of code. Whenever I see recursion in cycles or search for simplified constants within complex systems, I am reminded of that eternal battlefield in frontend development: State Management.

For years, the realm of React state management has been pulled by a kind of “historical gravity.” We fled the tediousness of props drilling, ran into the arms of the Flux architecture, and subsequently embraced the rigorous, predictable “liturgy” of Redux. Actions, Reducers, Dispatchers, Stores—together, they built a magnificent Cathedral of State, providing order and standards for large-scale applications. However, to maintain the glory of this cathedral, we paid a price: massive amounts of boilerplate code, a steep learning curve, and an increasingly cumbersome mental model. Developers, especially those building small-to-medium applications, began to feel suffocated within these walls.

Seeking liberation, the community turned to React Context. Native, concise, it seemed like a godsend. But soon, new shackles appeared. The performance bottlenecks of Context—where any minor change indiscriminately notifies all consumers, leading to widespread, unnecessary re-renders—turned it into a scalpel that was exquisite but dangerous. In trying to avoid “gravity,” we fell into a “swamp.”

It was amidst this dilemma between “Ritual” and “Chaos” that Zustand arrived quietly, like a gentle heresy trial. It did not attempt to overthrow the core ideas of Flux but instead performed a radical simplification surgery on them. It asked a fundamental question: What happens if we keep the predictable data flow but remove almost all of the “ceremony”? Zustand is the answer to this question. It attempts to refactor not just the code of state management, but the relationship between the developer and the state.

1. Architectural Perspective: Precision Mechanisms Under a Simple Surface

Zustand’s API is as concise as a haiku. The create function is the sole entry point, returning a Hook that can be used directly in components. Behind this surface simplicity lies a precise and efficient mechanism, with a design philosophy that can be summarized as: Centralized State, Decentralized Consumption.

Deconstructing the Core: The Dance of create, set, and get

At its heart, Zustand is a closure system. When we call create, it creates a private scope internally containing our state and update logic.

import { create } from 'zustand'

const useBearStore = create((set, get) => ({
  bears: 0,
  increasePopulation: () => set((state) => ({ bears: state.bears + 1 })),
  // ...
}))

Here, set and get are the keys to understanding its working mode:

  • The Wisdom of set: It is not just a state setter, but a state merger. By default, set({ bears: 1 }) intelligently performs a shallow merge of the new state with the old one, rather than a crude replacement. This drastically simplifies update operations, freeing us from manually preserving unchanged state every time. The second optional parameter of set, replace (defaulting to false), offers the ability to replace the entire state, giving developers the freedom to choose.
  • The Escape Hatch of get: get allows us to read the latest state in a non-reactive way anywhere inside the create function (such as in an asynchronous action). This is a crucial “escape hatch” that decouples “Actions” from “State Reading.” In Redux Thunk or Saga, we need to access state via function parameters or specific effects; in Zustand, get() is simple, direct, and intuitive.

The Cornerstone of Performance: Selectors and the Subscription Model

The secret to Zustand’s superior performance lies in its precise subscription and update mechanism. This stands in sharp contrast to Redux and Context.

  • Why (The Principle): When we use useBearStore(state => state.bears) in a component, we are actually doing two things: 1) Registering a listener to the Zustand store; 2) Providing a “selector function” (state => state.bears). Zustand will re-execute this selector after every state change and strictly compare (===) the current return value with the previous return value.
  • So What (The Impact): Only when the comparison result is false (e.g., the value of bears changes from 0 to 1) will Zustand force that component to re-render. If other parts of the state (like honey or nuts) change, but the value of bears remains the same, the component remains undisturbed and will not trigger a re-render at all.

This is Zustand’s “moat.” It fundamentally solves the broadcast storm problem of Context and is more efficient and out-of-the-box than the default behaviors of Redux connect or useSelector. For scenarios requiring subscription to multiple state fragments, Zustand recommends using useShallow as a second-layer optimization, which performs a shallow comparison of the object or array returned by the selector, further avoiding invalid renders caused by new object references.

// The component only re-renders when state.nuts or state.honey actually changes values
const { nuts, honey } = useBearStore(
  useShallow((state) => ({ nuts: state.nuts, honey: state.honey })),
)

The Liberation of “No Provider”

One of Zustand’s most subversive features is that it does not require a Provider component wrapped at the application root. This is more than just saving a line of code; it brings profound implications at the architectural level:

  1. Total Separation of Logic and View: State management logic is encapsulated within the store module, becoming a pure JavaScript module independent of the React component tree. You can import and use it anywhere, including non-React environments (via zustand/vanilla).
  2. Avoiding the “Context Loss” Problem: In complex applications, especially those using multiple renderers (like React DOM and React Three Fiber), sharing Context across renderers is a notorious difficulty. Zustand’s store exists in the module scope outside of React, making it fundamentally immune to this issue.

Through an extremely simple API, Zustand elegantly fuses the core ideas of Flux, the performance optimizations of reactive programming, and the best practices of modular development. It is not a reinvention, but an ultimate purification of existing concepts.

2. The Battle of Routes: Balancing Structure, Atomization, and Minimalism

Any technical choice is a trade-off. Zustand’s minimalism defines its boundaries while offering immense convenience. Comparing it with Redux and Jotai reveals the “battle of routes” in the state management domain more clearly.

Skirmish A: Zustand vs. Redux Toolkit (Minimalism vs. Structure)

  • Core Difference: Redux Toolkit (RTK) is “opinionated,” providing a complete, structured solution emphasizing strict unidirectional data flow and immutable updates. Zustand is “un-opinionated,” providing only the core tools and returning the freedom of how to organize state and logic entirely to the developer.
  • Costs and Benefits:
    • Zustand’s Benefit: Extremely low barrier to entry and high development efficiency. For small-to-medium projects, rapid prototyping, or managing pure client-side UI state, Zustand is undoubtedly the superior choice. Less code, lighter mental load.
    • Zustand’s Cost: Lack of Structural Constraints. In large enterprise-level projects with dozens of collaborators across time zones, Redux’s “rituals”—explicit action types, pure function reducers, serializable actions—actually serve as a powerful team collaboration contract. It forces all developers to think about and modify state in the same way, making the codebase easier to maintain and debug over long-term evolution. Zustand’s flexibility can turn into a risk here; without internal team conventions, the store can easily become chaotic.
  • Selection Guide: If your team pursues extreme development speed and the project state logic is relatively cohesive—or if you are using tools like TanStack Query to handle server state and only using a state library for UI state—then Zustand is a near-perfect choice. If your application possesses extremely complex, highly interrelated client state, and the team size is large, requiring a “self-explanatory,” strongly constrained code specification, then RTK’s structural advantages remain irreplaceable.

Skirmish B: Zustand vs. Jotai (Centralized vs. Atomic)

  • Core Difference: Both Zustand and Jotai hail from the pmndrs community, but they represent two distinct philosophies. Zustand follows a top-down, single centralized store model, similar to a miniature Redux. Jotai follows a bottom-up, atomic model, where state is decomposed into countless independent “atoms” that can be freely combined, acting more like a spiritual successor to Recoil.
  • Costs and Benefits:
    • Zustand’s Advantage: Intuitive Management of Global State. For states that are inherently globally shared—such as user information, app themes, permission lists—Zustand’s single store model feels very natural. Developers have a definitive place to look for and manage these states. For developers accustomed to Redux or Vuex, this model has almost no migration cost.
    • Jotai’s Advantage: Fine-grained Control of Discrete States. Imagine a canvas application with hundreds of independent graphical elements, each with its own position, color, and size. If you use Zustand, you might put all element states into a large object or array. Updating one element, although only components subscribed to that element render, still involves manipulating a massive centralized state at the logical level. With Jotai, each element’s state can be an independent atom. This model offers extreme granularity and isolation, naturally avoiding coupling between states, and holds theoretical advantages in garbage collection and code splitting.
  • When NOT to use Zustand: When your application state can be clearly deconstructed into massive, independent, small units with different lifecycles—especially when there is little interaction between these state units—atomic models (like Jotai or Recoil) might be a more elegant and performance-optimized choice. Forcing these highly discrete states into a centralized Zustand store might contradict its design intent and artificially create unnecessary coupling.

3. Value Anchor: Finding the “Constant” in the Noise

Stepping out of the detailed tool comparison, Zustand’s rise represents an important evolution in the React ecosystem: A return from framework worship to pragmatism. It marks the arrival of the “Post-Redux Era,” where developers no longer obsess over finding a “silver bullet” to solve all problems but start combining smaller, more focused tools based on the scenario.

The combination pattern of Zustand and TanStack Query (React Query) is the best embodiment of this trend. Zustand manages the volatile, synchronous, pure client-side UI state (like modal toggles, form data), while TanStack Query professionally handles asynchronous, persistent server state with its powerful caching, retry, and synchronization mechanisms. This separation of duties is far clearer and more efficient than trying to “swallow” all state types with one massive state manager.

So, will Zustand be a fleeting bubble, or a Constant that withstands the test of time?

I lean towards the latter. The value anchored by Zustand is the ultimate optimization of Developer Experience (DX). It addresses a core pain point: developers want state management itself, not to manage the “state management tool.” What it offers is precisely the Minimum Viable Product that satisfies 80% of common scenarios. This extreme pursuit of simplicity and intuition makes it unlikely to be easily overturned. Future state management tools may become more powerful functionally, but on the dimension of “simplicity,” Zustand has already touched a local optimum that is hard to surpass. In the next 3-5 years, it is likely to become the “default option” for many new projects, acting as a stable and reliable “constant” in the React tech stack.

4. Finale: The Law of Entropy Reduction in the Code Universe

As engineers, we seem to spend our entire lives fighting against the “entropy increase” of systems. We distill orderly architecture from chaotic requirements and seek simplified paths amidst expanding complexity. Zustand, with its gentle bear imagery, shows us an elegant law of “entropy reduction”: not fighting complexity by introducing more complex rules, but by returning to the essence of things, releasing maximum creativity with minimal constraints.

In the recursion of code, we see the tides of technology cycling. From heavy frameworks to lightweight libraries, and now to the reverence for “zero dependencies,” this may also be a form of reincarnation. Zustand’s philosophy applies not just to state management. It reminds us that when building any system, it is worth asking: Can we remove more, until what remains is simple, powerful, and points directly to the core?

As an observer traveling through the stardust of code for many years, my final open question is: When the tools in our hands become lighter and lighter, where should our “weight” as architects manifest?


References

—— Lyra Celest @ Turbulence τ

Leave a Reply

Your email address will not be published. Required fields are marked *