Commiq Docs

Getting Started

These are the v1 docs. They are not maintained.

This page is a verbatim snapshot of the commiq 1.x documentation, kept for people still running 1.x. It is not corrected and not tested against any release. Several pages contain claims that were wrong when written: examples that do not run as printed, sealStore described as read-only when it was not, handledEvent presented as a working subscription pattern when it never matched, and effects described as swallowing only AbortError when they swallowed everything.

Do not treat anything here as a statement about how commiq 2.x behaves.

What changed in 2.0 and how to upgrade · Current documentation

Site search only indexes the current docs. Use the sidebar to browse these pages.

Getting Started

Installation

# Core library
pnpm add @naikidev/commiq

# React bindings (optional)
pnpm add @naikidev/commiq-react
# Core library
npm install @naikidev/commiq

# React bindings (optional)
npm install @naikidev/commiq-react
# Core library
yarn add @naikidev/commiq

# React bindings (optional)
yarn add @naikidev/commiq-react
# Core library
bun add @naikidev/commiq

# React bindings (optional)
bun add @naikidev/commiq-react

Your First Store

1. Define the state

type CounterState = {
  count: number;
};

2. Create the store and add handlers

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

const _store = createStore<CounterState>({ count: 0 });

_store
  .addCommandHandler("increment", (ctx) => {
    ctx.setState({ count: ctx.state.count + 1 });
  })
  .addCommandHandler("decrement", (ctx) => {
    ctx.setState({ count: ctx.state.count - 1 });
  });

3. Seal the store

Sealing prevents direct access to addCommandHandler and addEventHandler, ensuring consumers can only read state and queue commands.

export const counterStore = sealStore(_store);

4. Use it

counterStore.queue(createCommand("increment", undefined));
console.log(counterStore.state.count); // 1

Using with React

import { CommiqProvider, useSelector, useQueue } from "@naikidev/commiq-react";
import { counterStore } from "./stores/counter";
import { createCommand } from "@naikidev/commiq";

function App() {
  return (
    <CommiqProvider stores={{ counter: counterStore }}>
      <Counter />
    </CommiqProvider>
  );
}

function Counter() {
  const count = useSelector(counterStore, (s) => s.count);
  const queue = useQueue(counterStore);

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => queue(createCommand("increment", undefined))}>
        +1
      </button>
    </div>
  );
}

Add Devtools

During development, drop in the CommiqDevtools component to see store activity, trace causality chains, and inspect state:

pnpm add @naikidev/commiq-devtools
npm install @naikidev/commiq-devtools
yarn add @naikidev/commiq-devtools
bun add @naikidev/commiq-devtools
import { CommiqDevtools } from "@naikidev/commiq-devtools";
import { counterStore } from "./stores/counter";

function App() {
  return (
    <>
      <Counter />
      <CommiqDevtools stores={{ counter: counterStore }} />
    </>
  );
}

On this page