Profile
Back to NewsBack
GitHub Trending 12 min
Reader Mode
richiemcilroy/Tov: A TypeScript-shaped language built for coding agents. It compiles to small, fast native binaries.

richiemcilroy/Tov: A TypeScript-shaped language built for coding agents. It compiles to small, fast native binaries.

11 hours ago

Tov

A programming language for coding agents. Tov reads like TypeScript, so your agent can already write it, and when the agent gets something wrong the compiler hands back the edit that fixes it. What comes out is one native binary, faster than Rust's on our benchmarks and in a fraction of the memory Bun uses (the numbers).

To start, paste the prompt on tov.sh into your agent. It installs Tov and reads tov.sh/llms.txt, which is the language written up for agents. To install it yourself, run curl -fsSL https://tov.sh/install.sh | sh. That builds Tov from source, so it needs git and a C compiler.

Code that looks like TypeScript behaves like TypeScript, or doesn't compile. Bun's and Node's APIs are there (Bun.serve, fetch, node:fs, async/await), and so are npm packages: an app written for Bun runs on Tov unchanged. What Tov leaves out is what makes programs hard to follow. There's no any, null or ==, a call that can fail is marked try, integer overflow stops the program, and arrays and records are values, so nothing changes behind the agent's back. Errors have a code, and where the fix is clear, tov check --json returns the exact edit and says whether it's safe to apply as it is.

A program compiles in about 42 ms (Rust: 98). A web server serves 242,000 requests a second on one core in 1.6 MB of memory, against 216,000 in 4.4 MB for Rust's axum and 111,000 in 17 MB for Bun (macOS, M4 Max).

The landing page, site/, is a Tov program: cd site && tov dev.

Status

Tov is early, and it changes every day. It's at version 0.0.1.

| Works today | Not yet | |---|---| | Command-line programs and web servers | Windows | | Records, unions, generics, classes, interfaces, checked errors | A package manager of its own (install packages with npm or Bun) | | async/await, promises, timers | Tuples, enums and some other TypeScript features (spec) | | fetch() over HTTP and HTTPS, with streaming, compression and proxies | TLS sockets (tls.connect) and worker threads for npm packages | | Bun's server API (Bun.serve, routes, Request, Response) | Promise.allSettled/any, .then/.catch | | A Node-style standard library (fs, path, process) | | | npm packages, including Node-API native addons, and Bun apps | | | macOS (arm64) and Linux | |

How an agent works with Tov

An agent writes TypeScript:

Bun.serve({
  port: 3000,
  fetch(req) {
    const url = new URL(req.url)
    return new Response(Hello from ${url.pathname})
  },
})

Tov says what's wrong and how to fix it, for people:

error[T0831] hello.tov:4:17: new URL can throw TypeError; mark the call try to pass the error on, or catch it
    4 |     const url = new URL(req.url)
  why: errors are values in Tov: every call that can fail is marked, so control flow is visible
  or: wrap it in try { ... } catch (e) { ... }
  fix[safe]: pass it on: try new URL(req.url)

and for tools (tov check --json, trimmed):

{
  "code": "T0831",
  "file": "hello.tov",
  "start": { "line": 4, "col": 17 },
  "message": "new URL can throw TypeError; mark the call try to pass the error on, or catch it",
  "fixes": [{
    "label": "pass it on: try new URL(req.url)",
    "applicability": "safe",
    "edits": [{ "start": { "line": 4, "col": 17 }, "end": { "line": 4, "col": 17 }, "text": "try " }]
  }]
}

A safe fix can be applied as it is, and tov explain T0831 describes any code. With the fix applied, tov build hello.tov writes a 152 KB binary.

To get an agent started, give it tov.sh/llms.txt. It's docs/spec.md, which lists only what differs from TypeScript, with a short guide to the commands in front.

Example

type Shape =
  | { kind: "circle", r: f64 }
  | { kind: "rect", w: f64, h: f64 }

function area(s: Shape): f64 { switch (s.kind) { case "circle": return Math.PI s.r s.r case "rect": return s.w * s.h } }

function main() { const shapes: Shape[] = [{ kind: "circle", r: 1 }, { kind: "rect", w: 2, h: 3 }] for (const s of shapes) { console.log(${s.kind}: ${area(s).toFixed(2)}) } }

test("rect area", () => { expect(area({ kind: "rect", w: 2, h: 3 })).toBe(6) })

Getting started

You need Rust 1.95 or newer (to build the compiler) and a C compiler (clang or gcc).

git clone https://github.com/richiemcilroy/Tov
cd Tov && cargo install --path crates/tov   # puts tov in ~/.cargo/bin

tov run examples/shapes # build and run main() tov --watch server.tov # rebuild and restart when a source file changes tov dev # run package.json's "dev" script, as bun dev does tov test examples # run every test(...) tov build examples/shapes -o app # write a native binary tov check src/ # type-check only (--json for tools) tov explain T0001 # what an error code means

The command line works like Bun's: tov runs a program and passes it the arguments after the file name, tov Chat with me