Guide · Open source
How to use redux-saga: install, set up and write your first saga
Updated · written with AI from the project's own documentation and checked against our catalogue data
redux-saga is an open-source MIT-licensed JavaScript library for Redux apps that manages side effects such as fetching data from a server or reading from the browser cache. This guide shows you how to install it, connect it to a Redux store, and write a saga that handles a fetch request. By the end you will know how the pieces fit together and when the library is a good fit.
Quick start
- 1Install the package. Run npm install redux-saga or yarn add redux-saga in your project.
- 2Create the middleware. Call createSagaMiddleware() to make the saga middleware.
- 3Mount it on the store. Pass the middleware to applyMiddleware when you call createStore.
- 4Write a worker saga. Write a generator function that uses call to make the API request and put to dispatch the result.
- 5Write a watcher saga. Use takeEvery or takeLatest to start the worker when a specific action type is dispatched.
- 6Run the root saga. Call sagaMiddleware.run with your root saga after the store is created.
- 7Dispatch the trigger action. Dispatch a plain object action such as USER_FETCH_REQUESTED from your component.
What redux-saga does and when to use it
redux-saga runs as Redux middleware. A saga is a background task that is responsible for side effects. Normal Redux actions can start, pause or cancel it, and it can read the application state and dispatch actions of its own.
The library uses JavaScript generator functions so that asynchronous code reads like ordinary step-by-step code. The README notes that this is similar to async/await but offers more features, including cancellation.
- Good fit: React or other frontend developers already using Redux who need to manage async logic.
- Good fit: teams that want asynchronous flows that are easy to test.
- Good fit: apps where side effects need cancellation, such as cancelling a pending fetch when a new one starts.
- Probably not a fit: apps that do not use Redux, since the library is built as Redux middleware.
- Probably not a fit: simple apps with only a few API calls, where a lighter approach may be enough.
Install redux-saga with npm or yarn
The library is installed through a package manager. The README lists no prerequisites beyond this. Run one of the following commands in your project folder.
$ npm install redux-saga
or
$ yarn add redux-sagaConnect the saga middleware to your Redux store
Create the saga middleware with createSagaMiddleware, mount it on the store with applyMiddleware, and then run your root saga with sagaMiddleware.run. The example below is taken from the README and assumes you have a reducer and a saga file of your own.
import { createStore, applyMiddleware } from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducers'
import mySaga from './sagas'
// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(reducer, applyMiddleware(sagaMiddleware))
// then run the saga
sagaMiddleware.run(mySaga)Write a worker saga and a watcher saga
The README's example has a component dispatch a plain object action called USER_FETCH_REQUESTED. A worker saga, fetchUser, calls the API using the call effect and reports the result with put. If the call throws, the catch block dispatches a failure action.
A watcher saga listens for the request action. Use takeEvery to start a worker for every matching action, which allows concurrent fetches. Use takeLatest if only the newest request should run: a pending fetch is cancelled when a new one is dispatched.
- takeEvery: starts fetchUser on each USER_FETCH_REQUESTED action; concurrent fetches are allowed.
- takeLatest: a pending fetch is cancelled when a new USER_FETCH_REQUESTED action arrives, and only the latest one runs.
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
// worker Saga: will be fired on USER_FETCH_REQUESTED actions
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId)
yield put({ type: 'USER_FETCH_SUCCEEDED', user: user })
} catch (e) {
yield put({ type: 'USER_FETCH_FAILED', message: e.message })
}
}
function* mySaga() {
yield takeEvery('USER_FETCH_REQUESTED', fetchUser)
}
export default mySagaDispatch the action from your component
The component does not call the API itself. It dispatches a plain object action, and the saga takes over from there. This keeps the component simple and keeps the action objects pure.
class UserComponent extends React.Component {
...
onSomeButtonClicked() {
const { userId, dispatch } = this.props
dispatch({type: 'USER_FETCH_REQUESTED', payload: {userId}})
}
...
}Where to learn more and check examples
The official documentation covers the introduction, basic and advanced concepts, recipes, and the API reference. The README also links to translations in several languages. To run the bundled examples, clone the repository and use the scripts it lists, such as npm run counter or npm run async.
If your target browser does not support ES2015 generators, the README says you must transpile them and provide a runtime such as regenerator-runtime. A UMD build is also available in the dist/ folder for projects that do not use Webpack or Browserify.
- Documentation: https://redux-saga.js.org/
- Introduction: https://redux-saga.js.org/docs/introduction/BeginnerTutorial.html
- API Reference: https://redux-saga.js.org/docs/api/index.html
- Troubleshooting: https://redux-saga.js.org/docs/Troubleshooting.html
What people use it for
- Fetching user data from a server when a button is clicked, as shown in the README example.
- Cancelling a pending fetch when a new one starts, using takeLatest.
- Reading from the browser cache as a side effect, which the README gives as an example of impure work.
- Organising asynchronous logic that has grown messy with redux-thunk callbacks.
Frequently asked questions
How do I install redux-saga?
Run npm install redux-saga or yarn add redux-saga in your project folder. The README lists no other prerequisites for installation. A UMD build is also available for use directly in a script tag.
Is redux-saga free to use?
redux-saga is released under the MIT licence, as stated in the project's listing. Check the LICENSE file in the repository for the full terms.
Does redux-saga require Redux?
Yes. The library is built as Redux middleware, so it is only useful in apps that use Redux. Apps without Redux should look at other tools.
What is the difference between takeEvery and takeLatest?
takeEvery starts a worker for every matching action and allows concurrent fetches. takeLatest cancels any pending worker when a new matching action is dispatched, so only the latest one runs.
Is redux-saga better than redux-thunk?
The README says that, unlike redux-thunk, sagas avoid callback hell, can be tested more easily, and keep actions pure. Simple apps with few API calls may not need it, so the choice depends on how complex your async logic is.
Do I need to learn generator functions to use it?
Yes. The project chose generators over async/await, so sagas are written as generator functions. The README links to introductory resources if you are not familiar with them.
New agent skills, repos and AI tools — every week
The best new skills and open-source projects, the fastest-growing repos, and one free prompt. Five minutes to read. Unsubscribe anytime.
Our verdict
redux-saga suits Redux apps with complex asynchronous logic, especially where cancellation and testability matter. Choose something lighter, such as redux-thunk or a built-in Redux Toolkit option, if your app is not using Redux or only makes a few API calls.
Install options & downloads