Commiq Docs

Introduction

Commiq is a command and event driven state management library for TypeScript, with optional React bindings.

Introduction

Commiq is a command and event driven state management library for TypeScript. The core has no framework dependency; React bindings ship separately as @naikidev/commiq-react.

Instead of writing to state directly, you dispatch a command describing what should happen. One handler processes it, produces the next state, and may emit events that other parts of the application react to. Every command and event carries a correlationId and a causedBy link, so the causal chain behind any state change is recoverable.

The cost of that structure is indirection: a state change is a command definition, a handler and a dispatch rather than a setter. In exchange, state transitions are named, auditable, cancellable, and observable from outside the code that caused them.

Upgrading from 1.x? The migration guide lists every breaking change — and the features that silently never worked in v1.

Key concepts

ConceptDescription
CommandA request to do something, dispatched via queue(). Exactly one handler per name
HandlerProcesses a command and produces the next state via ctx.setState()
EventA notification that something happened. Zero or many handlers, which may only queue commands
StoreHolds one state object, routes commands sequentially, publishes events
Sealed storeA facade exposing only state, queue, flush, suspend and stream control — no registration
Event busRoutes events between multiple stores without coupling them

Packages

All packages share one version and are released together.

PackagePurpose
@naikidev/commiqCore library, framework-agnostic
@naikidev/commiq-reactReact bindings — useSelector, useQueue, useEvent and more
@naikidev/commiq-effectsStructured side effects with cancellation and concurrency modes
@naikidev/commiq-persistState persistence and rehydration across localStorage, sessionStorage and IndexedDB
@naikidev/commiq-contextPrebuilt context extensions — logging, metadata, history, guards, dependency injection
@naikidev/commiq-devtools-coreInstrumentation engine: event timeline, causality chains, state history
@naikidev/commiq-devtoolsEmbedded devtools panel for React applications
@naikidev/commiq-otelOpenTelemetry tracing

Quick example

import { createStore, createCommandDef, sealStore } from "@naikidev/commiq";

const increment = createCommandDef("increment");
const store = createStore({ count: 0 });

store.addCommandHandler(increment, (ctx) => {
  ctx.setState({ count: ctx.state.count + 1 });
});

const counter = sealStore(store);

await counter.queue(increment);
counter.state.count; // 1

Commands are processed asynchronously, so counter.state reflects the change once the handle resolves — or after await counter.flush() when several commands are in flight.

Start with Getting Started.

On this page