Skip to content
tokenworm ★ GitHub

Zig 0.16 · MIT · github.com/neul-labs/tokenworm

The systems-language agent SDK.

A tiny, fast, zero-dependency AI coding agent — CLI, C-ABI library, and idiomatic SDKs for Python, TypeScript, and Go. One 960KB Zig binary, 8ms cold start, the same agent core in every package.

What the README claims, verbatim

960KB

ReleaseSmall binary

8ms

cold start

2.4MB

idle memory

0

runtime dependencies

6

built-in tools

5

LLM providers

18

lifecycle hooks

Zig 0.16

compiler

What is tokenworm?

A systems-language AI coding agent, shipped as one binary.

tokenworm is an MIT-licensed AI coding agent written in Zig 0.16. It ships as a ~960KB native binary with zero runtime dependencies, and the same agent core is exposed as a CLI, a C ABI library (libtokenworm.so / .dylib), and idiomatic SDKs for Python, TypeScript, and Go. The product surface is small on purpose: six built-in tools, five LLM providers, OS-native sandboxing, and portable .tworm sessions.

At a glance

  • LanguageZig 0.16
  • Binary size960KB
  • Runtime deps0
  • SurfacesCLI · C ABI · Py · TS · Go
  • Providers5
  • LicenseMIT

The problem, and the bet

Agent SDKs shouldn't need a runtime to run

The problem

  • ×Most agent SDKs assume a Node.js or Python runtime — hundreds of megabytes to deploy for one feature.
  • ×Embedding an agent in a native app, a CI runner, or a systems daemon means shipping that whole runtime alongside it.
  • ×Polyglot teams re-implement agent logic per language, and behaviour drifts between the copies.

tokenworm's answer

  • A single ~960KB native binary with zero runtime dependencies — per the README, 8ms cold start and 2.4MB idle.
  • A C ABI at the centre, so any language with FFI drives the same shared library.
  • One Zig core, thin idiomatic SDKs, and portable .tworm sessions — a fix propagates everywhere at once.

One agent core, many surfaces

CLI · C ABI · Python · TypeScript · Go

The C ABI in src/lib/ffi.zig is the load-bearing decision. Every SDK is a thin language binding over the same shared library; the agent loop, the providers, the tools, and the sandbox all live in the native code.

CLI

A single 960KB binary

Install with brew, npm, pip, or `zig build`. The CLI is the same Zig-compiled native binary in every package — no Node runtime, no Python interpreter, no Docker required.

C ABI

libtokenworm.so / .dylib

src/lib/ffi.zig exposes `tokenworm_init`, `tokenworm_run`, `tokenworm_cancel`, and the session functions as a stable C boundary. Any language with FFI can drive the agent.

Python SDK

async iterator over chunks

`Agent(provider="opencode-zen")` and `async for chunk in agent.run(...)`. Wraps libtokenworm; the agent loop, providers, and tools all live in the native binary.

TypeScript SDK

idiomatic for-await stream

`new Agent({ provider })` with the same `agent.run()` shape. Sessions exported from one SDK resume in another — the .tworm format is the portable contract.

Go SDK

cgo-linked native runtime

`tokenworm.NewAgent(Options{...})` returns outputs synchronously. The Go binding is intentionally thin; the heavy lifting stays in the Zig core.

Sessions (.tworm)

binary, portable, fast to parse

The README documents .tworm sessions as 5x smaller and 20x faster to parse than JSONL. O(1) offset table for random message access. Export from CLI, resume in Python.

Install

Four package managers, one binary

brew, npm, pip, and `go get` all resolve to the same Zig-compiled native binary. Or build from source with Zig 0.16 — `zig build -Doptimize=ReleaseSmall` produces the 960KB executable.

~ install
# macOS / Linux
brew install tokenworm

# npm
npm install -g tokenworm

# pip
pip install tokenworm

# Go SDK
go get github.com/tokenworm/tokenworm-go

# Build from source (requires Zig 0.16)
zig build -Doptimize=ReleaseSmall

Quickstart

One-shot or REPL

Set an API key for any of the five providers and ask. The agent loop, the tool dispatch, and the sandbox are already wired up.

~ tokenworm
# Pick a provider
export OPENCODE_ZEN_API_KEY="your-key"

# One-shot
tokenworm "what does src/core/agent.zig do?"

# Switch provider at runtime
tokenworm --provider anthropic "refactor the login flow"

# Portable session
tokenworm --export-session session.tworm "analyze auth"

# Or run the REPL
tokenworm -i

What the agent can do

Six built-in tools, workspace-scoped

All tools are workspace-scoped — they cannot access files outside the project directory. The `bash` tool runs commands in an OS-level sandbox: bubblewrap on Linux (`/usr`, `/lib`, `/etc` read-only; workspace read-write), sandbox-exec on macOS (Seatbelt profile).

read

Read file contents with offset/limit.

write

Create or overwrite files.

edit

Surgical text replacement (unique match required).

bash

Sandboxed shell commands (bwrap on Linux, sandbox-exec on macOS).

grep

Substring search across files with extension filter.

glob

Wildcard pattern file search.

Tool allowlist

Restrict the agent to a subset: Agent(allowed_tools=["read","grep","glob"]) for a read-only agent. The agent's system prompt only mentions the allowed tools.

Context compaction

Auto-trims old messages at the 80% context-window threshold (default), preserves recent messages and tool-call chains, and inserts a compaction marker so the model knows context was trimmed.

Trace export

Capture every agent event for debugging and evaluation with --trace-file trace.json on the CLI or agent.enable_trace() in the SDK.

Five LLM providers

Switch providers at runtime

No code change required. tokenworm --provider ollama on the CLI; agent.switch_provider("anthropic") in the SDK. All providers share the same agent loop, tool dispatch, and session format.

Provider Setup Use case
OpenCode Zen OPENCODE_ZEN_API_KEY Default. Free models, curated for coding agents.
Anthropic Claude ANTHROPIC_API_KEY Best coding performance.
OpenAI OPENAI_API_KEY Broad model selection.
Ollama install ollama Local, private, no API key.
MiniMax MINIMAX_API_KEY OpenAI-compatible alternative.

Architecture

Layered, with the C ABI in the middle

Key patterns from the README: vtable-based runtime polymorphism, a canonical agent while-loop, thread-local context globals, and a C ABI for zero-copy cross-language interop.

┌────────────────────────────────────────────────┐
  CLI (src/cli/)   Python SDK  TS SDK  Go SDK
├────────────────────────────────────────────────┤
          C ABI (src/lib/ffi.zig)
  tokenworm_init / run / cancel / session / free
├────────────────────────────────────────────────┤
  AgentRunner (src/lib/agent_runner.zig)
  Provider → Tools → Conversation → Stats
├────────────────────────────────────────────────┤
  Core: agent.zig  conversation.zig  session.zig
        stats.zig   trace.zig   subagent.zig
├────────────────────────────────────────────────┤
  Providers: anthropic / openai / minimax / ...
├────────────────────────────────────────────────┤
  Tools: read / write / edit / bash / grep / glob
├────────────────────────────────────────────────┤
  Sandbox: bwrap / darwin / allowlist / restricted
└────────────────────────────────────────────────┘

FAQ

Questions before you embed it

+ Do I need Node.js or Python to use tokenworm?

No. The CLI binary is self-contained — it is a single 960KB Zig-compiled executable with no runtime dependencies. The Python, TypeScript, and Go SDKs require their respective runtimes, but the agent core itself is the native binary in every case.

+ What models can I use?

Any provider with an OpenAI-compatible API. Built-in support for Anthropic, OpenAI, Ollama, MiniMax, and OpenCode Zen. OpenCode Zen includes free models such as deepseek-v4-flash-free and big-pickle.

+ Is it safe to let the agent run bash commands?

Yes, by default. All bash commands run in an OS-level sandbox — bubblewrap on Linux, sandbox-exec on macOS. The agent cannot access files outside the workspace, and network access is configurable. `--no-sandbox` disables it entirely if you need to.

+ Can I use tokenworm in CI/CD?

Yes. The 8ms cold start and 960KB binary size make it well suited to CI runners — no `npm install` or `pip install` of a hundred megabytes of dependencies, no Docker pull. The .tworm session format is designed to be exported from a CI step and resumed elsewhere.

+ How does session portability work?

Sessions use a custom binary format (.tworm) that includes conversation history, provider metadata, timestamps, token counts, and workspace file snapshots. Per the README, the format is 5x smaller and 20x faster to parse than JSONL and supports random message access through an O(1) offset table. Sessions exported from one SDK resume in another.

+ How does it compare to Claude Agent SDK or OpenAI Agents SDK?

tokenworm ships as a native binary with no runtime dependency, while both alternatives require Node.js or Python. The README reports an 8ms cold start vs ~480-520ms for the alternatives, 2.4MB idle memory vs ~38-45MB, OS-native sandboxing vs none / container-based, and multi-provider support vs one provider each. See /compare/ for the full per-row breakdown.

+ Is it open source?

Yes — MIT-licensed. Source lives at github.com/neul-labs/tokenworm.

Explore the docs

Everything, one level down

Read deeper into any part of tokenworm — the full feature set, the C ABI architecture, the five providers, worked use cases, the glossary, and the long-form blog.

Features

The full feature set: native binary & performance, six tools, five providers, C ABI + SDKs, hooks/skills/MCP, sandboxing, and .tworm sessions.

How it works

The C ABI architecture end to end: surface → ffi.zig → AgentRunner loop → provider → workspace-scoped tools → OS-native sandbox → .tworm session.

Quickstart

Install, set a provider key, and run your first task from the CLI or the Python SDK — one-shot, REPL, runtime provider switch, portable session export.

Providers

The five LLM providers — OpenCode Zen, Anthropic, OpenAI, Ollama, MiniMax — with env vars and how runtime switching works.

Use cases

Three worked walkthroughs: embed an agent in a native app via the C ABI, a coding agent in CI, and one agent core across Python, TS, and Go.

Compare

README-grounded, per-row comparisons with the Claude Agent SDK and the OpenAI Agents SDK — every row sourced from the published vs-table.

Glossary

Plain-language definitions: native binary, C ABI, FFI, agent loop, MCP, SKILL.md, lifecycle hooks, sandboxing, .tworm session, cold start.

FAQ

Grounded answers on why Zig, binary size, the providers and tools, sandbox safety, MCP and skills, session portability, and the MIT license.

Blog

Long-form notes on native-binary AI agents: the 960KB deployment story, the C ABI as the universal SDK boundary, and the systems-language shift.

About

Design rationale: why a systems language, what the C ABI buys, the three architectural commitments, and what is in and out of scope.

An agent core small enough to embed anywhere.

MIT-licensed, 960KB native binary, C ABI for any-language interop, multi-provider, OS-native sandbox. The systems-language bet, made concretely.