https://github.com/zephraph/mustate
Minimal immutable state management for React
https://github.com/zephraph/mustate
Last synced: 6 months ago
JSON representation
Minimal immutable state management for React
- Host: GitHub
- URL: https://github.com/zephraph/mustate
- Owner: zephraph
- License: mit
- Created: 2025-07-04T03:41:26.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-07-05T05:51:08.000Z (9 months ago)
- Last Synced: 2025-07-05T06:33:45.999Z (9 months ago)
- Language: TypeScript
- Size: 69.3 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Mustate
> Minimal immutable state management for React
## Quick Start
```bash
npm install @just-be/mustate
```
**Table of Contents**
- [Example](#example)
- [API](#api)
- [`createStore(initialState: State): Store`](#createstorestateintialstate-state-storestate)
- [`createStoreHook(store: Store): useStore`](#createstorehookstatestore-storestate-usestore)
- [`createStoreWithHook(initialState: State): [Store, useStore]`](#createstorewithhookstateintialstate-state-storestate-usestore)
- [`store`](#store)
- [`useStore(selector: (state: State) => Value): Value`](#usestorevalueselector-state-state--value-value)
## Example
```jsx
import React from 'react';
import { render } from 'react-dom';
import { createStoreWithHook } from '@just-be/mustate';
// Create a lil' store with some state
let [store, useStore] = createStoreWithHook({
count: 0,
});
// The app doesn't need a provider
function App() {
return (
);
}
// You can mutate the store from anywhere you want to,
// even outside of React code. Mutate is based on mutative.
function increment() {
store.mutate(state => {
state.count++;
});
}
// Or you can update it like React.useState's update
function decrement() {
store.set(prevState => ({
...prevState,
count: prevState.count - 1
}));
}
// You don't need to pass the store down as a prop either
function Buttons() {
return (
-
+
);
}
// Lastly, you can subscribe to "slices" of state by passing a selector to
// useStore. The component will only be re-rendered when that portion of state
// changes.
function Label() {
const count = useStore(state => state.count);
return
The count is {count}
;
}
render(, window.root);
```
## API
### `createStore(initialState: State): Store`
Create a mustate `store` given some initial state. Returns a store instance that can be used anywhere in your application.
```jsx
import { createStore } from '@just-be/mustate';
const store = createStore({ count: 0, name: 'Alice' });
```
### `createStoreHook(store: Store): useStore`
Create a React hook for a specific store. This allows you to subscribe to state changes in React components.
```jsx
import { createStore, createStoreHook } from '@just-be/mustate';
const store = createStore({ count: 0 });
const useStore = createStoreHook(store);
// In a React component
function Counter() {
const count = useStore(state => state.count);
return
{count};
}
```
### `createStoreWithHook(initialState: State): [Store, useStore]`
Convenience function that combines `createStore` and `createStoreHook`. This is equivalent to calling both functions separately.
```jsx
import { createStoreWithHook } from '@just-be/mustate';
const [store, useStore] = createStoreWithHook({ count: 0, name: 'Alice' });
```
The `store` has the following API you can use in or out of React:
#### `store`
| **Method** | **Description** |
| ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `get()` | Get the current state. Do not use this inside of React, you should instead use [`useStore`](#usestorevalueselector-state-state--value-value) |
| `set(nextState: S \| (prevState: S) => V): void;` | Set state. This can either take a new value or and updater function (just like React.useState's updater) |
| `on(listener: Function): () => void;` | Subscribe to store. Pass in a callback function that will be executed on updates. `on()` returns the unsubscribe function for your convenience. |
| `off(listener: Function): void;` | Unsubscribe a given listener function |
| `reset(): void` | Set state back to the `initialState` used when creating the store |
| `mutate(updater: (draft: Draft) => void \| S): void;` | Mutative-style updater function. |
#### `useStore(selector: (state: State) => Value): Value`
React hook to subscribe to mustate state.
```jsx
const selector = state => state.count;
function Label() {
const count = useStore(selector);
return
The count is {count}
;
}
```
You can use props with mustate selector.
```jsx
function User({ id }) {
const user = useStore(state => state.users[id]);
return
The username is {user.name}
;
}
```
## Inspiration
This project was inspired by Jared Palmer's [Mutik](https://github.com/jaredpalmer/mutik).