Start with a plain store. Add structure only when the app earns it.
Most state libraries pick your architecture before you know if the app needs
one: actions, reducers, selectors, a provider tree, decided on day one. Kin
Store leaves that decision to you: one function, createStore, gets you
get/set/merge/subscribe, and .use() adds methods, namespacing, and
lifecycle hooks only when you reach for them.
| Kin Store | Zustand | Redux / RTK | Jotai | MobX | |
|---|---|---|---|---|---|
| Bundle size (React usage) | 1.6 KB | 389 B | 17.5 KB | 4.0 KB | 15.6 KB |
| Zero dependencies | ✅ | ✅ | ❌ | ✅ | ✅ |
| Tiny footprint | ✅ | ✅ | ❌ | ✅ | ❌ |
| 100% type-safe | ✅ | ✅ | ✅ | ||
| Low boilerplate | ✅ | ❌ | |||
| Linear plugin composition | ✅ | ❌ | ❌ | n/a | n/a |
| Separate state and logic | ✅ | ❌ | ✅ | n/a | ✅ |
| Opt-in complexity | ✅ | ✅ | ❌ | ❌ | |
| No hidden magic | ✅ | ✅ | ✅ | ✅ | ❌ |
| Reactive composition | ✅ | ❌ | ✅ | ✅ |
✅ full support ·
Bundle sizes are each library's full package import, bundled with rolldown, minified, and gzipped; tree-shaking down to only the APIs you use will land smaller across the board.
Don't believe it? See full comparison with code examples →
Kin Store is pay-per-use: import only createStore and pay 592 B, methods,
namespacing, and lifecycle hooks included. Import derive and it's 460 B more.
The plugin bundles (persist, history, immer, and the rest) add only what
you import.
| Package | Description |
|---|---|
@kintools/store-core |
createStore, derive: the core primitives |
@kintools/store-plugins |
persist, history, immer, devtools, broadcast |
@kintools/store-react |
useStore, useSelector: React bindings |