The official, opinionated, batteries-included toolset for efficient Redux development
npx @tessl/cli install tessl/npm-reduxjs--toolkit@2.9.0Redux Toolkit (RTK) is the official, opinionated, batteries-included toolset for efficient Redux development. It provides powerful utilities to simplify store setup, action creation, immutable updates, and data fetching, all with full TypeScript support and developer experience optimizations.
npm install @reduxjs/toolkit react-reduximport { configureStore, createSlice, createAsyncThunk } from "@reduxjs/toolkit";Entry Points:
@reduxjs/toolkit - Core Redux Toolkit utilities@reduxjs/toolkit/react - React-specific enhancements@reduxjs/toolkit/query - RTK Query data fetching@reduxjs/toolkit/query/react - RTK Query React hooksFor CommonJS:
const { configureStore, createSlice, createAsyncThunk } = require("@reduxjs/toolkit");import { configureStore, createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
// Define state type
interface CounterState {
value: number;
status: 'idle' | 'loading';
}
// Create async thunk
const incrementAsync = createAsyncThunk(
'counter/incrementAsync',
async (amount: number) => {
await new Promise(resolve => setTimeout(resolve, 1000));
return amount;
}
);
// Create slice with actions and reducer
const counterSlice = createSlice({
name: 'counter',
initialState: { value: 0, status: 'idle' } as CounterState,
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload;
}
},
extraReducers: (builder) => {
builder
.addCase(incrementAsync.pending, (state) => {
state.status = 'loading';
})
.addCase(incrementAsync.fulfilled, (state, action) => {
state.status = 'idle';
state.value += action.payload;
});
}
});
// Configure store
const store = configureStore({
reducer: {
counter: counterSlice.reducer
}
});
// Export actions and store
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export { incrementAsync };
export default store;Redux Toolkit is built around several key concepts:
configureStore() provides sensible defaults for Redux store setup with automatic middleware configurationcreateSlice() generates action creators and reducers from a single configuration objectcreateAsyncThunk() handles async operations with automatic pending/fulfilled/rejected actionsSimplified store setup with automatic middleware configuration, Redux DevTools integration, and performance optimizations.
function configureStore<S = any, A extends Action = AnyAction, M extends Middlewares<S> = Middlewares<S>, E extends Enhancers = Enhancers>(
options: ConfigureStoreOptions<S, A, M, E>
): EnhancedStore<S, A, E>;
interface ConfigureStoreOptions<S, A, M, E, P = S> {
reducer: Reducer<S, A> | ReducersMapObject<S, A>;
middleware?: (getDefaultMiddleware: GetDefaultMiddleware<S>) => M;
devTools?: boolean | DevToolsOptions;
preloadedState?: P;
enhancers?: (getDefaultEnhancers: GetDefaultEnhancers<S>) => E;
}Type-safe action creators and reducers with automatic action type generation and Immer-powered immutable updates.
function createAction<P = void, T extends string = string>(
type: T,
prepareAction?: PrepareAction<P>
): PayloadActionCreator<P, T>;
function createSlice<
State,
CaseReducers extends SliceCaseReducers<State>,
Name extends string = string
>(options: CreateSliceOptions<State, CaseReducers, Name>): Slice<State, CaseReducers, Name>;
interface PayloadAction<P = void, T extends string = string, M = never, E = never> {
payload: P;
type: T;
meta?: M;
error?: E;
}Streamlined async logic handling with automatic loading states and error management.
function createAsyncThunk<
Returned,
ThunkArg = void,
ThunkApiConfig extends AsyncThunkConfig = {}
>(
typePrefix: string,
payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg, ThunkApiConfig>,
options?: AsyncThunkOptions<ThunkArg, ThunkApiConfig>
): AsyncThunk<Returned, ThunkArg, ThunkApiConfig>;
interface AsyncThunk<Returned, ThunkArg, ThunkApiConfig> {
pending: ActionCreatorWithPreparedPayload<[string, ThunkArg, AsyncThunkOptions<ThunkArg, ThunkApiConfig>?], undefined, string, never, {
arg: ThunkArg;
requestId: string;
requestStatus: "pending";
}>;
fulfilled: ActionCreatorWithPreparedPayload<[Returned, string, ThunkArg, AsyncThunkOptions<ThunkArg, ThunkApiConfig>?], Returned, string, never, {
arg: ThunkArg;
requestId: string;
requestStatus: "fulfilled";
}>;
rejected: ActionCreatorWithPreparedPayload<[unknown, string, ThunkArg, AsyncThunkOptions<ThunkArg, ThunkApiConfig>?, string?, SerializedError?], undefined, string, SerializedError, {
arg: ThunkArg;
requestId: string;
requestStatus: "rejected";
aborted?: boolean;
condition?: boolean;
}>;
}Normalized state management with prebuilt CRUD operations and selectors.
function createEntityAdapter<T, Id extends EntityId = EntityId>(
options?: {
selectId?: IdSelector<T, Id>;
sortComparer?: false | Comparer<T>;
}
): EntityAdapter<T, Id>;
interface EntityAdapter<T, Id extends EntityId> {
addOne<S extends EntityState<T, Id>>(state: S, entity: T): void;
addMany<S extends EntityState<T, Id>>(state: S, entities: readonly T[] | Record<Id, T>): void;
setOne<S extends EntityState<T, Id>>(state: S, entity: T): void;
setMany<S extends EntityState<T, Id>>(state: S, entities: readonly T[] | Record<Id, T>): void;
setAll<S extends EntityState<T, Id>>(state: S, entities: readonly T[] | Record<Id, T>): void;
removeOne<S extends EntityState<T, Id>>(state: S, key: Id): void;
removeMany<S extends EntityState<T, Id>>(state: S, keys: readonly Id[]): void;
removeAll<S extends EntityState<T, Id>>(state: S): void;
updateOne<S extends EntityState<T, Id>>(state: S, update: Update<T, Id>): void;
updateMany<S extends EntityState<T, Id>>(state: S, updates: ReadonlyArray<Update<T, Id>>): void;
upsertOne<S extends EntityState<T, Id>>(state: S, entity: T): void;
upsertMany<S extends EntityState<T, Id>>(state: S, entities: readonly T[] | Record<Id, T>): void;
getInitialState(): EntityState<T, Id>;
getInitialState<S extends Record<string, any>>(state: S): EntityState<T, Id> & S;
getSelectors(): EntitySelectors<T, EntityState<T, Id>, Id>;
getSelectors<V>(selectState: (state: V) => EntityState<T, Id>): EntitySelectors<T, V, Id>;
}Advanced middleware for side effects, dynamic middleware injection, and development-time invariants.
function createListenerMiddleware<
StateType = unknown,
DispatchType extends Dispatch = AppDispatch,
ExtraArgument = unknown
>(options?: CreateListenerMiddlewareOptions<ExtraArgument>): ListenerMiddlewareInstance<StateType, DispatchType, ExtraArgument>;
function createDynamicMiddleware<
State = any,
DispatchType extends Dispatch<AnyAction> = Dispatch<AnyAction>
>(): DynamicMiddlewareInstance<State, DispatchType>;Complete data fetching solution with automatic caching, background updates, and optimistic updates.
function createApi<
BaseQuery extends BaseQueryFn,
Definitions extends EndpointDefinitions,
ReducerPath extends string = 'api',
TagTypes extends string = never
>(options: CreateApiOptions<BaseQuery, Definitions, ReducerPath, TagTypes>): Api<BaseQuery, Definitions, ReducerPath, TagTypes>;
function fetchBaseQuery(
options?: FetchBaseQueryArgs
): BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError>;React hooks for data fetching, automatic re-rendering, and component lifecycle integration.
// Auto-generated hooks for each endpoint
type UseQueryHook = <T = QueryResult>(
arg: QueryArg,
options?: UseQueryOptions
) => UseQueryResult<T>;
type UseMutationHook = <T = MutationResult>() => [
(arg: MutationArg) => Promise<T>,
MutationResult
];
// Provider component
function ApiProvider<A extends Api<any, {}, any, any>>(props: {
api: A;
setupListeners?: boolean | ((dispatch: ThunkDispatch<any, any, any>) => () => void);
children: React.ReactNode;
}): JSX.Element;RTK Query React | React Integration
Helper functions for selectors, action matching, and development utilities.
function createSelector<InputSelectors extends readonly unknown[], Result>(
...args: [...inputSelectors: InputSelectors, resultFunc: (...args: SelectorResultArray<InputSelectors>) => Result]
): Selector<GetStateFromSelectors<InputSelectors>, Result>;
function isAllOf<A extends AnyAction>(
...matchers: readonly ActionMatcherOrType<A>[]
): ActionMatcher<A>;
function isAnyOf<A extends AnyAction>(
...matchers: readonly ActionMatcherOrType<A>[]
): ActionMatcher<A>;
function nanoid(size?: number): string;Redux Toolkit is written in TypeScript and provides excellent type safety out of the box:
import type { PayloadAction } from '@reduxjs/toolkit';
import type { RootState, AppDispatch } from './store';
// Type-safe useSelector and useDispatch
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;createSlice() for most reducers to automatically generate actions and handle immutable updatescreateAsyncThunk() for async logic over manual thunksconfigureStore())