Migrate a legacy Redux app incrementally by first replacing createStore with configureStore to establish the new foundation, then converting existing reducers to createSlice and upgrading React-Redux connect components to the hooks API, all while allowing both old and new code to coexist in a single store.
It is absolutely possible to migrate a production Redux application to Redux Toolkit (RTK) incrementally and safely[citation:2][citation:6]. The key principle is that legacy Redux code and modern RTK code can coexist in the same store[citation:2]. By following a step-by-step approach, you can modernize your codebase piece by piece without having to do a risky, all-at-once rewrite. The recommended path is to first modernize your store setup with configureStore, then one by one convert your reducers using createSlice, and finally update your React components.
You should always start by replacing the legacy createStore call with RTK's configureStore[citation:1]. This step is crucial because it establishes the modern foundation upon which you will build incrementally. configureStore automatically adds essential middleware like redux-thunk and enables the Redux DevTools, but it's designed to be backwards-compatible—all of your existing reducers, middleware, and other code will continue to work as-is[citation:1][citation:6]. Once this is done, you can verify that your app still runs, and you're ready for the next phase.
After the store is using configureStore, you can begin converting your existing reducer logic. A typical legacy setup involves separate files for action types, action creators, and the reducer itself[citation:1]. You can replace these entirely with a single slice file that uses the createSlice API[citation:6]. This API combines action types, action creators, and reducer logic into one place and uses Immer to allow simpler mutable update logic[citation:1].
The legacy connect higher-order component can be replaced incrementally with React-Redux's modern hooks API—specifically useSelector and useDispatch[citation:1]. These hooks are not only more concise and easier to use but also work seamlessly with both your old and new reducers, allowing you to migrate your components one by one. Strongly typing your store's state and dispatch is considered a best practice, as it provides better type safety and autocompletion in your code editor[citation:1].
If you're considering moving to an entirely different state management solution like Jotai, the same principle of incremental migration applies. The approach is to keep your Redux store alongside the new state manager, building new features with Jotai and gradually moving old pieces to Jotai when they need to be changed or refactored. This distributed approach can offer a migration path away from centralised Redux to a more modern, atomic model without the risks of a 'big bang' rewrite[citation:9]. The key is that both systems can coexist in the same app.