Back to updates
New releaseJul 26, 2026

kuri v0.4.14

Browser automation, web crawling, and iOS + Android device control for AI agents. Zig-native, token-efficient CDP snapshots, HAR recording, native adb wire-protocol client, and a standalone fetcher.

Share

Kuri

Kuri 🌰

Stable release License Zig node_modules status

Install

curl -fsSL https://kuri.trilok.ai/download | sh

macOS arm64/x86_64 and Linux x86_64/arm64. Single binary, no runtime deps.

Direct downloads: macOS arm64 · macOS x86_64 · Linux x86_64 · Linux arm64


Browser automation & web crawling for AI agents. Written in Zig. Zero Node.js.

CDP automation · A11y snapshots · HAR recording · Standalone fetcher · Interactive terminal browser · Agentic CLI · Security testing · iOS + Android device control

Quick Start · Benchmarks · kuri-agent · Security Testing · API · Skills · Changelog

Why teams switch to Kuri: current Apple Silicon ReleaseFast builds stay sub-2 MB per binary, and a fresh Google Flights rerun on 2026-04-23 measured 3,392 tokens for a full kuri-agent loop (go→snap→click→snap→eval). Cross-tool deltas should be rerun in the same environment before quoting a percentage.


Why Kuri Wins for Agents

Most browser tooling was built for QA engineers. Kuri is built for agent loops: read the page, keep token cost low, act on stable refs, and move on.

  • 135 HTTP endpoints — full parity with agent-browser and browser-use, from React inspection to Core Web Vitals.
  • 7-12% fewer tokens than agent-browser on real pages thanks to @eN ref format and zero-prefix rendering.
  • 44x lighter observations with /page/state (48 tokens) vs full snapshot (2,124 tokens) for the same Google Flights page.
  • Batch execution — POST /batch sends N commands in one HTTP call, eliminating N-1 round-trips and N-1 LLM turns.
  • React-compatible — trusted CDP mouse events and per-character key events fire React 18/19 onClick and onChange.

Snapshot tokens: Google Flights SIN → TPE

Fresh rerun on 2026-05-24 in this workspace, measured with wc -c and chars/4 approximation.

Tool / ModeChars~TokensNote
kuri snap (full)8,4992,124All nodes + interactive refs
kuri snap (interactive only)~3,000~750Best for agent loops
kuri /page/state19048Lightweight observation (url, title, scroll%, counts)
agent-browser snap (estimated)~9,183~2,295[ref=e0] format overhead

Token efficiency: kuri vs agent-browser

Pagekuri tokensagent-browser tokensSavings
example.com4035-13% (trivial page, agent-browser skips root)
Hacker News386~44012% fewer
Google Flights SIN→TPE2,124~2,2957% fewer

The savings come from kuri's compact format:

  • @e0 refs (3 chars) vs [ref=e0] (9 chars)
  • No - prefix per line (saves 2 chars × line count)
  • Same indentation, same node filtering

Full workflow cost: go → snap → click → snap → eval

ToolTokens per cycle
kuri-agent~3,400
With /page/state instead of second snap~1,700
With POST /batch (all in one call)~1,700 (same tokens, 1 HTTP call instead of 5)

kuri vs libretto

libretto (Playwright + Node) is the closest competitor on per-step token cost. Measured head-to-head on 2026-07-04 — same Chrome, same tab, real tiktoken o200k_base counts (full methodology and reproduction: benchmarks/libretto_comparison.md). The honest split:

AxisWinnerDetail
Latency per callkuri4–117 ms vs 1,344–1,500 ms (13–376× faster — persistent server vs Node-per-command)
Snapshot tokens, typical pagekurisimple 61 vs 151 (2.5×), article 265 vs 363 (1.37×) — tighter grammar
Snapshot tokens, large listsplitkuri default 4,424 vs 813 — kuri emits all 259 refs, libretto truncates by default. With limit=5 kuri renders 555 tokens (1.46× under libretto), 34 refs + … +45 more markers
Trajectory (feed, 9 clicks)kuri, barely898 vs 939 tokens (limit=5 base + diff loop vs exec loop) — parity-to-slight-edge; the morning's 5.1× loss was the untruncated base
Repeat runslibrettocompiles trajectories to a Playwright script → 0-token replays; kuri re-pays the loop every run

What kuri gained from studying libretto (all shipped this release): a diff-first loop (take_snapshot_diff, ~38 tokens/step); an adaptive diff that falls back to a full snapshot with a ! page replaced header on navigation; identity-only removal lines; screenshots written to disk (path returned, bytes never enter context); get_page_state over MCP; and — after rewriting parseA11yNodes as a real DFS tree walk — opt-in list truncation (/snapshot?limit=N, one … +K more line per capped run), scoped re-capture (scope=@ref), and hierarchy indentation, also exposed as uid/limit on MCP take_snapshot. The 9-click feed trajectory that cost 44,285 tokens with naive full re-snapshots costs 898 with a truncated base + diffs — 49× cheaper, and past libretto's 939.

The older tables above use a chars/4 token approximation; the libretto comparison uses real tiktoken counts. Rerun cross-tool numbers in your own environment before quoting a percentage.

Binary size and memory

Measured on Apple M4 Pro, macOS 26.4.1. Current binaries were built with -Doptimize=ReleaseFast.

BinaryCurrent size
kuri1,093,840 B (1.04 MiB)
kuri-agent629,904 B (615 KiB)
kuri-browse1,089,120 B (1.04 MiB)
kuri-fetch2,063,488 B (1.97 MiB)

RSS stayed flat across the Zig 0.16 migration

Measured against the current v0.4.3 ReleaseFast build with /usr/bin/time -l.

Commandv0.4.3 mean max RSS
kuri-fetch --version~2.45 MiB
kuri-browse --version~2.45 MiB
kuri-fetch --quiet --dump markdown http://example.com/~9.17 MiB

The Problem

Every browser automation tool drags in Playwright (~300 MB), a Node.js runtime, and a cascade of npm dependencies. Your AI agent just wants to read a page, click a button, and move on. Kuri is a single Zig binary. Four modes, zero runtime:

kuri           →  CDP server (Chrome automation, a11y snapshots, HAR)
kuri-fetch     →  standalone fetcher (no Chrome, QuickJS for JS, ~2 MB)
kuri-browse    →  interactive terminal browser (navigate, follow links, search)
kuri-agent     →  agentic CLI (scriptable Chrome automation + security testing)

📦 Installation

One-line install (macOS / Linux)

curl -fsSL https://raw.githubusercontent.com/justrach/kuri/release-channel/stable/install.sh | sh

Categories