# reduxjs/redux — codebase unpack

> Canonical page: https://codevetter.com/unpack/redux

This is a deterministic Repo Unpack scan of reduxjs/redux — a structural map, not a review, security audit, or maintainer-endorsed description.

- Scanned commit: 56abca4749921d68f40cda20afd2043af9751f72 (2026-09-29)
- Last upstream commit: Merge pull request #4960 from reduxjs/ci/release-commit-skip-forks
- Generated by codevetter 1.15.0 on 2026-10-02
- 331 files scanned · 1.9 MB

Source inspection; upstream code and tests were not executed.

## Languages

- Markdown: 112 files
- TypeScript: 71 files
- JavaScript: 62 files
- JSON: 22 files
- CSS: 11 files
- YAML: 11 files
- HTML: 6 files
- TOML: 1 files

## Repository structure

- examples/ — 106 files
- docs/ — 90 files
- website/ — 50 files
- test/ — 22 files
- src/ — 17 files
- .github/ — 15 files
- scripts/ — 3 files
- logo/ — 2 files

Probable source entrypoint: `src/` (inferred from the tree, not upstream docs)

## Source layout — src/

- src/types/ — 1 file
- src/applyMiddleware.ts — 1 file
- src/createStore.ts — 1 file

## Package

- package.json: redux v5.0.1 — 17 declared dependencies

## Structural health signals

Average score 9.5/10 across 96 files; 1 hotspots. These are deterministic review leads, not proof of a bug.

## Recent history

- 56abca474992 (2026-09-29) Merge pull request #4960 from reduxjs/ci/release-commit-skip-forks
- ab15e57825ca (2026-09-29) Skip Release Commit workflow in forks
- 2c54225d6315 (2026-09-28) Merge pull request #4958 from reduxjs/docs/fundamentals-stackblitz
- b0f9ea4bfa51 (2026-09-28) Point Fundamentals embeds at the flipped example repo tags
- 253280083116 (2026-09-28) Rewrite Fundamentals tutorial with modern example setup

## Overview

Redux is a TypeScript implementation of a framework-independent JavaScript state container for application developers: actions enter a synchronous reducer pipeline, and subscribers read the resulting state. This checkout at 56abca4749921d68f40cda20afd2043af9751f72 packages Redux 5.0.1, maintains runtime and type compatibility tests, and hosts a combined documentation website for several Redux libraries. Its distinctive boundaries are a small in-memory core, composable middleware and store enhancers, and separately maintained React examples that illustrate both modern Toolkit usage and older Redux patterns.

## System map

The primary deliverable is an npm library whose public boundary is src/index.ts. Store execution, reducer composition, middleware composition, and public types occupy separate modules. Application state lives in a store closure, while React integration belongs to external packages used by examples. The documentation site has its own dependency installation, external source acquisition, and static deployment configuration.
- src/index.ts exports createStore, legacy_createStore, combineReducers, bindActionCreators, applyMiddleware, compose, isAction, isPlainObject, and public store/reducer/action/middleware types. — [src/index.ts#L1-L50](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/index.ts#L1-L50)
- createStore owns currentReducer, currentState, listener Maps, a listener ID counter, and the isDispatching guard within each store instance. — [src/createStore.ts#L136-L159](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L136-L159)
- The package exports modern ESM for import consumers, CJS as its default entry, declarations through redux.d.mts, and a legacy ESM module entry; published files include dist and src. — [package.json#L26-L40](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L26-L40)
- tsdown builds five output variants: modern ESM, ES2017 legacy ESM, minified production browser ESM, CJS, and declaration-only ESM. — [tsdown.config.mts#L71-L116](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/tsdown.config.mts#L71-L116)
- Root scripts use pnpm, tsdown, Vitest, TypeScript, oxlint, and oxfmt; build cleans generated output and subsequently strips sourcemap file fields. — [package.json#L41-L54](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L41-L54) [package.json#L75-L76](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L75-L76) [scripts/stripSourcemapFileField.mts#L24-L47](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/scripts/stripSourcemapFileField.mts#L24-L47)
- Root, docs, and website are independent pnpm projects rather than workspace packages; root settings select hoisted linking, disable automatic peer installation, and allow esbuild dependency builds. — [pnpm-workspace.yaml#L1-L23](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/pnpm-workspace.yaml#L1-L23) [docs/package.json#L13-L14](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/docs/package.json#L13-L14) [website/package.json#L63-L71](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/package.json#L63-L71)
- The counter-ts application creates its store with external @reduxjs/toolkit and renders App inside the external react-redux Provider; these integrations are outside the Redux core implementation. — [examples/counter-ts/src/app/store.ts#L1-L8](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/app/store.ts#L1-L8) [examples/counter-ts/src/index.tsx#L1-L18](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/index.tsx#L1-L18) [examples/counter-ts/package.json#L5-L9](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/package.json#L5-L9)
- Netlify builds the independent docs and website projects, forcibly fetches external docs, runs Docusaurus, and publishes website/build; npm publishing is a separate manual workflow using provenance. — [netlify.toml#L1-L20](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/netlify.toml#L1-L20) [website/package.json#L63-L69](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/package.json#L63-L69) [.github/workflows/publish.yml#L1-L32](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/publish.yml#L1-L32)

## Feature catalog

Redux exposes state-management APIs rather than an application router or hosted backend. Users can create stores, subscribe to changes, compose reducers, bind action creators, customize dispatch, replace reducers, and consume observable state. Teaching applications demonstrate counters, todos, shopping carts, and normalized trees. The website adds multi-library navigation, search, production error explanations, and opt-in live examples.
- Stores expose dispatch, subscribe, getState, replaceReducer, and an observable interoperability method; createStore initializes reducers before returning this interface. — [src/createStore.ts#L382-L394](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L382-L394)
- combineReducers creates a root reducer from function-valued map entries, producing one state slice per accepted key and rejecting undefined slice outputs. — [src/combineReducers.ts#L126-L141](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L126-L141) [src/combineReducers.ts#L177-L199](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L177-L199)
- bindActionCreators accepts a single function or a function map, preserves invocation arguments and this, dispatches each result, and skips non-function map values. — [src/bindActionCreators.ts#L9-L15](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/bindActionCreators.ts#L9-L15) [src/bindActionCreators.ts#L58-L82](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/bindActionCreators.ts#L58-L82)
- applyMiddleware customizes dispatch through composable wrappers; compose supports right-to-left composition, an identity function for zero inputs, and unchanged return of a single function. — [src/applyMiddleware.ts#L56-L75](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/applyMiddleware.ts#L56-L75) [src/compose.ts#L46-L60](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/compose.ts#L46-L60)
- The TypeScript counter offers increment, decrement, numeric amount addition, delayed async addition, and conditional addition when the current value satisfies currentValue % 2 === 1. — [examples/counter-ts/src/features/counter/Counter.tsx#L14-L64](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/Counter.tsx#L14-L64) [examples/counter-ts/src/features/counter/counterSlice.ts#L75-L82](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterSlice.ts#L75-L82)
- The todos example appends and toggles todos and selects all, completed, or active items through its connected visible-list container. — [examples/todos/src/reducers/todos.js#L1-L18](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/todos/src/reducers/todos.js#L1-L18) [examples/todos/src/containers/VisibleTodoList.js#L6-L27](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/todos/src/containers/VisibleTodoList.js#L6-L27)
- The shopping-cart example loads mock products, permits additions only when inventory is positive, and clears the cart on checkout request; the tree example supports node counters, child creation, and descendant deletion. — [examples/shopping-cart/src/actions/index.js#L9-L39](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/src/actions/index.js#L9-L39) [examples/shopping-cart/src/reducers/cart.js#L39-L49](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/src/reducers/cart.js#L39-L49) [examples/tree-view/src/containers/Node.js#L6-L26](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/tree-view/src/containers/Node.js#L6-L26) [examples/tree-view/src/reducers/index.js#L44-L70](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/tree-view/src/reducers/index.js#L44-L70)
- The site provides navigation and search tabs for Redux, Toolkit, React Redux, and Reselect, renders error messages selected by ?code=N, and starts StackBlitz examples only after user activation on an isolated page. — [website/docusaurus.config.ts#L27-L104](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/docusaurus.config.ts#L27-L104) [website/docusaurus.config.ts#L127-L142](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/docusaurus.config.ts#L127-L142) [website/src/components/ErrorCodesPage.tsx#L15-L44](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/src/components/ErrorCodesPage.tsx#L15-L44) [website/src/components/LiveExample.tsx#L65-L119](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/src/components/LiveExample.tsx#L65-L119)

## Data flow

The core input boundary is dispatch, with preloaded state supplying the initial state boundary. Reducers transform state synchronously, and subscribers retrieve the resulting value rather than receiving action or state arguments. Middleware can interpret other input forms before reaching base dispatch. Documentation has a separate pipeline from external source acquisition through code-block checking and static page generation.
- createStore assigns supplied preloaded state to currentState and dispatches INIT before exposing the store, allowing reducers to fill undefined initial state. — [src/createStore.ts#L136-L143](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L136-L143) [src/createStore.ts#L297-L301](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L297-L301) [src/createStore.ts#L382-L394](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L382-L394)
- Base dispatch validates a plain-object action and a defined string type before invoking currentReducer; it returns the original action after listener notification. — [src/createStore.ts#L270-L308](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L270-L308) [src/utils/isPlainObject.ts#L5-L15](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/utils/isPlainObject.ts#L5-L15)
- combination passes each slice's previous value and the same action to its reducer, builds nextState, and retains the old root object only if references and key counts match. — [src/combineReducers.ts#L177-L199](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L177-L199)
- Subscription mutations use a copied nextListeners Map, while dispatch iterates its captured listener Map; callbacks receive no arguments and getState returns currentState. — [src/createStore.ts#L152-L175](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L152-L175) [src/createStore.ts#L219-L241](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L219-L241) [src/createStore.ts#L304-L307](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L304-L307)
- Middleware receives getState and a forwarding dispatch closure; its chain wraps the base dispatch, so calls to middlewareAPI.dispatch use the completed outer chain. — [src/applyMiddleware.ts#L65-L75](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/applyMiddleware.ts#L65-L75)
- The inspected core stores state in memory and accepts preloaded state for hydration; persistence is described as an enhancer capability rather than implemented as serialization or disk writes in createStore. — [src/createStore.ts#L136-L143](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L136-L143) [src/createStore.ts#L413-L422](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L413-L422)
- Counter input remains a local string until Number(incrementAmount) || 0 converts it; incrementAsync awaits a 500ms mock Promise and feeds its numeric result into the fulfilled reducer. — [examples/counter-ts/src/features/counter/Counter.tsx#L14-L19](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/Counter.tsx#L14-L19) [examples/counter-ts/src/features/counter/counterSlice.ts#L20-L26](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterSlice.ts#L20-L26) [examples/counter-ts/src/features/counter/counterSlice.ts#L51-L62](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterSlice.ts#L51-L62) [examples/counter-ts/src/features/counter/counterAPI.ts#L1-L6](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterAPI.ts#L1-L6)
- External documentation is copied or sparsely cloned into website/external; TypeScript code blocks become virtual files, receive checker diagnostics, and are syntactically emitted through oxc for JavaScript presentation. — [website/scripts/fetch-external-docs.mts#L101-L136](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L101-L136) [website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L157-L183](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L157-L183) [website/plugins/remark-typescript-tools/transpileCodeblocks/compiler.ts#L117-L184](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/compiler.ts#L117-L184) [website/plugins/remark-typescript-tools/transpileCodeblocks/compiler.ts#L187-L213](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/compiler.ts#L187-L213)

## Behavior traces

The traced flows cover core startup, browser interaction, middleware construction, async counter behavior, reducer replacement, observable delivery, checkout, and documentation acquisition. These walkthroughs follow source execution order and preserve the important conditional branches. They describe expected behavior from code inspection, without asserting successful runtime execution.
- Core startup: createStore validates reducer → normalizes an enhancer passed as argument two → delegates through enhancer(createStore) when supplied; otherwise it allocates state/listeners → dispatches INIT → returns the store. — [src/createStore.ts#L97-L143](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L97-L143) [src/createStore.ts#L382-L394](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L382-L394)
- Vanilla counter: module import → createStore(counter) → render → subscribe(render); an increment click dispatches INCREMENT → counter returns state + 1 → dispatch invokes render → getState().toString() updates the DOM. — [examples/counter-vanilla/index.html#L17-L48](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-vanilla/index.html#L17-L48) [src/createStore.ts#L297-L308](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L297-L308)
- Middleware setup: applyMiddleware(...)(createStore) creates the base store → installs a throwing temporary dispatch → calls each middleware with middlewareAPI → composes wrappers around store.dispatch → returns the copied store with enhanced dispatch. — [src/applyMiddleware.ts#L53-L76](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/applyMiddleware.ts#L53-L76) [src/compose.ts#L46-L60](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/compose.ts#L46-L60)
- Toolkit counter: index.tsx renders Provider(store) and App → App renders Counter → Add Async dispatches incrementAsync(amount) → pending sets loading → fetchCount resolves after 500ms → fulfilled sets idle and adds the payload; rejected sets failed. — [examples/counter-ts/src/index.tsx#L9-L18](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/index.tsx#L9-L18) [examples/counter-ts/src/App.tsx#L5-L14](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/App.tsx#L5-L14) [examples/counter-ts/src/features/counter/Counter.tsx#L53-L57](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/Counter.tsx#L53-L57) [examples/counter-ts/src/features/counter/counterSlice.ts#L20-L62](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterSlice.ts#L20-L62)
- Reducer replacement: replaceReducer validates nextReducer → assigns currentReducer → dispatches REPLACE; combination reuses existing slices, initializes newly undefined slices, and drops keys absent from its new reducer map. — [src/createStore.ts#L320-L335](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L320-L335) [src/combineReducers.ts#L157-L199](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L157-L199) [test/combineReducers.spec.ts#L311-L382](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/combineReducers.spec.ts#L311-L382)
- Observable subscription: store's observable method returns a subscribable object → subscribe validates observer → observeState immediately calls next(getState()) when next exists → registers observeState through store.subscribe → returns its unsubscribe handle. — [src/createStore.ts#L344-L378](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L344-L378) [src/utils/symbol-observable.ts#L7-L10](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/utils/symbol-observable.ts#L7-L10)
- Checkout: checkout(products) snapshots getState().cart → dispatches CHECKOUT_REQUEST, resetting cart → shop.buyProducts invokes its timed callback → CHECKOUT_SUCCESS is dispatched with the saved cart; rollback is an explicitly commented alternative CHECKOUT_FAILURE path. — [examples/shopping-cart/src/actions/index.js#L26-L39](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/src/actions/index.js#L26-L39) [examples/shopping-cart/src/api/shop.js#L6-L12](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/src/api/shop.js#L6-L12) [examples/shopping-cart/src/reducers/cart.js#L39-L49](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/src/reducers/cart.js#L39-L49)
- Docs acquisition: parse flags and requested library names → reject unknown names → skip existing targets unless forced or locally sourced → copyLocalSource or cloneSource → optionally watch local files and spawn pnpm start; clone failures remove partial targets and retry once. — [website/scripts/fetch-external-docs.mts#L83-L98](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L83-L98) [website/scripts/fetch-external-docs.mts#L118-L151](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L118-L151) [website/scripts/fetch-external-docs.mts#L190-L225](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L190-L225)

## Testing signals

Tests and CI were inspected, not executed; no passing result or coverage percentage is established here. Root Vitest tests exercise runtime contracts, while TypeScript fixtures exercise API inference and extension types. CI describes source tests, packed-artifact tests, a compiler-version matrix, and consumer integration builds. This is a bounded inspection, and test discovery and direct source imports limit what can be inferred about examples, documentation, and distribution coverage.
- Root test uses vitest --run --typecheck, with globals enabled and discovery rooted at test; type-tests separately invokes tsc against test/typescript. These configurations were inspected without execution. — [package.json#L47-L50](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L47-L50) [vitest.config.mts#L3-L16](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/vitest.config.mts#L3-L16) [tsconfig.test.json#L1-L9](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/tsconfig.test.json#L1-L9)
- createStore tests assert unsubscribe behavior during notification, subscriptions added mid-dispatch, and the latest subscription snapshot for nested dispatch. — [test/createStore.spec.ts#L290-L343](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L290-L343) [test/createStore.spec.ts#L346-L423](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L346-L423)
- Store tests cover plain-object validation, forbidden reducer-time store operations, recovery after a reducer exception, and non-string action type rejection, including acceptance of an empty string type. — [test/createStore.spec.ts#L462-L470](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L462-L470) [test/createStore.spec.ts#L499-L548](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L499-L548) [test/createStore.spec.ts#L585-L612](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L585-L612)
- combineReducers tests exercise invalid map entries, undefined outputs, initialization failure, referential equality, and root shape changes when reducers are added, changed, or removed. — [test/combineReducers.spec.ts#L29-L120](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/combineReducers.spec.ts#L29-L120) [test/combineReducers.spec.ts#L124-L162](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/combineReducers.spec.ts#L124-L162) [test/combineReducers.spec.ts#L311-L382](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/combineReducers.spec.ts#L311-L382)
- Middleware tests cover construction-time dispatch rejection, one-time setup, recursive dispatch through the chain, thunk behavior, and extra dispatch arguments; observable tests include unsubscribe and RxJS integration. — [test/applyMiddleware.spec.ts#L8-L64](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/applyMiddleware.spec.ts#L8-L64) [test/applyMiddleware.spec.ts#L67-L150](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/applyMiddleware.spec.ts#L67-L150) [test/createStore.spec.ts#L794-L879](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L794-L879)
- Declaration fixtures use expectTypeOf and typed middleware examples for Promise dispatch, thunk dispatch, exact state access, and custom action unions; CI specifies TypeScript 5.6 through 7.0 plus a non-blocking next compiler. — [test/typescript/middleware.test-d.ts#L10-L107](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/typescript/middleware.test-d.ts#L10-L107) [.github/workflows/test.yaml#L132-L144](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L132-L144) [.github/workflows/test.yaml#L175-L186](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L175-L186)
- CI describes lint, format, source tests, build/pack, TEST_DIST artifact tests, package-type analysis, and pinned Toolkit consumer projects for Next, Vite, Node, React Native, and Expo; some tests such as compose.spec.ts import source directly despite TEST_DIST. — [.github/workflows/test.yaml#L59-L82](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L59-L82) [.github/workflows/test.yaml#L121-L130](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L121-L130) [.github/workflows/test.yaml#L224-L237](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L224-L237) [test/compose.spec.ts#L1-L19](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/compose.spec.ts#L1-L19)
- The inspected counter-ts reducer suite asserts initialization and three synchronous actions, without async lifecycle assertions in that file; examples use separate react-scripts test commands and fall outside the root Vitest test directory. — [examples/counter-ts/src/features/counter/counterSlice.spec.ts#L1-L34](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/src/features/counter/counterSlice.spec.ts#L1-L34) [examples/counter-ts/package.json#L27-L31](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-ts/package.json#L27-L31) [examples/shopping-cart/package.json#L19-L24](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/package.json#L19-L24) [vitest.config.mts#L3-L6](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/vitest.config.mts#L3-L6)

## Risk map

These are source observations and explicitly marked hypotheses, not confirmed vulnerabilities. The inspected core executes caller-provided reducers and middleware in process and validates only a limited action shape. Operational boundaries appear in documentation acquisition, mutable build output, browser embeds, and publishing automation. Compatibility and validation gaps require attention because the library has several distributed formats and the site consumes independently changing repositories.
- Base dispatch validates action shape and type but performs no payload authorization, sanitization, or deep serializability validation in the inspected implementation; payload and reducer trust remain application responsibilities. — [src/createStore.ts#L270-L301](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L270-L301) [src/types/actions.ts#L7-L13](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/actions.ts#L7-L13)
- getState returns the stored reference, and combination detects changes using slice references rather than deep comparisons; a mutating reducer can violate the documented pure-reducer contract without this mechanism detecting the mutation. (inferred) — [src/createStore.ts#L166-L175](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L166-L175) [src/combineReducers.ts#L182-L199](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L182-L199) [src/types/reducers.ts#L15-L24](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/reducers.ts#L15-L24)
- Subscriber callbacks run after currentState is assigned and have no individual exception handling; a throwing callback stops ordinary Map.forEach iteration and does not roll back the already assigned state. — [src/createStore.ts#L297-L308](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L297-L308)
- The main CI path filter lists src, test, .github, tsdown.config.mts, and pnpm-lock.yaml, but omits package.json, scripts, tsconfig files, and vitest.config.mts; an isolated change to an omitted file does not satisfy the build job's src condition. — [.github/workflows/test.yaml#L17-L31](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/test.yaml#L17-L31)
- External docs default to master refs, honor caller-provided repository/ref/local-source settings, and copy or symlink files from outside the checkout; --force and local refresh remove existing generated targets before reacquisition. — [website/scripts/fetch-external-docs.mts#L50-L77](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L50-L77) [website/scripts/fetch-external-docs.mts#L101-L120](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L101-L120) [website/scripts/fetch-external-docs.mts#L197-L214](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L197-L214)
- Netlify sets DOCS_TYPECHECK=warn, and the code-block plugin then emits warnings rather than failing on diagnostics; this configuration permits publication with reported snippet type errors. — [netlify.toml#L17-L20](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/netlify.toml#L17-L20) [website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L174-L183](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L174-L183)
- Build is a mutating operation: clean removes dist and coverage, the Babel plugin may rewrite tracked errors.json, and transform failures are logged before returning null rather than explicitly rethrown by the tsdown hook. — [package.json#L51-L53](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L51-L53) [scripts/clean.mts#L1-L9](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/scripts/clean.mts#L1-L9) [scripts/mangleErrors.mts#L178-L182](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/scripts/mangleErrors.mts#L178-L182) [tsdown.config.mts#L39-L42](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/tsdown.config.mts#L39-L42)
- The vanilla example loads an unpinned redux@latest browser module from unpkg, while legacy examples declare Redux 4 and React 17; these examples therefore do not uniformly exercise the pinned Redux 5 source. — [examples/counter-vanilla/index.html#L16-L17](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/counter-vanilla/index.html#L16-L17) [examples/shopping-cart/package.json#L10-L17](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/package.json#L10-L17) [examples/todos/package.json#L8-L13](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/todos/package.json#L8-L13) [examples/tree-view/package.json#L11-L15](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/tree-view/package.json#L11-L15)

## Extension points

Core extensibility comes from function interfaces rather than a named plugin registry. Reducers define state transitions, middleware wraps dispatch, and enhancers wrap store creation. Runtime reducer replacement and observable interoperability expose additional integration seams. Website extensibility uses explicit library metadata, Docusaurus plugin instances, navbar component registration, and configurable Markdown transformation hooks.
- A custom root reducer plugs directly into createStore; the Reducer type separates returned state, accepted actions, and optional preloaded-state input shape. — [src/createStore.ts#L86-L96](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L86-L96) [src/types/reducers.ts#L30-L34](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/reducers.ts#L30-L34)
- Reducer maps plug into combineReducers, whose mapped types infer combined state, action unions, and partial preloaded state; only function-valued entries participate at runtime. — [src/combineReducers.ts#L114-L141](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L114-L141) [src/types/reducers.ts#L62-L68](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/reducers.ts#L62-L68) [src/types/reducers.ts#L94-L114](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/reducers.ts#L94-L114)
- Middleware plugins implement api => next => action with unknown action inputs and outputs; applyMiddleware overloads accumulate middleware dispatch extensions into the enhanced store type. — [src/types/middleware.ts#L22-L29](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/middleware.ts#L22-L29) [src/applyMiddleware.ts#L24-L52](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/applyMiddleware.ts#L24-L52)
- StoreEnhancer wraps a StoreEnhancerStoreCreator and combines store/state extensions; createStore delegates to the enhancer before allocating its own base store. — [src/types/store.ts#L220-L232](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/store.ts#L220-L232) [src/createStore.ts#L121-L134](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L121-L134)
- replaceReducer supports dynamic reducer loading and hot replacement, while the observable method provides reactive-library integration using Symbol.observable or the @@observable fallback. — [src/createStore.ts#L311-L335](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L311-L335) [src/createStore.ts#L344-L378](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L344-L378) [src/utils/symbol-observable.ts#L7-L10](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/utils/symbol-observable.ts#L7-L10)
- Adding an external documentation library involves the sources acquisition table, libraries navigation metadata, and a Docusaurus docs-plugin instance; these are separate explicit configuration seams. — [website/scripts/fetch-external-docs.mts#L32-L78](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L32-L78) [website/docusaurus.config.ts#L27-L104](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/docusaurus.config.ts#L27-L104) [website/docusaurus.config.ts#L311-L330](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/docusaurus.config.ts#L311-L330)
- Navbar ComponentTypes registers custom-libraryDropdown and custom-libraryLinks; useCurrentLibrary chooses a non-root route prefix match, then root metadata, then the first library. — [website/src/theme/NavbarItem/ComponentTypes.tsx#L1-L9](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/src/theme/NavbarItem/ComponentTypes.tsx#L1-L9) [website/src/components/useCurrentLibrary.ts#L50-L66](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/src/components/useCurrentLibrary.ts#L50-L66)
- transpileCodeblocks accepts custom compiler settings, TypeScript/JavaScript post-processors, replacement-node assembly, and file extensions; code-block metadata can explicitly opt out with no-transpile. — [website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L30-L57](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L30-L57) [website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L159-L171](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/plugins/remark-typescript-tools/transpileCodeblocks/plugin.ts#L159-L171)

## Contributor handoff

Start with the public export surface and the implementation/type pair for the affected API. Preserve synchronous reduction, subscriber snapshot behavior, and package-format compatibility when editing the core. Tests and CI were inspected, not executed, and this bounded report does not establish exhaustive coverage or passing checks. Website acquisition and root build commands have side effects, so future execution requires authority beyond this read-only investigation.
- For a core change, first read src/index.ts, the affected implementation, and matching public types; these jointly define exported names, runtime behavior, and consumer contracts. — [src/index.ts#L13-L50](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/index.ts#L13-L50) [src/types/store.ts#L81-L119](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/store.ts#L81-L119) [src/types/reducers.ts#L30-L34](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/reducers.ts#L30-L34) [src/types/middleware.ts#L22-L29](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/types/middleware.ts#L22-L29)
- Subscription changes must preserve copy-on-write Maps, idempotent unsubscribe, and nested-dispatch snapshots; read the corresponding createStore tests before changing listener bookkeeping. — [src/createStore.ts#L152-L159](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L152-L159) [src/createStore.ts#L219-L241](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L219-L241) [test/createStore.spec.ts#L313-L423](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/createStore.spec.ts#L313-L423)
- Do not handle randomized Redux INIT, REPLACE, or probe strings as application action types; reducers must initialize undefined state and return current state for unknown actions. — [src/utils/actionTypes.ts#L1-L17](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/utils/actionTypes.ts#L1-L17) [src/combineReducers.ts#L62-L93](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/combineReducers.ts#L62-L93)
- createStore's deprecation annotation recommends external Toolkit configureStore while explicitly retaining the core API; legacy_createStore is the documented alternative without the visual deprecation warning. — [src/createStore.ts#L16-L38](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/src/createStore.ts#L16-L38)
- When execution is authorized, use the existing pnpm test, pnpm type-tests, pnpm lint, and pnpm format:check scripts and scope the first runtime check to the affected suite; tests and CI in this report were inspected, not executed. — [package.json#L43-L50](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L43-L50) [CONTRIBUTING.md#L57-L75](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/CONTRIBUTING.md#L57-L75) [vitest.config.mts#L3-L16](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/vitest.config.mts#L3-L16)
- Packaging changes require reviewing exports, all tsdown output variants, TEST_DIST aliasing, and CI's packed-artifact checks; source-direct imports can bypass artifact resolution even in the dist job. — [package.json#L26-L35](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/package.json#L26-L35) [tsdown.config.mts#L71-L116](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/tsdown.config.mts#L71-L116) [vitest.config.mts#L7-L14](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/vitest.config.mts#L7-L14) [test/compose.spec.ts#L1-L1](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/test/compose.spec.ts#L1-L1)
- Keep project installation boundaries distinct: root/docs/website are independent pnpm projects, and standalone examples have their own manifests; older examples' Redux 4 dependencies are not proof of Redux 5 compatibility. — [pnpm-workspace.yaml#L1-L7](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/pnpm-workspace.yaml#L1-L7) [CONTRIBUTING.md#L81-L89](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/CONTRIBUTING.md#L81-L89) [examples/shopping-cart/package.json#L10-L17](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/examples/shopping-cart/package.json#L10-L17)
- Before website execution, inspect fetch-external-docs and Netlify settings for clone/copy/removal behavior, moving external refs, warning-only snippet checks, and required isolation headers; publishing also has separate manual npm and automatic commit-preview workflows. — [website/scripts/fetch-external-docs.mts#L190-L225](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/website/scripts/fetch-external-docs.mts#L190-L225) [netlify.toml#L1-L31](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/netlify.toml#L1-L31) [.github/workflows/publish.yml#L1-L32](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/publish.yml#L1-L32) [.github/workflows/release-commit.yml#L3-L16](https://github.com/reduxjs/redux/blob/56abca4749921d68f40cda20afd2043af9751f72/.github/workflows/release-commit.yml#L3-L16)

Source repository: https://github.com/reduxjs/redux
Full evidence corpus: https://github.com/Codevetter/codevetter/tree/main/benchmarks/repo-unpacks/redux.json

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
