DEV Community

quojs
quojs

Posted on

Introducing Quo.js: Declarative, Ultra-simple, Expressive State Management for React

Introducing Quo.js

Declarative • Ultra-simple • Expressive

Quo.js is a modern, open-source state management library inspired by Redux — but without the Redux Toolkit baggage.

It brings back the simplicity and predictability of the original Redux pattern while introducing:

  • 🗪 Channels + Events — actions become { channel, event, payload }
  • Native async middleware & effects — async by default; no thunks or sagas
  • 🎯 Granular (atomic) subscriptions — update only what changes
  • 🧩 Dynamic reducers — add or remove reducers at runtime
  • 🧠 TypeScript-first design
  • 🕹️ React bindings ready for Suspense and Concurrent Mode
  • 📦 Zero dependencies

🧭 The idea behind Quo.js

Redux was brilliant — explicit, predictable, and easy to reason about.

But over time, modern abstractions (Toolkit, Zustand, Recoil…) traded that clarity for convenience, and state management became heavier again.

Selectors everywhere, async middleware chains, and component re-renders for tiny changes.

Quo.js started with a simple question:

“What if Redux stayed explicit — but became atomic, async-aware, and effortless?”


⚙️ The Channel + Event model

Instead of actions like { type: 'todos/add', payload }, Quo.js uses channels and events:

store.dispatch({
  channel: "todo",
  event: "add",
  payload: { title: "Write intro post" }
});
Enter fullscreen mode Exit fullscreen mode

Reducers subscribe to specific channels and events (or even property paths) so they only react to what matters.

This enables fine-grained reactivity — without selectors.


🔬 Atomic property subscriptions

You can subscribe directly to a property path:

store.subscribe("todo.data.4.status", handler);
Enter fullscreen mode Exit fullscreen mode

When that property changes, only the component that depends on it re-renders.

No context broadcasts, no memo gymnastics.

Result: updates stay flat and localized — even in large component trees.


🧩 Async middleware & effects

Quo.js ships with an async runtime — no external setup required.

You can define effects that orchestrate workflows, cancel tasks, or coordinate across reducers.

store.effect("todo/fetchAll", async (ctx) => {
  const data = await fetchTodos();
  ctx.dispatch({ channel: "todo", event: "set", payload: data });
});
Enter fullscreen mode Exit fullscreen mode

Async Effects are cancellable and composable — think of them as workflow controllers for your app.


📊 Quo.js vs Redux Toolkit — Profiler Results

Both implementations render the same interactive todo list (creation, filtering, toggling).

Metric Redux Toolkit Quo.js
Re-renders per toggle 12 1
Total re-renders (12 todos) 144 12
Rendering pattern Broad, spiky Flat, localized

Each Quo.js update touches only the subscribed component.

Atomic property subscriptions eliminate wasted renders — even in nested lists.

🔗 Full comparison:

Quo.js vs Redux Toolkit: Profiler Analysis →


🧠 Philosophy

What really defines a state manager isn’t its API surface — it’s the philosophy behind it.

How predictable are updates?

How much boilerplate stands between intent and effect?

Quo.js focuses on:

  • Explicit events
  • Predictable transitions
  • Native async orchestration
  • Minimal surface area

No magic. No hidden optimizations. No ceremony.


🚀 Quick Start

npm i @quojs/core @quojs/react
Enter fullscreen mode Exit fullscreen mode
import { createStore } from "@quojs/core";
import { StoreProvider } from "@quojs/react";
Enter fullscreen mode Exit fullscreen mode

Wrap your React tree:

<StoreProvider store={store}>
  <App />
</StoreProvider>
Enter fullscreen mode Exit fullscreen mode

Use the hooks:

const todo = useSelect("todo.data.4");
const dispatch = useDispatch();
Enter fullscreen mode Exit fullscreen mode

That’s it — no selectors to memoize, no reducers to register manually.


🧩 Packages

Package Description
@quojs/core Core store, reducers, middleware, effects (framework-agnostic)
@quojs/react React provider & hooks (Suspense / Concurrent-ready)
examples/ Runnable samples including the Redux comparison demo

💬 Contributing

Quo.js is fully open source under MPL-2.0.

Check out the Contributing Guide — feedback, forks, and adapters are all welcome.

If you’re into async workflows, reactive state, or typed APIs, come play with us.


🪄 Closing

Quo.js doesn’t try to replace Redux — it evolves it.

A smaller core, more expressive semantics, and a focus on developer happiness.

💙 Declarative

⚡ Ultra-simple

🎨 Expressive

🧭 GitHub Repository


Thanks for reading - We’d love to hear your thoughts, ideas, or performance tests using Quo.js!

Top comments (0)