Key Takeaways
At Boundev, we build React applications for enterprise clients where state management complexity scales with the product. Redux Toolkit with RTK Query is our default architecture for applications that need to manage both local UI state and server data at scale. It eliminates the boilerplate that made plain Redux painful while providing production-grade caching, cache invalidation, and TypeScript safety that alternatives do not match when integrated with an existing Redux store.
This guide covers Redux Toolkit and RTK Query from the architecture perspective — not the getting-started tutorial. We focus on the design decisions, patterns, and production considerations that determine whether your state management scales or becomes the bottleneck your team works around.
What Redux Toolkit Replaces
Redux Toolkit is not a different library — it is the same Redux with dramatically less code. Understanding what it eliminates makes clear why it is now the only recommended way to write Redux.
The Core APIs: createSlice vs createApi
The most important architecture decision in a Redux Toolkit application is understanding which API to use for which type of state. Using the wrong one creates unnecessary complexity that grows with every feature.
createSlice — Client State:
createApi (RTK Query) — Server State:
RTK Query: How It Works
RTK Query’s architecture centers on a single createApi call that defines all your endpoints, generates typed React hooks, manages caching automatically, and provides tag-based invalidation. Understanding this flow is essential for building API layers that scale.
Define Endpoints
- ●Call createApi once with a base URL and endpoint definitions
- ●Queries for data fetching, Mutations for data modification
- ●Add providesTags to queries and invalidatesTags to mutations
- ●TypeScript generics define request and response types per endpoint
Use Auto-Generated Hooks
- ●useGetXQuery hooks handle fetching, caching, loading, and error states
- ●useXMutation hooks return trigger functions with lifecycle tracking
- ●Duplicate requests automatically deduplicated — one network call shared
- ●Full TypeScript inference from endpoint definition to component usage
Cache Invalidation
- ●Mutations invalidate tags — associated queries automatically refetch
- ●Cache expires after 60s by default (keepUnusedDataFor configurable)
- ●Optimistic updates via onQueryStarted for instant UI feedback
- ●Polling support for real-time data with configurable intervals
Build Scalable React Applications With Confidence
Boundev’s software outsourcing teams architect React applications with Redux Toolkit and RTK Query from day one. TypeScript-first, cache-optimized, and built for production scale from the initial deployment.
Talk to Our React Engineering TeamProduction Architecture Patterns
Moving from a tutorial project to a production application with Redux Toolkit requires specific architecture decisions that tutorials skip. These five patterns address the most common scaling challenges.
1One createApi Per Base URL
Define a single createApi instance per backend service. If your app consumes three APIs, create three API slices. Each API slice manages its own cache, middleware, and tag invalidation independently. Never mix endpoints from different backends in one createApi — cache invalidation semantics break when tags span unrelated services.
2Code-Split API Endpoints
Use injectEndpoints to add endpoints to an existing API slice from feature modules. Define the createApi with an empty endpoints builder, then inject endpoints from each feature’s own file. This keeps API definitions colocated with the features that use them while maintaining a single cache and middleware instance.
3Typed Tag Constants
Define cache tag types as string union constants shared between queries and mutations. Typos in tag names fail silently — a mutation invalidating "User" while the query provides "Users" means no cache invalidation occurs and stale data appears. TypeScript enum or const assertions prevent this entirely.
4Optimistic Updates With Rollback
Use onQueryStarted with api.util.updateQueryData for instant UI feedback when mutations fire. Store the patchResult from updateQueryData and call patchResult.undo() in the catch block if the mutation fails. This pattern gives users immediate feedback while maintaining data consistency on server errors.
5Add the API Middleware
The middleware generated by createApi is not optional — it enables caching, cache invalidation, polling, and subscription lifecycle management. Forgetting to add it to configureStore is the most common reason RTK Query appears to "not work" in production. Always concat the API middleware to the default middleware.
Boundev Practice: Our staff augmentation React engineers enforce a strict client/server state boundary in every project. createSlice manages UI-only state, RTK Query owns all API data, and selectors bridge the two layers. This separation eliminates the "stale data" and "duplicate state" bugs that plague applications mixing server data into client state slices.
RTK Query vs React Query
Both RTK Query and React Query (TanStack Query) solve the same problem — managing server state with automatic caching. Choosing between them depends on your existing architecture and where you want your state to live.
Redux Toolkit Impact Metrics
Production improvements when migrating from plain Redux to Redux Toolkit with RTK Query.
FAQ
What is Redux Toolkit and why should I use it?
Redux Toolkit (RTK) is the official, recommended way to write Redux logic. It eliminates the boilerplate that made plain Redux painful: createSlice auto-generates action types and creators from reducer definitions, configureStore handles middleware and DevTools setup, and Immer allows direct state mutations that compile to immutable updates. RTK reduces Redux code by approximately 60% while adding TypeScript inference, better developer experience, and the ability to use RTK Query for server state management. Every new Redux project should use Redux Toolkit.
What is RTK Query and how does it work?
RTK Query is a data fetching and caching solution built into Redux Toolkit. You define API endpoints once using createApi with a base URL and endpoint builders (queries for reads, mutations for writes). RTK Query then auto-generates typed React hooks (useGetXQuery, useXMutation) that handle data fetching, loading states, error handling, caching, request deduplication, and cache invalidation. When multiple components use the same query hook, only one network request is made. Cache invalidation uses a tag system where mutations automatically trigger refetches of related queries.
How does RTK Query cache invalidation work?
RTK Query uses a tag-based cache invalidation system. Query endpoints declare which cache tags they provide using providesTags (e.g., a getPosts query provides tags of type "Post"). Mutation endpoints declare which tags they invalidate using invalidatesTags (e.g., an addPost mutation invalidates the "Post" tag). When a mutation executes successfully, RTK Query automatically refetches all queries that provide the invalidated tags, keeping the UI synchronized with server state. Tags can be specific to individual items using IDs, enabling granular cache updates without refetching entire lists.
Should I use RTK Query or React Query?
Use RTK Query if your project already uses Redux Toolkit or if you need server data accessible from Redux middleware and thunks. RTK Query stores data in the Redux store, making it visible in Redux DevTools and accessible throughout the Redux ecosystem. Use React Query (TanStack Query) if your project does not use Redux or if you prefer a standalone, lightweight data-fetching library. Both provide excellent TypeScript support, automatic caching, and optimistic updates. The key difference is integration: RTK Query provides unified state, React Query provides independent server state management.
When should I use createSlice vs RTK Query?
Use createSlice for client-only state that does not come from a server: UI toggles (modals, sidebars), filter and search state, form wizard progress, selected items, and app preferences like theme or locale. Use RTK Query (createApi) for all server state: API data, user records, content feeds, and any data that originates from a backend. The most common architecture mistake is storing API response data in a createSlice state and manually managing loading, error, and cache states when RTK Query handles all of this automatically. Keep client and server state in separate layers.
