Kiss State is a powerful and modern state management library for React, launched in May 2025. While new to React, Kiss has been available for Flutter for years, battle-tested in hundreds of real-world applications.
AI ready: Centralizes state and business logic in predictable ways, making it easier for AI models to reason about code. This improves AI-driven generation, and helps you achieve results with surprisingly little effort.
Store and state
The store holds all the application state. A few examples:
// If your state is a number
const store = createStore<number>({initialState: 1});
// If your state is a plain JavaScript object
const store = createStore({initialState: {name: 'Mary', age: 25}});
// If your state is an ES6 class object
class State { constructor(public name: string, public age: number){} }
const store = createStore<State>({initialState: new State('Mary', 25)});
Use a StoreProvider
to add the store to your component tree:
function App() {
return (
<StoreProvider store={store}>
<AppContent />
</StoreProvider>
);
};
Components use the state
The useAllState
hook lets you access the state from any component.
It rebuilds when the state changes.
function MyComponent() {
const state = useAllState();
return <div>{state.name} is {state.age} years old</div>;
};
The useSelect
hook selects only the part of the state that your component needs.
It rebuilds only when that part changes.
function MyComponent() {
const name = useSelect((state) => state.name);
const age = useSelect((state) => state.age);
return <div>{name} is {age} years old</div>;
};
The useObject
hook also only rebuilds when needed:
function MyComponent() {
const state = useObject((state) => {
name: state.name,
age: state.age
});
return <div>{state.name} is {state.age} years old</div>;
};
Actions and reducers
An action is a class that contains its own reducer function. This reducer has access to the current state, and its goal is to return a new and modified state.
class Increment extends Action {
reduce() {
// The reducer has access to the current state
return this.state + 1; // It returns a new state
};
}
Dispatch an action
The store state is immutable.
The only way to change the store state is by dispatching an action. This will run the action's reducer to get a new state that will replace the current one, and rebuild all components that use it.
// Dispatch an action
store.dispatch(new Increment());
// Dispatch multiple actions
store.dispatchAll([new Increment(), new LoadText()]);
// Dispatch an action and wait for it to finish
await store.dispatchAndWait(new Increment());
// Dispatch multiple actions and wait for them to finish
await store.dispatchAndWaitAll([new Increment(), new LoadText()]);
Components can dispatch actions
The hooks to dispatch actions are useDispatch
, useDispatchAll
etc.
function MyComponent() {
const dispatch = useDispatch();
return (
<Button onClick={() => dispatch(new LoadText())}>
Click me!
</Button>
);
};