# Runtimes — OpenClaw and Hermes
Hangar provisions one of two runtimes per agent. Adding a new runtime
is one adapter file plus one DB seed row.
## OpenClaw — Node.js 20
- **Image:** `ghcr.io/ravidsrk/openclaw-runtime:v0.1.0`
- **Entrypoint:** Node 20 worker process
- **Skill format:** Anthropic `AGENTS.md` / `SKILL.md`
- **Bundled skills:** code review, summarization, retrieval, web fetch
- **Channels:** Telegram, Discord, Slack
- **Identity file:** `AGENTS.md`
- **Config file:** `openclaw.json`
OpenClaw is the right pick when:
- Your agent is JavaScript / TypeScript-shaped.
- You want to ship Anthropic SKILL.md skills unmodified.
- You want bundled utility skills already wired to the LLM proxy.
## Hermes — Python 3.11
- **Image:** `ghcr.io/ravidsrk/hermes-runtime:v2026.4.30`
- **Entrypoint:** `python -m hermes_agent`
- **Pre-installed:** LangGraph, CrewAI
- **Channels:** Telegram, Discord, Slack, WhatsApp, email, Matrix
- **Identity file:** `SOUL.md`
- **Config file:** `config.yaml`
Hermes is the right pick when:
- Your agent is Python-shaped, especially LangGraph or CrewAI.
- You want to mount a custom NousResearch hermes-agent persona.
- You need WhatsApp / email / Matrix channels.
## Adapter pattern
Both runtimes implement the same interface:
```ts
interface RuntimeAdapter {
dockerImage(version: string): string
defaultVersion(): string
recommendedMemoryMb(): number
recommendedVolumeGb(): number
startupGracePeriodSec(): number
internalPort(): number
healthPath(): string
cmd(): string[]
buildMachineEnv(state: AdapterInstanceState): Record<string, string>
renderFiles(state: AdapterInstanceState): RuntimeFile[]
features: RuntimeFeatures
}
```
`lib/instances/index.ts` builds the `AdapterInstanceState` (decrypts
secrets, loads personas, skills, channels) then calls the adapter. The
adapters themselves are pure functions — no Drizzle, no network.
## Token audience separation
Every machine receives **three** audience-scoped HMAC tokens. A leaked
LLM token cannot dump the user's secret vault. A leaked files token
cannot make billed calls. Audit-driven design — see
[github.com/ravidsrk/hangar/docs/RUNTIMES.md](https://github.com/ravidsrk/hangar/blob/main/docs/RUNTIMES.md)
for the full table.
## Adding a new runtime
1. Implement `lib/runtimes/<id>/adapter.ts` (export `RuntimeAdapter`).
2. Register it in `lib/runtimes/registry.ts`.
3. Build the Docker image under `runtimes/<id>/`.
4. Push to GHCR via `.github/workflows/runtime-<id>.yml`.
5. Add a `prices` row with `metadata.runtime = '<id>'` in your billing
provider.
That's the entire shopping list. Provisioning, channels, skills,
billing, and realtime stay runtime-agnostic.