# https://github.com/reduxjs/redux-toolkit Project Manual

Generated at: 2026-06-17 19:10:14 UTC

## Table of Contents

- [Overview & Architecture](#page-1)
- [Core Store & State Management APIs](#page-2)
- [RTK Query: Server Data, Hooks & Code Generation](#page-3)
- [Advanced Patterns, Extensibility & Tooling](#page-4)

<a id='page-1'></a>

## Overview & Architecture

### Related Pages

Related topics: [Core Store & State Management APIs](#page-2), [RTK Query: Server Data, Hooks & Code Generation](#page-3), [Advanced Patterns, Extensibility & Tooling](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [packages/toolkit/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/package.json)
- [packages/toolkit/scripts/issue-triage/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/package.json)
- [packages/toolkit/scripts/issue-triage/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/README.md)
- [packages/toolkit/scripts/issue-triage/src/categorize/config.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/config.ts)
- [packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts)
- [packages/toolkit/scripts/issue-triage/src/categorize/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/types.ts)
- [packages/toolkit/scripts/issue-triage/src/reports/generator.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/generator.ts)
- [packages/toolkit/scripts/issue-triage/src/reports/utils.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/utils.ts)
- [packages/toolkit/scripts/issue-triage/src/github/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/github/types.ts)
- [packages/toolkit/scripts/issue-triage/src/utils/errors.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/utils/errors.ts)
- [packages/rtk-query-codegen-openapi/src/index.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/index.ts)
- [website/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/website/README.md)
- [examples/publish-ci/cra4/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra4/README.md)
- [examples/publish-ci/cra5/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra5/README.md)
</details>

# Overview & Architecture

Redux Toolkit (RTK) is the official, opinionated, batteries-included toolset for Redux. It provides a thin layer of abstractions and utilities that codify the recommended patterns for store setup, reducer authoring, immutable updates, and data fetching. The monorepo publishes multiple packages that share a common development workflow, documentation site, and release pipeline.

## 1. Package Layout and Distribution

The `@reduxjs/toolkit` package is the primary deliverable. Its `package.json` lists `dist/`, `src/`, and three sub-path entry folders — `query`, `react`, and `skills` — as published files, while excluding tests and build artifacts. Source: [packages/toolkit/package.json:18-31]().

The runtime dependencies are intentionally small and well-known:

| Dependency | Role |
| --- | --- |
| `immer` | Powers "mutative" immutable reducer logic |
| `redux` | Core store and reducer implementation |
| `redux-thunk` | Default thunk middleware |
| `reselect` | Memoized selector primitives |
| `@standard-schema/spec`, `@standard-schema/utils` | Schema validation interop |

Source: [packages/toolkit/package.json:32-39](). The package's `sideEffects: false` flag enables aggressive tree-shaking, and `react` / `react-redux` are listed as optional `peerDependencies` so that the core can be consumed outside React. Source: [packages/toolkit/package.json:40-48]().

The repository is structured as a Yarn workspaces monorepo that also ships:

- `packages/rtk-query-codegen-openapi` — a generator that produces RTK Query API slices from an OpenAPI schema, exposed via `generateEndpoints`. Source: [packages/rtk-query-codegen-openapi/src/index.ts:11-30]().
- `packages/toolkit/scripts/issue-triage` — an internal TypeScript tool that fetches, categorizes, and reports on GitHub issues, executed via `bun src/index.ts` or `npm start`. Source: [packages/toolkit/scripts/issue-triage/package.json:5-10]().
- `examples/publish-ci/cra4` and `examples/publish-ci/cra5` — Create React App templates bootstrapped with the Redux + Redux Toolkit TS template that double as publish/CI smoke tests. Source: [examples/publish-ci/cra4/README.md:1-4](), [examples/publish-ci/cra5/README.md:1-4]().
- `website/` — the Docusaurus 2-based documentation site, started locally with `yarn start` and deployed with `yarn deploy` to the `gh-pages` branch. Source: [website/README.md:4-22]().

## 2. Core Architectural Pillars

The issue-triage categorizer explicitly enumerates the architectural surface area of the core package, which doubles as a reliable map of the public API. The `core` category, with weight 1.3, contains the following subcategories and their matching patterns: Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:69-128]().

| Subcategory | Keywords / Patterns Tracked |
| --- | --- |
| `createSlice` | `createSlice`, `extraReducers` |
| `configureStore` | `configureStore`, store setup |
| `createAsyncThunk` | `createAsyncThunk`, thunks, `.pending`, `.fulfilled` |
| `middleware` | middleware, listener middleware |
| `devtools` | Redux DevTools, time travel |
| `immer` | Immer integration, `draft`, `produce` |

These six pillars map directly onto the published sub-paths. The `query` sub-path exposes `createApi` and the data-fetching pipeline, while the `react` sub-path exposes the generated React hooks and the `<Provider>` glue. Source: [packages/toolkit/package.json:25-27]().

The triage tool itself reflects the layered design of the codebase. It uses a multi-tier categorization strategy: label-based matching is the most confident signal (95% confidence), followed by weighted keyword matching across categories, and finally pattern matching against the issue body. Source: [packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts:1-99](). This mirrors how RTK itself layers abstractions — a high-level ergonomic API on top of lower-level primitives that remain accessible.

## 3. Data Flow and Issue Lifecycle

Internally, the project tracks community issues through a small, well-typed pipeline. `CategorizedIssue` carries the GitHub metadata plus a `Categorization` block (primary, secondary, type, confidence, method), `Scores` (urgency, complexity, engagement), and `Flags` (isUrgent, isEasyFix, needsTriage, isStale, hasBreakingChange, needsRepro). Source: [packages/toolkit/scripts/issue-triage/src/categorize/types.ts:1-58]().

The GitHub layer is similarly typed. `GhIssueResponse` and `GhPullRequestResponse` represent the raw `gh` CLI payloads, while `SimplifiedComment` is the cached, trimmed form written to disk to avoid hitting rate limits. Source: [packages/toolkit/scripts/issue-triage/src/github/types.ts:1-86](). The end-to-end flow is:

```mermaid
flowchart LR
  A[GitHub API / gh CLI] --> B[Fetch issues & PRs]
  B --> C[Simplify & cache to JSON]
  C --> D[Categorize: labels → keywords → patterns]
  D --> E[Score urgency, complexity, engagement]
  E --> F[Apply flags: urgent, easy-fix, stale, …]
  F --> G[Group, cluster, dedupe]
  G --> H[Generate markdown reports]
```

Source: [packages/toolkit/scripts/issue-triage/src/reports/generator.ts:1-58](), [packages/toolkit/scripts/issue-triage/src/reports/utils.ts:1-30](). Custom error classes (`GitHubError`, `GhCliError`, `GhApiError`, `GhParseError`) preserve cause chains and stack traces, and are raised from the GitHub layer when the CLI is missing, the network fails, or JSON parsing fails. Source: [packages/toolkit/scripts/issue-triage/src/utils/errors.ts:1-41]().

## 4. Community-Driven Architectural Concerns

The categorization taxonomy is also a snapshot of the topics the community actually engages with, which is useful for understanding where the architecture is being stretched. The high-engagement discussions that map onto the tracked categories include:

- **Middleware / `createAsyncThunk`** — TypeScript errors with computed action names inside `extraReducers` (e.g. `affectedCases/update` as a thunk prefix) are a recurring source of friction. The triage tool explicitly keys on `extraReducers` and `createAsyncThunk` to surface these. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:78-93](), referencing community issue #478.
- **RTK Query (`query` sub-path)** — Generated React hooks sometimes require an `arg` parameter that the generated TypeScript declarations make non-optional, leading to `Expected 1-2 arguments, but got 0` errors. The `typescript` category (weight 1.2) groups these reports. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:131-141](), referencing community issue #1676.
- **API ergonomics** — Requests to combine multiple actions inside a single `.addCase` mirror the `combineActions` helper from `redux-actions`. The `architecture` and `core/middleware` categories are where these discussions surface. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:165-178](), referencing community issue #429.
- **Suspense in RTK Query** — A long-standing feature request for React Suspense integration is tracked under `core` with the `query` keywords. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:69-128](), referencing community issue #1574.
- **RTK 2.x planning** — Migration and future-planning categories (weights 1.4 and 1.2) are used to triage the discussions that culminated in the v2.0.0 release and the most recent v2.12.0 feature drop, which adds RTK skills files and exports RTK Query hook option types. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts:179-208]().

Taken together, the codebase is organized around a small set of opinionated APIs (`createSlice`, `configureStore`, `createAsyncThunk`, listener middleware, Immer, and the RTK Query pipeline), exposed through tree-shakable sub-paths, documented on a Docusaurus site, and supported by a typed internal tooling layer that mirrors the same architectural shape.

## See Also

- `createSlice` and `createAsyncThunk` API reference
- `configureStore` and middleware composition
- RTK Query `createApi` and React hooks
- OpenAPI codegen (`rtk-query-codegen-openapi`)
- Issue triage reports (auto-generated under `scripts/issue-triage/reports/`)

---

<a id='page-2'></a>

## Core Store & State Management APIs

### Related Pages

Related topics: [Overview & Architecture](#page-1), [RTK Query: Server Data, Hooks & Code Generation](#page-3), [Advanced Patterns, Extensibility & Tooling](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [packages/toolkit/src/configureStore.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/configureStore.ts)
- [packages/toolkit/src/getDefaultMiddleware.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/getDefaultMiddleware.ts)
- [packages/toolkit/src/createSlice.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createSlice.ts)
- [packages/toolkit/src/createReducer.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createReducer.ts)
- [packages/toolkit/src/createAction.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createAction.ts)
- [packages/toolkit/src/createAsyncThunk.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createAsyncThunk.ts)
- [packages/toolkit/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/package.json)
</details>

# Core Store & State Management APIs

## Overview and Purpose

Redux Toolkit (RTK) is the official, opinionated, batteries-included toolset for efficient Redux development. The **Core Store & State Management APIs** are the package's foundational surface — they wrap vanilla Redux primitives (store creation, reducers, actions, middleware) to remove the boilerplate that originally made Redux verbose.

The runtime dependencies tell the story of the design goals: `immer` for ergonomic mutable-looking updates, `redux` for the core store, `redux-thunk` for async dispatch, `reselect` for memoized selectors, and `@standard-schema/spec` for runtime validation hooks. Source: [packages/toolkit/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/package.json)

The five exports a developer touches first are:

| API | Role |
| --- | --- |
| `configureStore` | Create a Redux store with sane defaults and DevTools |
| `getDefaultMiddleware` | The opinionated middleware chain (thunk, serializable, immutable) |
| `createSlice` | Generate actions + reducer for a feature slice of state |
| `createAsyncThunk` | Define an async action with `pending` / `fulfilled` / `rejected` lifecycle |
| `createAction` / `createReducer` | Lower-level building blocks used internally and in advanced cases |

These surface names are also recognized as first-class categories by the project's own internal issue-triage heuristics — confirming their centrality to the project. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/config.ts)

## Store Assembly: `configureStore` and `getDefaultMiddleware`

`configureStore` is the recommended way to instantiate a store. It accepts a `reducer` map, optional `middleware`, `devTools`, `preloadedState`, and `enhancers`, and returns a fully configured `EnhancedStore`. Internally it calls `getDefaultMiddleware` and composes the final middleware chain using `applyMiddleware`. Source: [packages/toolkit/src/configureStore.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/configureStore.ts)

`getDefaultMiddleware` returns the default chain. The default chain is intentionally opinionated to surface common mistakes during development:

- **Redux Thunk** — included for async dispatch (also a top-level dependency).
- **Serializable State Check** — warns when a non-serializable value enters state or an action payload.
- **Immutability Check** — uses `immer`'s draft tracking to detect accidental mutation outside reducers.

Both checks are dev-only and stripped in production. To customize, you can spread the default array and append/remove items, e.g. `getDefaultMiddleware({ serializableCheck: false }).concat(logger)`. Source: [packages/toolkit/src/getDefaultMiddleware.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/getDefaultMiddleware.ts)

```ts
import { configureStore } from '@reduxjs/toolkit'
import todosReducer from './features/todos/todosSlice'

export const store = configureStore({
  reducer: {
    todos: todosReducer,
  },
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
```

A common gotcha: dispatching a thunk from inside a non-component scope (e.g. a plain `.ts` file) requires importing the typed `AppDispatch`. A bare `useDispatch` returns the unthunked `Dispatch<UnknownAction>`, so prefer a pre-typed `useAppDispatch` hook.

## Slices, Reducers, and Actions: `createSlice`

`createSlice` is the highest-level authoring API. You provide a `name`, an `initialState`, and an object of `reducers`. RTK uses `createAction` and `createReducer` under the hood to generate a `case reducer` per key, attach a string-typed action creator, and wrap the state transition in `immer.produce` so you can write mutating code that becomes immutable updates. Source: [packages/toolkit/src/createSlice.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createSlice.ts)

```ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment(state) { state.value += 1 },
    addBy(state, action: PayloadAction<number>) {
      state.value += action.payload
    },
  },
})
```

The `extraReducers` field is how slices respond to actions defined elsewhere — most commonly the `pending` / `fulfilled` / `rejected` actions emitted by `createAsyncThunk`. It accepts either a builder callback (`(builder) => builder.addCase(...)`) or an object map. Source: [packages/toolkit/src/createSlice.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createSlice.ts)

```mermaid
flowchart LR
  UI[Component] -->|dispatch| Thunk[createAsyncThunk]
  Thunk -->|pending| Slice[createSlice extraReducers]
  Thunk -->|fulfilled| Slice
  Thunk -->|rejected| Slice
  Slice -->|Immer draft| Store[configureStore]
  Store -->|subscribe| UI
```

A long-standing TypeScript pain point is using a **computed property name** inside `extraReducers`. Community discussion #478 reports the error *"A computed property name must be of type 'string', 'number', 'symbol', or 'any'"* when the thunk's string literal (e.g. `updateAffectedCase.fulfilled.type`) is not statically recognizable. The recommended fix is the builder-callback form, which gives the type system a clear place to infer the action signature. Source: [Community issue #478](https://github.com/reduxjs/redux-toolkit/issues/478)

A second common request is being able to reduce on **multiple action types with one handler** — a `combineActions`-style helper. As of the v2.12.0 release the builder API still expects one `addCase` per type, so the common workaround is to repeat the handler in a small local function. Source: [Community issue #429](https://github.com/reduxjs/redux-toolkit/issues/429)

## Async Logic: `createAsyncThunk`

`createAsyncThunk` accepts a string action-type prefix and a payload-creating async function, and returns a thunk action creator that automatically dispatches:

- `<type>/pending` with `{ arg, requestId }`
- `<type>/fulfilled` with `{ arg, payload, requestId, meta }` on resolve
- `<type>/rejected` with `{ arg, payload, requestId, error, meta }` on throw

The payload creator receives a `ThunkAPI` object exposing `{ dispatch, getState, extra, requestId, signal, rejectWithValue, fulfillWithValue }`. The `condition` option lets you skip dispatch (useful for caching) and `idGenerator` / `dispatchConditionRejection` provide further control. Source: [packages/toolkit/src/createAsyncThunk.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createAsyncThunk.ts)

```ts
export const fetchUser = createAsyncThunk(
  'users/fetchById',
  async (id: string, { rejectWithValue }) => {
    const res = await fetch(`/api/users/${id}`)
    if (!res.ok) return rejectWithValue(res.status)
    return res.json()
  },
)
```

## Lower-Level Building Blocks

`createAction(type, prepare?)` produces a typed action creator and a matching reducer case-reducer (via `prepare` for non-trivial payloads like `{ payload, meta, error }` triples). `createReducer` accepts an object of case reducers (or a builder callback) and wraps the result in `immer.produce` — this is what gives `createSlice` its mutating ergonomics. Source: [packages/toolkit/src/createAction.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createAction.ts), [packages/toolkit/src/createReducer.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/createReducer.ts)

You generally reach for these directly only when authoring a reusable library on top of RTK, when you need to support non-`createSlice` reducers, or when integrating with existing vanilla Redux code.

## See Also

- RTK Query — the data-fetching layer that consumes `createAsyncThunk` patterns and replaces much of the manual thunk boilerplate. See issue #1574 for the discussion of Suspense integration.
- React-Redux integration (`useSelector`, `useDispatch`, `Provider`) — the binding layer, declared as a peer dependency in [packages/toolkit/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/package.json).
- Migration guides for moving from Redux + manual reducers to RTK (referenced in the issue-triage configuration under the `migration` category).

---

<a id='page-3'></a>

## RTK Query: Server Data, Hooks & Code Generation

### Related Pages

Related topics: [Overview & Architecture](#page-1), [Core Store & State Management APIs](#page-2), [Advanced Patterns, Extensibility & Tooling](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [packages/toolkit/src/query/createApi.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/createApi.ts)
- [packages/toolkit/src/query/fetchBaseQuery.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/fetchBaseQuery.ts)
- [packages/toolkit/src/query/core/buildInitiate.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildInitiate.ts)
- [packages/toolkit/src/query/core/buildThunks.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildThunks.ts)
- [packages/toolkit/src/query/core/buildSelectors.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildSelectors.ts)
- [packages/toolkit/src/query/core/buildSlice.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildSlice.ts)
- [packages/toolkit/src/query/utils/getOrInsert.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/utils/getOrInsert.ts)
- [packages/rtk-query-codegen-openapi/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/README.md)
- [packages/rtk-query-codegen-openapi/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/package.json)
- [examples/query/react/infinite-queries/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/query/react/infinite-queries/README.md)
</details>

# RTK Query: Server Data, Hooks & Code Generation

## Overview and Purpose

RTK Query is the data-fetching and server-state management layer bundled inside Redux Toolkit. It is a small, opinionated data fetching and caching solution designed to simplify common cases for loading data in a web application. It is built on top of Redux, so it inherits immutability, predictable state updates, and a familiar single-store architecture, while remaining a self-contained API.

The module is composed of three cooperating pieces:

- A **core runtime** in `packages/toolkit/src/query/` that defines endpoints, thunks, reducers, selectors, and React hooks.
- A **code generator** distributed as `@rtk-query/codegen-openapi` that produces typed API slices from an OpenAPI schema.
- A **React integration** that auto-generates hooks (`useQuery`, `useLazyQuery`, `useMutation`, `useInfiniteQuery`, etc.) from endpoint definitions.

The package is published as part of `@reduxjs/toolkit`, while the code generator ships as a separate package and a CLI binary, as defined in [packages/rtk-query-codegen-openapi/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/package.json).

## Core Architecture

The runtime is centered on a single `createApi` call. Internally, the factory wires together several smaller builders, each responsible for a slice of behavior.

```mermaid
flowchart TD
    A[createApi] --> B[buildSlice<br/>reducer + actions]
    A --> C[buildThunks<br/>query/mutation actions]
    A --> D[buildInitiate<br/>dispatch thunks]
    A --> E[buildSelectors<br/>memoized state reads]
    A --> F[buildHooks<br/>React layer]
    A --> G[fetchBaseQuery<br/>HTTP transport]
    C --> H[Middleware<br/>api.middleware]
    H --> I[Redux Store]
    E --> I
    B --> I
    F --> C
    F --> E
    J[OpenAPI Schema] --> K[codegen-openapi CLI]
    K --> A
```

Key responsibilities:

- `createApi` returns an `api` object containing `reducer`, `middleware`, `endpoints`, and the React hooks. Source: [packages/toolkit/src/query/createApi.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/createApi.ts).
- `buildSlice` constructs the reducer path and action creators that track per-endpoint request status. Source: [packages/toolkit/src/query/core/buildSlice.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildSlice.ts).
- `buildThunks` defines the async thunk action creators (one per endpoint) that the hooks ultimately call. Source: [packages/toolkit/src/query/core/buildThunks.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildThunks.ts).
- `buildInitiate` exposes thunks that components dispatch, returning a subscription object with `.unwrap()`, `refetch`, and unsubscribe methods. Source: [packages/toolkit/src/query/core/buildInitiate.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildInitiate.ts).
- `buildSelectors` produces memoized selectors for request state, typically accessed by `state.api.endpoints[endpointName]`. Source: [packages/toolkit/src/query/core/buildSelectors.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/src/query/core/buildSelectors.ts).

## React Hooks and Component Usage

When `createApi` is called inside a React app, it auto-generates hooks for every defined endpoint. The hook types are:

| Hook | Purpose |
|------|---------|
| `useQuery` | Read data and subscribe to refetch / cache invalidation. |
| `useLazyQuery` | Trigger a query imperatively (e.g., on click). |
| `useMutation` | Send a write request and receive a `trigger` function. |
| `useInfiniteQuery` | Paginated or cursor-based reads; supports `initialPage`, `maxPages`, bidirectional cursors, and `FlatList` integration for React Native. See [examples/query/react/infinite-queries/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/query/react/infinite-queries/README.md). |

Each hook returns an object shaped like `{ data, error, isLoading, isFetching, isSuccess, refetch, ... }`. Mutations additionally expose `[trigger, result]`. This contract is what users encounter in real code, and is the source of one of the most common TypeScript pitfalls — a hook for an endpoint that *requires* an argument will produce a type that requires that argument, otherwise it is optional. This explains the community issue #1676, where users see "Expected 1-2 arguments, but got 0" because the generated hook type correctly reflects that the endpoint takes an `arg`.

## Code Generation

For projects that maintain an OpenAPI/Swagger schema, RTK Query provides a code generator that emits a fully-typed `createApi` block. It is documented in [packages/rtk-query-codegen-openapi/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/README.md) and is run via the CLI `rtk-query-codegen-openapi` (exposed by the `"bin"` field in its `package.json`).

```bash
npx rtk-query-codegen-openapi ./openapi.yaml \
  --outputFile ./src/store/api.generated.ts \
  --modulePath 'store/emptyApi' \
  --apiFile 'store/emptyApi.ts'
```

The generator reads an OpenAPI document and produces endpoint definitions with inferred request and response types, removing most of the manual typing burden. According to the issue-triage category config in [packages/toolkit/scripts/issue-triage/src/categorize/config.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/config.ts), codegen-related issues form one of the highest-weighted categories for the maintainers, reflecting the volume of questions about type generation, parameter handling, and OpenAPI features.

## Common Failure Modes and Caveats

- **Hook argument errors.** A hook's `arg` parameter is *required* if the endpoint's `query` callback depends on it; TypeScript will refuse to call the hook with no argument. The fix is to either pass `undefined` explicitly, mark the parameter optional in the endpoint, or wrap the call in a guard.
- **Mutating the cached response.** Because RTK Query keeps results in the Redux store, returning a non-serializable value from `transformResponse` will trip DevTools. Use a small pure mapper or `createEntityAdapter` for collections.
- **Cache invalidation behavior.** Tags configured on a `query` endpoint are not invalidated by mutations of a different endpoint. The `invalidatesTags` array on the mutation must list the tags for the queries you want to refetch.
- **Infinite query status flags.** The v2.12.0 release notes call out fixes for infinite-query status flags and batching; older code that relied on `isFetching` semantics for infinite queries may need updates after upgrading.
- **Suspense.** First-class Suspense support for RTK Query has been a long-standing community request (issue #1574). As of the v2.12.0 release there is no built-in `useSuspenseQuery`; users currently need to handle loading fallbacks explicitly via `isLoading` / `isFetching`.

## See Also

- RTK Core: `createSlice`, `configureStore`, `createAsyncThunk`
- Listener Middleware for side effects
- React Native integration examples (infinite queries, optimistic updates)
- OpenAPI code generation documentation at `redux-toolkit.js.org/rtk-query/usage/code-generation`

---

<a id='page-4'></a>

## Advanced Patterns, Extensibility & Tooling

### Related Pages

Related topics: [Overview & Architecture](#page-1), [Core Store & State Management APIs](#page-2), [RTK Query: Server Data, Hooks & Code Generation](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [packages/toolkit/scripts/issue-triage/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/README.md)
- [packages/toolkit/scripts/issue-triage/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/package.json)
- [packages/toolkit/scripts/issue-triage/src/categorize/config.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/config.ts)
- [packages/toolkit/scripts/issue-triage/src/categorize/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/types.ts)
- [packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts)
- [packages/toolkit/scripts/issue-triage/src/github/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/github/types.ts)
- [packages/toolkit/scripts/issue-triage/src/utils/errors.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/utils/errors.ts)
- [packages/toolkit/scripts/issue-triage/src/reports/generator.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/generator.ts)
- [packages/toolkit/scripts/issue-triage/src/reports/utils.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/utils.ts)
- [packages/rtk-query-codegen-openapi/src/index.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/index.ts)
- [packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts)
- [website/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/website/README.md)
- [examples/publish-ci/cra4/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra4/README.md)
- [examples/publish-ci/cra5/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra5/README.md)
</details>

# Advanced Patterns, Extensibility & Tooling

Redux Toolkit is not only a runtime library — it ships an ecosystem of **extensibility points, code-generation tools, and project-maintenance utilities** that sit around the core packages. This page documents the tooling that extends RTK's reach beyond the reducers, slices, and queries covered in the user-facing guides: the **OpenAPI codegen package**, the **GitHub issue triage tool**, the **Docusaurus documentation site**, and the **published CI example templates**.

These tools exist to solve concrete community pain points: removing the boilerplate of writing typed API slices by hand, keeping a high-volume issue tracker organized, and providing copy-paste-ready starters for the most common bundler frameworks.

## OpenAPI Codegen: Type-Safe API Scaffolding

The `rtk-query-codegen-openapi` package reads an OpenAPI/ Swagger schema and produces a fully-typed RTK Query `createApi` definition, including endpoint definitions and React hook bindings. It is the primary **extensibility surface** for projects that need to consume a large REST surface without manually maintaining endpoint metadata.

The entry point is the `generateEndpoints` function. It accepts a `schemaFile` (either a local path or a remote URL) plus generation options, normalizes the schema path, and dispatches to an internal generator:

```ts
export async function generateEndpoints(options: GenerationOptions): Promise<string | void> {
  const schemaLocation = options.schemaFile;
  const schemaAbsPath = isValidUrl(options.schemaFile)
    ? options.schemaFile
    : path.resolve(process.cwd(), schemaLocation);
  // ...
  if (outputFile) {
    fs.writeFileSync(
      path.resolve(process.cwd(), outputFile),
      await prettify(outputFile, sourceCode, prettierConfigFile)
    );
  } else {
    return await prettify(null, sourceCode, prettierConfigConfig);
  }
}
```

Source: [packages/rtk-query-codegen-openapi/src/index.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/index.ts)

The function has two overloads: when `outputFile` is omitted it returns the generated source as a string (useful for in-memory pipelines), and when `outputFile` is supplied it writes the prettified source to disk. A separate `parseConfig` helper reads a multi-file configuration and expands it into a list of `CommonOptions & OutputFileOptions` entries. Source: [packages/rtk-query-codegen-openapi/src/index.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/index.ts)

The React-hook generator emits a single `export` statement whose binding pattern contains one identifier per generated hook. It is constructed with the TypeScript factory API:

```ts
factory.createObjectBindingPattern(
  operationDefinitions
    .map((op) => getReactHookName({ operationDefinition: op, endpointOverrides, config, operationNameSuffix }))
    .flat()
)
```

Source: [packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts)

### Community relevance

Community issue **#1676** ("RTK query - generated Hooks asking for 1 - 2 arguments in typescript") directly addresses the typed-binding output produced by this generator. The `.flat()` call on the mapped hook names reflects the fact that a single OpenAPI operation can produce more than one React hook (e.g. `useGetXQuery` *and* `useLazyGetXQuery`), each of which must appear in the export binding. Source: [packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/rtk-query-codegen-openapi/src/generators/react-hooks.ts)

## Issue Triage: Community Maintenance Tooling

The repository bundles a TypeScript-based **GitHub Issues triage tool** under `packages/toolkit/scripts/issue-triage`. It fetches open issues, scores and categorizes them, and emits Markdown reports — letting maintainers triage a large backlog without manual inspection. Source: [packages/toolkit/scripts/issue-triage/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/README.md)

### Runtime and configuration

The tool is an ES-module TypeScript project and supports both **Node.js 18+** and **Bun 1.0+** runtimes. The `package.json` declares `"type": "module"` and a `start` script that runs directly under Bun:

```json
{
  "name": "github-issues-triage",
  "type": "module",
  "scripts": {
    "start": "bun src/index.ts",
    "build": "tsc"
  }
}
```

Source: [packages/toolkit/scripts/issue-triage/package.json](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/package.json)

It supports a `--use-cache` flag that reads from `cache/issues-data.json` rather than re-querying the GitHub API, which is useful for development and for respecting rate limits. Source: [packages/toolkit/scripts/issue-triage/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/README.md)

### Categorization model

Categorization is **multi-tiered**: the tool first attempts a high-confidence label match, then falls back to keyword and pattern scoring over the issue title and body. The tiered approach is encoded directly in `categorizeIssue`:

```ts
// Tier 1: Label-based (highest confidence - 95%)
const labelResult = checkLabels(issue)
if (labelResult) return labelResult
// Tier 2: Keyword matching with context-aware scoring
const scores = calculateKeywordScores(issue)
```

Source: [packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/categorizer.ts)

Categories are defined declaratively in `config.ts` with weighted keywords, regex patterns, and optional subcategories. Examples include `core` (covering `createSlice`, `configureStore`, `createAsyncThunk`, middleware, Immer, DevTools) with subcategories that mirror the public API surface, and `future-planning` (roadmap, RFC, v2/v3). Each entry has a `weight` multiplier that influences the final score. Source: [packages/toolkit/scripts/issue-triage/src/categorize/config.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/config.ts)

The data model is captured in a small set of TypeScript interfaces:

| Type | Purpose |
|------|---------|
| `Categorization` | Primary/secondary category, type, confidence, method |
| `Scores` | Urgency, complexity, engagement (0-100) |
| `Flags` | `isUrgent`, `isEasyFix`, `needsTriage`, `isStale`, `hasBreakingChange`, `needsRepro` |
| `CategorizedIssue` | Aggregated issue record combining GitHub data + scoring |

Source: [packages/toolkit/scripts/issue-triage/src/categorize/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/categorize/types.ts)

### Report generation

The report generator composes Markdown sections — quick wins, urgent bugs, easy fixes, needs-attention, duplicates, work clusters, and a per-category breakdown — and sorts categories by issue count so the busiest topics surface first. Source: [packages/toolkit/scripts/issue-triage/src/reports/generator.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/generator.ts) Utility helpers such as `formatIssueLink`, `formatRelativeDate`, and `formatScoreBar` produce the visual primitives used throughout the report. Source: [packages/toolkit/scripts/issue-triage/src/reports/utils.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/reports/utils.ts)

A dedicated error hierarchy (`GitHubError` → `GhCliError`, `GhApiError`, `GhParseError`) carries the original `cause` so failures from the `gh` CLI or network can be distinguished programmatically. Source: [packages/toolkit/scripts/issue-triage/src/utils/errors.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/utils/errors.ts) GitHub payloads are typed by `GhIssueResponse`, `GhPullRequestResponse`, and `GhComment` so the rest of the toolchain can be type-safe. Source: [packages/toolkit/scripts/issue-triage/src/github/types.ts](https://github.com/reduxjs/redux-toolkit/blob/main/packages/toolkit/scripts/issue-triage/src/github/types.ts)

```mermaid
flowchart LR
  A[gh CLI] --> B[Fetch Issues + PRs]
  B --> C{Cache?}
  C -- hit --> D[cache/issues-data.json]
  C -- miss --> E[GitHub API]
  D --> F[Categorize]
  E --> F
  F --> G[Score + Flag]
  G --> H[Report Generator]
  H --> I[reports/*.md]
```

## Documentation Site & Template Starters

### Docusaurus website

User-facing documentation is a Docusaurus 2 site under `website/`. Local development uses `yarn start` for a hot-reloading dev server, `yarn build` produces static output in the `build/` directory, and `yarn deploy` publishes to the `gh-pages` branch via SSH. Source: [website/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/website/README.md)

### Publish-CI templates

The `examples/publish-ci/` directory ships two **Create React App** templates (CRA 4 and CRA 5) pre-wired with Redux and Redux Toolkit's TypeScript template. They expose the standard CRA scripts (`npm start`, `npm test`, `npm build`, and the one-way `npm run eject`) and serve as reproducible baselines for verifying the publish/CI pipeline. Source: [examples/publish-ci/cra4/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra4/README.md), Source: [examples/publish-ci/cra5/README.md](https://github.com/reduxjs/redux-toolkit/blob/main/examples/publish-ci/cra5/README.md)

## Putting It Together: An Advanced Workflow

A team adopting RTK at scale typically layers these tools as follows:

1. **Bootstrap** a new app from the `cra5` (or equivalent) template, or scaffold one from a custom Vite/Next config.
2. **Generate** the API slice via `generateEndpoints` against the backend's OpenAPI schema, eliminating hand-written endpoint metadata.
3. **Extend** the generated slice with `createListenerMiddleware` for side-effects, `extraReducers` for cross-slice reactions, and the `addMatcher` API for ergonomic action routing (the latter being the long-standing request tracked in community issue **#429**).
4. **Operate** the project with the issue-triage tool to keep community reports categorized and prioritized as the package evolves toward future major versions (community issue **#958**).

## See Also

- [Core API: `createSlice`, `configureStore`, `createAsyncThunk`](https://redux-toolkit.js.org/api/configureStore)
- [RTK Query: `createApi` and generated hooks](https://redux-toolkit.js.org/rtk-query/api/createApi)
- [Listener Middleware](https://redux-toolkit.js.org/api/createListenerMiddleware)
- [OpenAPI Codegen on npm](https://www.npmjs.com/package/@rtk-query/codegen-openapi)

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: reduxjs/redux-toolkit

Summary: Found 13 structured pitfall item(s), including 1 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: high
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5191

## 2. Identity risk - Identity risk requires verification

- Severity: medium
- Evidence strength: runtime_trace
- Finding: Project evidence flags a identity risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Repro command: `npm install @reduxjs/toolkit`
- Evidence: identity.distribution | https://www.npmjs.com/package/@reduxjs/toolkit

## 3. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5196

## 4. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5313

## 5. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5316

## 6. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://www.npmjs.com/package/@reduxjs/toolkit

## 7. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5225

## 8. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: community_evidence:github | https://github.com/reduxjs/redux-toolkit/issues/5292

## 9. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/@reduxjs/toolkit

## 10. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://www.npmjs.com/package/@reduxjs/toolkit

## 11. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://www.npmjs.com/package/@reduxjs/toolkit

## 12. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/@reduxjs/toolkit

## 13. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://www.npmjs.com/package/@reduxjs/toolkit

<!-- canonical_name: reduxjs/redux-toolkit; human_manual_source: deepwiki_human_wiki -->
