Skip to content
AI & Agents
Skill

/iii-getting-started

Install the iii engine, set up your first worker, and get a working backend running. Use when a user wants to start a new iii project, install the SDK, or needs help with initial setup and configuration.

From plugin
iii
19k8 skills

Claude Code

$ npx -y skills add iii-hq/iii --skill iii-getting-started --agent claude-code

SKILL.md

iii-getting-started.SKILL.md
name: iii-getting-started
description: >-
  Install the iii engine, set up your first worker, and get a working backend running. Use when a
  user wants to start a new iii project, install the SDK, or needs help with initial setup and
  configuration.

Getting Started with iii

iii replaces your API framework, task queue, cron scheduler, pub/sub, state store, and observability pipeline with a single engine and three primitives: **Worker**, **Function**, **Observer**. Workers host functions, any worker runs a function with `call`, and `iii.observe(a, b)` means "when `a` runs, `b` runs".

Step 1: Install the Engine

curl -fsSL https://install.iii.dev/iii/main/install.sh | sh

Verify it installed:

iii --version

Step 2: Create a Project

iii project init my-app              # barebones project
iii project init my-app -t harness   # or: the harness template (agent + console UI)
cd my-app

`iii project init --learn-iii` scaffolds the harness template and starts it in one step; the installer offers the same when you answer "y" at its prompt. `iii project init --template quickstart` scaffolds the Quickstart with a Python and a TypeScript worker.

Step 3: Start the Project

iii compose --namespace dev --up --file worker-compose.yaml

The file's `engine:` section starts the engine; `containers:` starts project workers. The engine commonly listens on `ws://localhost:49134`. Keep this foreground supervisor running.

`--namespace dev` names the daemon and becomes `III_NAMESPACE` for every worker it starts, so your workers register and call each other in `dev`; that is why the `iii call` commands below pass `-n dev`. Engine-owned functions (`engine::*`, `configuration::*`) stay in `default`, and SDK calls to them resolve there without a namespace (see `iii-sdk-reference`).

Step 4: Install the SDK

Pick your language:

# TypeScript / Node.js
pnpm add iii-sdk @iii-dev/helpers

# Python
pip install iii-sdk iii-helpers

# Rust
cargo add iii-sdk iii-helpers

Step 5: Write Your First Worker

The worker registers `hello::greet` and observes `http::on-request` with a route: each `POST /hello` request runs `hello::greet`, and its return value is the HTTP response.

TypeScript

import { registerWorker } from "iii-sdk";
import { Logger } from "@iii-dev/helpers/observability";

const iii = registerWorker(process.env.III_URL ?? "ws://localhost:49134");

iii.registerFunction(
  "hello::greet",
  async (req: { body?: { name?: string } }) => {
    const logger = new Logger();
    const name = req.body?.name ?? "world";
    logger.info("Greeting user", { name });
    return { status_code: 200, body: { message: `Hello, ${name}!` } };
  },
  { description: "Greet a user by name" },
);

iii.observe(
  { function_id: "http::on-request", args: { method: "POST", path: "/hello" } },
  "hello::greet",
);

Python

from iii import register_worker, InitOptions
from iii_helpers.observability import Logger

iii = register_worker(address="ws://localhost:49134", options=InitOptions(worker_name="hello-worker"))

def greet(req):
    logger = Logger()
    body = req.get("body") or {}
    name = body.get("name", "world") if isinstance(body, dict) else "world"
    logger.info("Greeting user", {"name": name})
    return {"status_code": 200, "body": {"message": f"Hello, {name}!"}}

iii.register_function("hello::greet", greet, description="Greet a user by name")
iii.observe(
    {"function_id": "http::on-request", "args": {"method": "POST", "path": "/hello"}},
    "hello::greet",
)

Rust

use iii_sdk::{register_worker, InitOptions, RegisterFunction, Source};
use iii_helpers::observability::Logger;
use serde_json::json;

let iii = register_worker("ws://127.0.0.1:49134", InitOptions::default());

iii.register_function(
    "hello::greet",
    RegisterFunction::new(|req: serde_json::Value| -> Result<serde_json::Value, iii_sdk::Error> {
        let logger = Logger::new();
        let name = req["body"]["name"].as_str().unwrap_or("world");
        logger.info("Greeting user", Some(json!({ "name": name })));
        Ok(json!({ "status_code": 200, "body": { "message": format!("Hello, {}!", name) } }))
    }).description("Greet a user by name"),
);

iii.observe(
    Source::function("http::on-request").args(json!({ "method": "POST", "path": "/hello" })),
    "hello::greet",
);

To run a function whenever another one runs, observe it the same way: `iii.observe("hello::greet", "audit::record")` (see `iii-observe`).

Step 6: Test It

`http::on-request` comes from the `http` worker. Add it once through the running Compose daemon, then call your endpoint:

iii call -n dev compose::add worker=http
curl -X POST http://localhost:3111/hello \
  -H "Content-Type: application/json" \
  -d '{"name": "iii"}'

Expected response:

{ "message": "Hello, iii!" }

Add Existing Workers

To add a capability that already exists, browse `https://workers.iii.dev/` and add it through the running Compose daemon:

iii call -n dev compose::add worker=state
iii call -n dev compose::add worker=queue
iii call -n dev compose::add worker=image-resize@0.1.2

`compose::add` resolves dependencies, writes exact versions to `worker-compose.yaml`, and restarts the affected project. A local worker can be declared as a `path://` container or added by path.

Install Agent Skills

Get all iii skills for your AI coding agent:

npx skills add iii-hq/iii/skills

Skills teach your agent the top-level iii model: workers, functions, observers, registry access, SDKs, engine configuration, architecture patterns, and error handling. Worker-backed capabilities live with the worker docs and registry entries.

Adapting This Pattern

  • Add more functions to the same worker: each gets its own `registerFunction`, plus an `observe`

for each event that should run it

  • Use `::` separator for f
Read more
@iii-hq
Ships withiii

What is iii? · Install iii · Add Workers · SDKs · Agent Skills · Resources

Stars on GitHub

Momentum

stars in total
18.9k
Star history of iii-hq/iii on GitHub, a chart by star-history.com

Other skills on iii.

iii-architecture-patterns

iii-architecture-patte…

Use when composing iii primitives into backend architectures: durable workflows, reactive backends, observer side effects,…

@iii-hq@iii-hqInstall Skill
iii-core-primitives

iii-core-primitives

Use when registering iii functions, calling them (call with sync, void, or enqueue), observing functions and event sources,…

@iii-hq@iii-hqInstall Skill
iii-engine-config

iii-engine-config

Configure a managed iii engine through worker-compose.yaml or a directly supervised engine through config.yaml. Use for engine…

@iii-hq@iii-hqInstall Skill
iii-error-handling

iii-error-handling

Handle iii engine and SDK errors across Node, Python, Rust, and browser workers. Use when interpreting error codes, retryability,…

@iii-hq@iii-hqInstall Skill
iii-observe

iii-observe

Use when one iii function should run when another runs (iii.observe), when binding functions to HTTP routes, cron schedules,…

@iii-hq@iii-hqInstall Skill
iii-sdk-reference

iii-sdk-reference

Use when working with iii SDK APIs across Node.js, browser, Python, Rust, or Go: package installation, worker initialization,…

@iii-hq@iii-hqInstall Skill

More skills from other plugins.

1password

1password

Set up and use 1Password CLI for sign-in, desktop integration, and reading or injecting secrets.

openclaw11d393k
@openclaw@openclawInstall Skill

Questions about iii-getting-started.

Which coding agents can use iii-getting-started?
iii-getting-started installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.