Iii iii-reactive-backend

install
source · Clone the upstream repo
git clone https://github.com/iii-hq/iii
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/iii-hq/iii "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/iii-reactive-backend" ~/.claude/skills/iii-hq-iii-iii-reactive-backend && rm -rf "$T"
manifest: skills/iii-reactive-backend/SKILL.md
source content

Reactive Backend

Comparable to: Convex, Firebase, Supabase, Appwrite

Key Concepts

Use the concepts below when they fit the task. Not every reactive backend needs every trigger or realtime surface shown here.

  • State is the "database" — CRUD via
    state::set
    ,
    state::get
    ,
    state::update
    ,
    state::delete
    ,
    state::list
  • State triggers fire automatically when any value in a scope changes
  • Side effects (notifications, metrics, stream pushes) are wired reactively, not imperatively
  • Streams deliver real-time updates to connected clients

Architecture

HTTP CRUD endpoints
  → `state::set`, `state::update`, `state::delete` (writes to 'todos' scope)
    ↓ (automatic state triggers)
    → on-change → stream::send (push to clients)
    → update-metrics → state::update (aggregate counters)

HTTP GET /metrics → reads from 'todo-metrics' scope
WebSocket clients ← stream 'todos-live'

iii Primitives Used

PrimitivePurpose
registerWorker
Initialize the worker and connect to iii
registerFunction
CRUD handlers and reactive side effects
trigger({ function_id: 'state::...', payload })
Database layer
registerTrigger({ type: 'state', config: { scope } })
React to any change in a scope
trigger({ ..., action: TriggerAction.Void() })
Fire-and-forget stream push to clients
registerTrigger({ type: 'http' })
REST endpoints

Reference Implementation

See ../references/reactive-backend.js for the full working example — a real-time todo app with CRUD endpoints, automatic change broadcasting via streams, and reactive aggregate metrics.

Common Patterns

Code using this pattern commonly includes, when relevant:

  • registerWorker(url, { workerName })
    — worker initialization
  • trigger
    state::set
    ,
    state::get
    — CRUD via state module
  • registerTrigger({ type: 'state', function_id, config: { scope } })
    — reactive side effects on state change
  • Event argument destructuring in reactive handlers:
    async (event) => { const { new_value, old_value, key } = event }
  • trigger({ function_id: 'stream::send', payload, action: TriggerAction.Void() })
    — push live updates to clients
  • const logger = new Logger()
    — structured logging inside handlers

Adapting This Pattern

Use the adaptations below when they apply to the task.

  • State triggers fire on any change in the scope — use the
    event
    argument (
    new_value
    ,
    old_value
    ,
    key
    ) to determine what changed
  • Multiple functions can react to the same scope independently (on-change and update-metrics both watch
    todos
    )
  • Stream clients connect via
    ws://host:port/stream/{stream_name}/{group_id}
  • Keep reactive functions fast — offload heavy work to queues if needed

Pattern Boundaries

  • If the request focuses on registering external/legacy HTTP endpoints via
    registerFunction
    (especially with endpoint lists like
    { path, id }
    plus iteration), prefer
    iii-http-invoked-functions
    .
  • Stay with
    iii-reactive-backend
    when state scopes, state triggers, and live stream updates are the core requirement.

When to Use

  • Use this skill when the task is primarily about
    iii-reactive-backend
    in the iii engine.
  • Triggers when the request directly asks for this pattern or an equivalent implementation.

Boundaries

  • Never use this skill as a generic fallback for unrelated tasks.
  • You must not apply this skill when a more specific iii skill is a better fit.
  • Always verify environment and safety constraints before applying examples from this skill.