npx skills add ...
npx skills add iii-hq/iii --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.
npx skills add iii-hq/iii --skill iii-getting-started
iii replaces your API framework, task queue, cron scheduler, pub/sub, state store, and observability pipeline with a single engine and three primitives: Function, Trigger, Worker.
Verify it installed:
Follow the interactive prompts to select a template and language. The default quickstart template includes TypeScript, Python, and Rust workers.
Then change into the project directory you chose at the prompt:
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.
Pick your language:
Expected response:
To add a capability that already exists, browse https://workers.iii.dev/ and add it through the
running Compose daemon:
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.
Get all iii skills for your AI coding agent:
Skills teach your agent the top-level iii model: functions, triggers, workers, registry access, SDKs, engine configuration, architecture patterns, and error handling. Worker-backed capabilities live with the worker docs and registry entries.
registerFunction + registerTrigger
calls:: separator for function IDs to namespace them: orders::create, orders::validate{ type: 'cron', config: { expression: '0 0 9 * * * *' } } (7-field: sec
min hour day month weekday year){ type: 'durable:subscriber', config: { topic: 'my-queue' } }iii.trigger() to invoke other functions from within a functionstate::get / state::set to persist data across function callsiii trigger -n <daemon> compose::add worker=<name> when the capability already exists in
the worker registryAfter getting your first worker running:
iii-core-primitivesiii-sdk-referenceiii-engine-configiii-architecture-patternsiii-error-handlingiii-core-primitivesiii-sdk-referenceiii-engine-configengine/src/workers/**/skillsiii-getting-started for installation, initial setup, and first-worker guidanceiii compose --namespace dev --up --file worker-compose.yaml# TypeScript / Node.js
pnpm add iii-sdk @iii-dev/helpers
# Python
pip install iii-sdk iii-helpers
# Rust
cargo add iii-sdk iii-helpersimport { registerWorker, TriggerAction } 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 (input) => {
const logger = new Logger();
const name = input?.name ?? "world";
logger.info("Greeting user", { name });
return { message: `Hello, ${name}!` };
},
{ description: "Greet a user by name" },
);
iii.registerTrigger({
type: "http",
function_id: "hello::greet",
config: { api_path: "/hello", http_method: "POST" },
});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(data):
logger = Logger()
name = data.get("name", "world") if isinstance(data, dict) else "world"
logger.info("Greeting user", {"name": name})
return {"message": f"Hello, {name}!"}
iii.register_function("hello::greet", greet, description="Greet a user by name")
iii.register_trigger({"type": "http", "function_id": "hello::greet", "config": {"api_path": "/hello", "http_method": "POST"}})use iii_sdk::{register_worker, InitOptions, RegisterFunction};
use iii_sdk::protocol::RegisterTriggerInput;
use iii_helpers::observability::Logger;
use serde_json::json;
let iii = register_worker("ws://127.0.0.1:49134", InitOptions::default());
iii.register_function(
RegisterFunction::new("hello::greet", |input: serde_json::Value| -> Result<serde_json::Value, String> {
let logger = Logger::new();
let name = input["name"].as_str().unwrap_or("world");
logger.info("Greeting user", Some(json!({ "name": name })));
Ok(json!({ "message": format!("Hello, {}!", name) }))
}).description("Greet a user by name"),
);
iii.register_trigger(RegisterTriggerInput {
trigger_type: "http".into(),
function_id: "hello::greet".into(),
config: json!({ "api_path": "/hello", "http_method": "POST" }),
metadata: None,
})?;curl -X POST http://localhost:3111/hello \
-H "Content-Type: application/json" \
-d '{"name": "iii"}'{ "message": "Hello, iii!" }iii trigger -n dev compose::add worker=state
iii trigger -n dev compose::add worker=queue
iii trigger -n dev compose::add worker=image-resize@0.1.2npx skills add iii-hq/iii/skills