Top Related Projects
Quick Overview
Rematch is a Redux framework that aims to simplify state management in JavaScript applications. It provides a more intuitive API for managing state, reducing boilerplate code, and improving developer experience while maintaining the benefits of Redux.
Pros
- Simplified Redux setup with less boilerplate code
- Built-in support for async actions and side effects
- Easy integration with existing Redux projects
- Excellent TypeScript support
Cons
- Learning curve for developers new to Redux concepts
- May be overkill for small projects
- Potential performance overhead compared to vanilla Redux
- Limited ecosystem compared to Redux
Code Examples
- Defining a model:
const count = {
state: 0,
reducers: {
increment(state, payload) {
return state + payload
},
},
effects: (dispatch) => ({
async incrementAsync(payload) {
await new Promise(resolve => setTimeout(resolve, 1000))
dispatch.count.increment(payload)
},
}),
}
- Creating a store:
import { init } from '@rematch/core'
import * as models from './models'
const store = init({
models,
})
- Using in a React component:
import { useSelector, useDispatch } from 'react-redux'
function Counter() {
const count = useSelector(state => state.count)
const dispatch = useDispatch()
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch.count.increment(1)}>Increment</button>
<button onClick={() => dispatch.count.incrementAsync(1)}>Increment Async</button>
</div>
)
}
Getting Started
- Install Rematch:
npm install @rematch/core
- Create a model:
// models/count.js
export const count = {
state: 0,
reducers: {
increment(state, payload) {
return state + payload
},
},
}
- Initialize the store:
// store.js
import { init } from '@rematch/core'
import * as models from './models'
const store = init({
models,
})
export default store
- Use in your app:
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
Competitor Comparisons
A JS library for predictable global state management
Pros of Redux
- Widely adopted and battle-tested in large-scale applications
- Extensive ecosystem with many middleware and developer tools
- Predictable state management with a single source of truth
Cons of Redux
- Steep learning curve and complex boilerplate code
- Verbose syntax for defining actions and reducers
- Can be overkill for smaller applications
Code Comparison
Redux:
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
default:
return state;
}
};
Rematch:
const count = {
state: 0,
reducers: {
increment(state) {
return state + 1;
},
},
};
Rematch simplifies the Redux pattern by reducing boilerplate and providing a more intuitive API. It offers automatic action creation and simplified reducer definitions, making it easier to manage state in React applications. However, Redux's extensive ecosystem and widespread adoption make it a more versatile choice for complex projects with specific requirements.
Both libraries aim to solve state management challenges in React applications, but Rematch focuses on simplicity and ease of use, while Redux provides a more robust and flexible foundation for large-scale applications.
Simple, scalable state management.
Pros of MobX
- Simpler API with less boilerplate code
- Automatic tracking of observable state changes
- More flexible, allowing fine-grained control over reactivity
Cons of MobX
- Steeper learning curve for developers new to reactive programming
- Less predictable behavior due to automatic reactivity
- Potential performance issues with large, complex state trees
Code Comparison
MobX:
import { makeAutoObservable } from "mobx";
class TodoStore {
todos = [];
constructor() {
makeAutoObservable(this);
}
addTodo(text) {
this.todos.push({ text, completed: false });
}
}
Rematch:
const todos = {
state: [],
reducers: {
addTodo(state, payload) {
return [...state, { text: payload, completed: false }];
},
},
};
export const store = init({
models: { todos },
});
MobX uses a more object-oriented approach with automatic reactivity, while Rematch follows a more traditional Redux-like pattern with explicit actions and reducers. MobX's code is often more concise, but Rematch's structure may be more familiar to developers with Redux experience.
Both libraries aim to simplify state management, but they take different approaches. MobX focuses on reactivity and minimal boilerplate, while Rematch provides a structured, Redux-like experience with less complexity than vanilla Redux.
👻 Primitive and flexible state management for React
Pros of Jotai
- Lightweight and minimalistic approach to state management
- Supports TypeScript out of the box with excellent type inference
- Easier to use with React's concurrent features and Suspense
Cons of Jotai
- Less suitable for complex, large-scale applications compared to Rematch
- Lacks built-in middleware support and plugins ecosystem
- May require additional libraries for advanced features like persistence
Code Comparison
Jotai:
import { atom, useAtom } from 'jotai'
const countAtom = atom(0)
function Counter() {
const [count, setCount] = useAtom(countAtom)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
Rematch:
import { init } from '@rematch/core'
const store = init({
models: {
count: {
state: 0,
reducers: {
increment(state) { return state + 1 }
}
}
}
})
function Counter() {
const count = useSelector(state => state.count)
const { increment } = useDispatch(store.dispatch.count)
return <button onClick={increment}>{count}</button>
}
Business logic with ease ☄️
Pros of Effector
- Lightweight and fast, with a smaller bundle size
- More flexible and composable API
- Better TypeScript support out of the box
Cons of Effector
- Steeper learning curve due to unique concepts
- Smaller community and ecosystem compared to Rematch
- Less integration with existing Redux tooling
Code Comparison
Effector:
import { createStore, createEvent } from 'effector'
const increment = createEvent()
const $counter = createStore(0)
.on(increment, state => state + 1)
$counter.watch(console.log)
increment()
Rematch:
import { init } from '@rematch/core'
const counter = {
state: 0,
reducers: {
increment: state => state + 1
}
}
const store = init({ models: { counter } })
store.dispatch.counter.increment()
Both libraries aim to simplify state management, but Effector takes a more functional approach with its event-based system, while Rematch builds on top of Redux with a more familiar model-based structure. Effector's API is more concise and flexible, but Rematch may be easier to adopt for developers already familiar with Redux patterns.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Rematchjs
Rematch is Redux best practices without the boilerplate. No more action types, action creators, switch statements or thunks in less than 1.4 kilobytes.
Documentation · Quickstart · Examples · Contribute · Licence
Features
Redux is an amazing state management tool, supported by a healthy middleware ecosystem and excellent devtools. Rematch builds upon Redux by reducing boilerplate and enforcing best practices. It provides the following features:
- No configuration needed
- Reduces Redux boilerplate
- Built-in side-effects support
- React Devtools support
- TypeScript support
- Supports dynamically adding reducers
- Supports hot-reloading
- Allows to create multiple stores
- Supports React Native
- Extendable with plugins
- Many plugins available out of the box:
- for persisting data with redux-persist
- for wrapping state with immer.js
- for creating selectors with reselect
- ...and others
Are you ready to use Rematch?
In a few lines you can get easily asynchronous calls to an external API and data stored globally. It's amazing, with Redux you will needs tons of boilerplate, libraries and extra configuration.
type PlayersState = {
players: PlayerModel[]
}
export const players = createModel<RootModel>()({
state: {
players: [],
} as PlayersState,
reducers: {
SET_PLAYERS: (state: PlayersState, players: PlayerModel[]) => {
return {
...state,
players,
}
},
},
effects: (dispatch) => {
const { players } = dispatch
return {
async getPlayers(): Promise<any> {
let response = await fetch('https://www.balldontlie.io/api/v1/players')
let { data }: { data: PlayerModel[] } = await response.json()
players.SET_PLAYERS(data)
},
}
},
})
Check it out, right now!
Redux vs Rematch
Redux | Rematch | |
---|---|---|
simple setup â | ââ | |
less boilerplate | ââ | |
readability | ââ | |
configurable | â â | ââ |
redux devtools | ââ | ââ |
generated action creators | â | ââ |
async | thunks | âasync/await |
Migrate From Redux
Migrating from Redux to Rematch may only involve minor changes to your state management, and no necessary changes to your view logic. See the migration reference for the details.
Composable Plugins
Rematch and its internals are all built upon a plugin pipeline. As a result, developers can make complex custom plugins that modify the setup or add data models, often without requiring any changes to Rematch itself. See the plugins developed by the Rematch team or the API for creating plugins.
Contact & Support
- Create a GitHub issue for bug reports, feature requests, or questions
- Add a âï¸ star on GitHub to support the project!
Contributors
Thank you to all the people who have already contributed to rematch!
Made with contributors-img.
Licence
This project is licensed under the MIT license.
Top Related Projects
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot