library/specializations/web-development/skills/redux-toolkit/SKILL.md
Redux Toolkit patterns including slice creation, async thunks, RTK Query, state normalization, and DevTools integration.
npx skillsauth add a5c-ai/babysitter redux-toolkitInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert assistance for implementing Redux Toolkit in React applications with modern patterns and best practices.
Invoke this skill when you need to:
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | featureName | string | Yes | Name of the feature/slice | | stateShape | object | Yes | Initial state structure | | asyncActions | array | No | Async thunks to create | | useRTKQuery | boolean | No | Whether to use RTK Query | | entityAdapter | boolean | No | Use entity adapter for normalization |
{
"featureName": "users",
"stateShape": {
"items": [],
"selectedId": null,
"status": "idle",
"error": null
},
"asyncActions": ["fetchUsers", "createUser", "updateUser"],
"useRTKQuery": false,
"entityAdapter": true
}
import { createSlice, createEntityAdapter, PayloadAction } from '@reduxjs/toolkit';
import type { RootState } from '../../app/store';
interface User {
id: string;
name: string;
email: string;
}
const usersAdapter = createEntityAdapter<User>({
selectId: (user) => user.id,
sortComparer: (a, b) => a.name.localeCompare(b.name),
});
interface UsersState extends ReturnType<typeof usersAdapter.getInitialState> {
status: 'idle' | 'loading' | 'succeeded' | 'failed';
error: string | null;
}
const initialState: UsersState = usersAdapter.getInitialState({
status: 'idle',
error: null,
});
const usersSlice = createSlice({
name: 'users',
initialState,
reducers: {
userAdded: usersAdapter.addOne,
userUpdated: usersAdapter.updateOne,
userRemoved: usersAdapter.removeOne,
usersReceived: usersAdapter.setAll,
},
extraReducers: (builder) => {
builder
.addCase(fetchUsers.pending, (state) => {
state.status = 'loading';
})
.addCase(fetchUsers.fulfilled, (state, action) => {
state.status = 'succeeded';
usersAdapter.setAll(state, action.payload);
})
.addCase(fetchUsers.rejected, (state, action) => {
state.status = 'failed';
state.error = action.error.message ?? 'Failed to fetch users';
});
},
});
export const { userAdded, userUpdated, userRemoved, usersReceived } = usersSlice.actions;
export const {
selectAll: selectAllUsers,
selectById: selectUserById,
selectIds: selectUserIds,
} = usersAdapter.getSelectors<RootState>((state) => state.users);
export default usersSlice.reducer;
import { createAsyncThunk } from '@reduxjs/toolkit';
import { usersApi } from '../api/users.api';
export const fetchUsers = createAsyncThunk(
'users/fetchUsers',
async (_, { rejectWithValue }) => {
try {
const response = await usersApi.getAll();
return response.data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
export const createUser = createAsyncThunk(
'users/createUser',
async (userData: CreateUserDto, { rejectWithValue }) => {
try {
const response = await usersApi.create(userData);
return response.data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
interface User {
id: string;
name: string;
email: string;
}
export const usersApi = createApi({
reducerPath: 'usersApi',
baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
tagTypes: ['User'],
endpoints: (builder) => ({
getUsers: builder.query<User[], void>({
query: () => 'users',
providesTags: (result) =>
result
? [...result.map(({ id }) => ({ type: 'User' as const, id })), 'User']
: ['User'],
}),
getUserById: builder.query<User, string>({
query: (id) => `users/${id}`,
providesTags: (result, error, id) => [{ type: 'User', id }],
}),
createUser: builder.mutation<User, Partial<User>>({
query: (body) => ({
url: 'users',
method: 'POST',
body,
}),
invalidatesTags: ['User'],
}),
updateUser: builder.mutation<User, Partial<User> & Pick<User, 'id'>>({
query: ({ id, ...patch }) => ({
url: `users/${id}`,
method: 'PATCH',
body: patch,
}),
invalidatesTags: (result, error, { id }) => [{ type: 'User', id }],
}),
}),
});
export const {
useGetUsersQuery,
useGetUserByIdQuery,
useCreateUserMutation,
useUpdateUserMutation,
} = usersApi;
import { configureStore } from '@reduxjs/toolkit';
import { setupListeners } from '@reduxjs/toolkit/query';
import usersReducer from '../features/users/usersSlice';
import { usersApi } from '../features/users/usersApi';
export const store = configureStore({
reducer: {
users: usersReducer,
[usersApi.reducerPath]: usersApi.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(usersApi.middleware),
});
setupListeners(store.dispatch);
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
development
Model documentation skill for generating model cards following Google's model card framework.
development
MLflow integration skill for experiment tracking, model registry, and artifact management. Enables LLMs to log experiments, compare runs, manage model lifecycle, and retrieve artifacts through the MLflow API.
data-ai
LIME-based local explanation skill for individual predictions across tabular, text, and image data.
devops
Kubeflow Pipelines skill for ML workflow orchestration, component management, and Kubernetes-native ML.