
Product
Introducing Reports: An Extensible Reporting Framework for Socket Data
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Repatch is just a simplified Redux, that let you create actions more briefly by dispatching reducers directly.
store.dispatch(state => ({ ...state, counter: state.counter + 1 }));
In this terminology, an action is a function that returns a reducer:
const increment = amount => state => ({
...state,
counter: state.counter + amount
});
store.dispatch(increment(42));
Redux has verbose action management. The most of redux projects do not need sctrict action administration. Action types, action creators and the reducer's action handlers are mutually assigned to each other. Repatch's purpose is creating actions briefly.
The simplest way to keep the immutable action controlled dataflow and define actions briefly is dispatching pure functions (as reducers) to the store.
Repatch is
than Redux.
If you have to keep the official Redux in your project, then you can use the redux-repatch or redux-repatch-creator enhancers.
Repatch - the simplified Redux
npm install --save repatch
import Store from 'repatch';
const store = new Store(initialState);
const Store = require('repatch').Store;
<script src="https://unpkg.com/repatch/dist/repatch.js"></script>
or the minified bundle:
<script src="https://unpkg.com/repatch/dist/repatch.min.js"></script>
and
const Store = Repatch.Store;
const thunk = Repatch.thunk;
Repatch's interface is very similar to Redux, therefore you can use with react-redux.
const unsubscribe = store.subscribe(() => console.log(store.getState()));
store.dispatch(resolveFetchingUsers(users));
unsubscribe();
const store = new Store([]);
const addTodo = text => todos => [...todos, { text, checked: false }];
const checkTodo = index => todos => todos.map(
(todo, i) => (i === index ? { ...todo, checked: !todo.checked } : todo)
);
const editTodo = (index, text) => todos => todos.map(
(todo, i) => (i === index ? { ...todo, text } : todo)
);
const removeTodo = index => todos => todos.filter((_, i) => i !== index);
We do not need to reduce always the whole state of the store. Repatch also offers a way to combine sub-reducers, those describe a deeply nested property in the state. We just define a helper function that takes a nested reducer as argument, and returns a reducer that reduces the whole state:
const reduceFoo = fooReducer => state => ({
...state,
bar: {
...state.bar,
foo: fooReducer(state.bar.foo)
}
});
Using that we can define easily an action, that sets an x property in the foo object:
const setX = x => reduceFoo(state => ({ ...state, x }));
A repatch middleware takes the store instance, a next function and the previous reducer. The middleware can provide a new reducer via the next function.
Middleware: Store -> Next -> Reducer -> any
Use the addMiddleware method to chaining middlewares:
const store = new Store(initialState)
.addMiddleware(mw1)
.addMiddleware(mw2, mw3);
This simple logger middleware logs the current- and the next state:
const logger = store => next => reducer => {
const state = store.getState()
const nextState = reducer(state)
console.log(state, nextState)
return next(_ => nextState)
}
const store = new Store(initialState).addMiddleware(logger)
The thunk middleware is useful for handling async actions similar to redux-thunk.
import Store, { thunk } from 'repatch';
const store = new Store(initialState).addMiddleware(thunk);
In thunk async actions reducer returns a function (delegate):
const updateUser = delta => state => async (dispatch, getState) => {
try {
const editedUserId = getState().editedUser;
dispatch(toggleSpinner(true));
await api.updateUser(editedUserId, delta);
await dispatch(fetchUsers());
} catch (error) {
dispatch(state => ({ ...state, error: error.message }))
} finally {
dispatch(toggleSpinner(false));
}
};
It is possible to embed async actions within each other too and awaiting their resolving:
await dispatch(fetchUsers());
It is possible to inject extra arguments into async actions:
import Store, { thunk } from 'repatch';
import api from './api';
import { hashHistory } from 'react-router';
const store = new Store(initialState)
.addMiddleware(thunk.withExtraArgument({ api, hashHistory }));
Then you can access these arguments in your delegates:
const updateUser = delta => state =>
async (dispatch, getState, { api, hashHistory }) => {
// ...
}
This way you can keep your async actions independently from outer instances or side-effects. This practice is useful for testing.
Testing a reducer is easy:
import * as assert from 'assert';
import { changeName } from './actions';
// ...
it('changeName', () => {
const state = { name: 'john' };
const nextState = changeName('jack')(state);
assert.strictEqual(nextState.name, 'jack');
});
For async action tests you need to instantiate the Store and provide mocked extra arguments.
import Store, { thunk } from 'repatch';
import * as assert from 'assert';
import { fetchUsers } from './actions';
const mockUsers = [{ username: 'john' }];
const mockApi = {
getUsers: () => Promise.resolve(mockUsers)
}
// ...
it('fetchUsers', async () => {
const state = { users: [] };
const store = new Store(state)
.addMiddleware(thunk.withExtraArgument({ api: mockApi }));
await store.dispatch(fetchUsers());
const nextState = store.getState();
assert.deepEqual(nextState.users, mockUsers);
});
FAQs
Dispatch reducers
The npm package repatch receives a total of 67 weekly downloads. As such, repatch popularity was classified as not popular.
We found that repatch demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Product
Explore exportable charts for vulnerabilities, dependencies, and usage with Reports, Socket’s new extensible reporting framework.

Product
Socket for Jira lets teams turn alerts into Jira tickets with manual creation, automated ticketing rules, and two-way sync.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.