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.mdsource 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::deletestate::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
| Primitive | Purpose |
|---|---|
| Initialize the worker and connect to iii |
| CRUD handlers and reactive side effects |
| Database layer |
| React to any change in a scope |
| Fire-and-forget stream push to clients |
| 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:
— worker initializationregisterWorker(url, { workerName })- trigger
,state::set
— CRUD via state modulestate::get
— reactive side effects on state changeregisterTrigger({ type: 'state', function_id, config: { scope } })- Event argument destructuring in reactive handlers:
async (event) => { const { new_value, old_value, key } = event }
— push live updates to clientstrigger({ function_id: 'stream::send', payload, action: TriggerAction.Void() })
— structured logging inside handlersconst logger = new Logger()
Adapting This Pattern
Use the adaptations below when they apply to the task.
- State triggers fire on any change in the scope — use the
argument (event
,new_value
,old_value
) to determine what changedkey - 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
(especially with endpoint lists likeregisterFunction
plus iteration), prefer{ path, id }
.iii-http-invoked-functions - Stay with
when state scopes, state triggers, and live stream updates are the core requirement.iii-reactive-backend
When to Use
- Use this skill when the task is primarily about
in the iii engine.iii-reactive-backend - 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.