CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

pmndrs/zustand

Scanned commit d7a5583cff dated 2026-09-29 — last upstream commit. Generated by codevetter 1.15.0 on 2026-10-02.

github.com/pmndrs/zustand ↗ · 130 files · 733 KB

A small, fast and scalable bearbones state-management solution using simplified flux principles.

Deep analysis by cli:codex via the codex CLI on 2026-10-02 (314s) — every claim below links to its cited source files. Source inspection; upstream code and tests were not executed.

Overview

Zustand is a TypeScript state-management library for React developers and applications that need stores outside React. Its core keeps state and synchronous subscriptions in a small closure; React bindings turn that API into selector-based hooks without requiring a provider. Optional middleware adds persistence, Redux DevTools, reducers, Immer updates, and selective subscriptions, while separate package entrypoints preserve the vanilla/React boundary.

System map

The package separates a framework-independent store from React consumers and opt-in middleware. State lives in memory unless a consumer supplies persistence middleware and storage. Rollup produces CommonJS, ESM, and declarations; GitHub Actions describes validation, package publication, previews, and documentation deployment.

Feature catalog

The principal user-facing surface is a library API for creating, reading, updating, and subscribing to stores. Equality helpers and middleware provide optional behavior without changing the basic store model. The examples demonstrate counters, snippet selection and copying, and an interactive graphical backdrop.

Data flow

State updates enter through values, updater functions, reducers, or middleware-wrapped setters. The vanilla store owns the resulting snapshot and notifies synchronous subscribers; React selects snapshots through its external-store interface. Persistence and DevTools create additional output and input boundaries around that same store.

Behavior traces

The source supports concrete walks through initialization, counter updates, selective subscriptions, persistence, and external debugging. Synchronous persistence can affect the returned initial state, whereas asynchronous hydration completes after initialization. Clearing storage invalidates pending hydration but preserves live state.

Testing signals

Tests and CI were inspected, not executed; their existence supplies coverage intent, not passing results. Vitest uses jsdom, React Testing Library, and source aliases, while TypeScript checking separately validates API and middleware contracts. The inspected inventory is bounded: mocked adapters, synthetic DOM hydration, and configured compatibility matrices do not establish exhaustive runtime or browser coverage.

Risk map

The material boundaries inspected are persisted data, browser-extension messages, server store ownership, and synchronous update propagation. These are source observations and explicitly identified hypotheses, not confirmed vulnerabilities. Packaging and examples also expose verification limits; the bounded inspection does not establish whole-repository absence of other sensitive paths.

Extension points

Extension centers on StateCreator factories and higher-order middleware rather than a runtime plugin loader. TypeScript module augmentation tracks how middleware changes StoreApi. Storage, selectors, comparators, reducers, slices, and exported entrypoints are the principal customization boundaries.

Contributor handoff

Start with the affected runtime module and its API/type contract before editing. Tests and CI were inspected, not executed, so all suggested validation remains future work when execution is authorized. Keep changes focused on source and meaningful regressions, and treat initialization, middleware ordering, hydration generations, and generated declarations as coupled contracts.

Languages

LanguageFilesShare of source
Markdown47docs/config
TypeScript3468%
JavaScript1632%
YAML13docs/config
JSON7docs/config
CSS3docs/config
HTML2docs/config

Start reading here

Probable source entrypoint: src/index.ts — inferred from the directory tree and manifest, not the upstream docs.

Source roots

src/ (16 files)

Source layout — src/

PathFiles
src/middleware/7
src/react/1
src/vanilla/1
src/index.ts1
src/middleware.ts1
src/react.ts1
src/shallow.ts1
src/traditional.ts1
src/types.d.ts1
src/vanilla.ts1

Repository structure

Top-level pathFiles
docs/42
examples/31
src/16
tests/15
.github/14

Docs found: CONTRIBUTING.mdREADME.mddocs/index.mddocs/learn/getting-started/comparison.mddocs/learn/getting-started/introduction.mddocs/learn/guides/advanced-typescript.mddocs/learn/guides/auto-generating-selectors.mddocs/learn/guides/beginner-typescript.mddocs/learn/guides/connect-to-state-with-url-hash.mddocs/learn/guides/event-handler-in-pre-react-18.md

Package

package.json — zustand v5.0.15, 39 declared dependencies.

@eslint/js@redux-devtools/extension@rollup/plugin-alias@rollup/plugin-node-resolve@rollup/plugin-replace@rollup/plugin-typescript@testing-library/jest-dom@testing-library/react@types/node@types/react@types/react-dom@types/use-sync-external-store

CI & config entrypoints

Structural health signals

Average score 9.2/10 across 33 analyzed source files; 1 hotspot surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history