Tov: a TypeScript-shaped language that hands agents a fix
A TypeScript-shaped language built for coding agents. It compiles to small, fast native binaries.
At a glance
- What is it?
- Tov is a version 0.0.1 programming language for coding agents: it keeps TypeScript syntax, requires every fallible call to be marked, and compiles to a single native binary. The promise is agent-friendly diagnostics, and the cost is a support matrix that leaves out Windows, TLS sockets and promise chaining.
- Who is it for?
- Adopt Tov if you are letting an agent write and repair TypeScript and you want the result as a small native binary, and if your platform is macOS arm64 or Linux and your dependencies stay inside the Bun and Node-API surface. Do not adopt it for Windows, for promise chaining, TLS sockets, worker threads or a package manager of its own, and do not put a critical service on version 0.0.1 without pinning the toolchain.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A language built around the agent in the loop
Tov is a programming language aimed at coding agents rather than at people typing by hand. The premise is that an agent already emits TypeScript, so the syntax carries over unchanged, and that the compiler should be the feedback channel: when the agent gets something wrong, the compiler hands back the edit that fixes it. What comes out is a single native binary. A landing page at tov.sh exists so that an agent can be pointed straight at the language write-up, and the landing page itself is a Tov program.
The scale of the project is worth stating plainly. It is at version 0.0.1, the README says it is early and that it changes every day, and the repository has no GitHub releases at all. The last push was on 2026-10-13. The licence is MIT, the default branch is main, and the implementation is Rust with a JavaScript runtime, laid out as a Cargo workspace whose only member is crates/tov. That combination says pre-1.0 tooling, and the README frames its own support matrix in the same terms, with a table of what works today and what does not.
Checked errors where the compiler proposes the edit
The central mechanism is that a call which can fail must be marked try, or caught, and a function's errors become part of its type. That single rule shapes most of the language, including the diagnostic format. The compiler assigns a code, T0831 in the example below, and where the fix is unambiguous it emits the exact edit and labels it safe to apply:
{
"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 " }]
}]
}For an agent driving a terminal, the JSON form matters more than the prose version. It carries a file, a line and a column, plus an edits array whose text is the literal replacement, so an agent can apply a safe fix without parsing an English sentence. The companion command tov explain T0831 describes any code. That is the loop the project is designed around: write code, compile, read the edit, apply it.
The same strictness shows up elsewhere. There is no any and no null, so a missing value becomes a type error rather than a runtime surprise, and unions of object types must be narrowed before their fields are touched, with a switch required to cover every case.
Value semantics and reference counting instead of a collector
Arrays, records and maps are values in Tov. Assigning one copies it, and the compiler flags the places where TypeScript would have shared the reference instead. To modify a caller's value, a function declares an inout parameter and the caller passes the value by reference.
Memory is handled by reference counting rather than a garbage collector, and the compiler pushes back on the case where reference counting does not work. If instances of a class could reference each other in a cycle, the compiler asks you to mark the back-reference weak, to make it readonly, or to declare a cyclic class, which adds cycle collection for that class alone. The trade-off is real: the type system makes the aliasing question explicit at compile time instead of deferring it to a runtime collector, but a class with cycles now needs a declaration that a TypeScript author would never have had to write, and the cyclic class path adds a runtime cost the other classes do not pay.
Installing the compiler and running the first program
You need Rust to build the compiler and a C compiler, either clang or gcc. The one line installer downloads the install.sh script from tov.sh and pipes it into sh, so it needs git and a C compiler already present:
Building from a checkout is the path most contributors take, and the workspace installs the tov binary into the cargo bin directory:
git clone https://github.com/richiemcilroy/Tov
cd Tov && cargo install --path crates/tov # puts `tov` in ~/.cargo/binThe rest of the command line covers running, watching, testing, building and checking:
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 meansThe examples directory holds calc, captions, inventory and shapes, so there is a real program to start from rather than a hello world. The command line deliberately mirrors Bun's: a bare file name runs a program and passes along the arguments that follow it, a script name runs the matching package.json script with pre and post hooks and the npm_* environment, and the watch flag restarts the process when the entry file or anything it imports changes.
npm packages bundled into the binary and run on JavaScriptCore
Package installation is not Tov's job. There is no package manager of its own, so you install with npm or Bun and then import the package the usual way, and Node-API native addons are supported. At build time the packages are resolved the way Node.js resolves them, with ES modules, TypeScript and JSX converted, then bundled into the binary and executed on JavaScriptCore, the same engine Bun uses. Values that cross that boundary come back with the type Js, which tells the compiler that a JavaScript result has escaped static analysis.
That boundary is where the sharp edges are. The status table in the README lists what is not there yet: Windows, TLS sockets through tls.connect, worker threads for npm packages, Promise.allSettled and any, and the then and catch promise methods. Tuples and enums are missing too, and the spec document is the authority on the gaps. A Bun program built around promise chaining rather than await will not run unchanged, so the compatibility claim holds for await-style code rather than for every program that targets Bun.
The performance figures are the project's own measurements
The README quotes a compile time of about 42 ms against 98 ms for Rust, and a web server that 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, on macOS with an M4 Max. These are figures the maintainers published in the README, not results reproduced here, so treat them as a claim to check on your own hardware and your own workload.
The comparison also explains where Tov sits between the two designs it is measured against. Rust produces native code with no runtime, and the Rust axum server in that measurement uses more memory. Bun runs JavaScript on its own engine, and a server built on it uses more still. Tov compiles the program itself to native code and embeds the JavaScriptCore runtime for the npm packages, which is the compromise these numbers describe. The toolchain is a Cargo workspace on edition 2024 with a single member, crates/tov, and a release profile that keeps line tables only for debug symbols.
Where Tov is the wrong tool today
The support matrix settles most adoptions. Windows is not supported, and the listed platforms are arm64 macOS and Linux. A team shipping desktop software for Windows is out, and so is a team whose dependencies need worker threads, promise chaining, or a TLS socket opened directly.
There is a second class of wrong fit: work that needs the reach of a mature runtime. Tov has no package manager of its own, so every dependency arrives through npm or Bun, and its npm support stops at what JavaScriptCore and Node-API expose. The Rust route to a small, dependency-free binary is the opposite choice, and if a program needs no JavaScript packages at all, compiling to native code with Rust stays the more predictable path.
Third, there is the risk of building on version 0.0.1 with no published releases. The last push was on 2026-10-13 and the README says the project changes every day, which cuts both ways: fixes land quickly, and a build can move under you. The answer is a pin rather than a slogan, and the repository layout already includes a Cargo.lock and a vendor directory, so a fixed dependency tree is available to hold onto.
Editorial conclusion
Adopt Tov if you are letting an agent write and repair TypeScript and you want the result as a small native binary, and if your platform is macOS arm64 or Linux and your dependencies stay inside the Bun and Node-API surface. Do not adopt it for Windows, for promise chaining, TLS sockets, worker threads or a package manager of its own, and do not put a critical service on version 0.0.1 without pinning the toolchain. Before you commit, run tov check on your own code, confirm that the diagnostics your agent consumes look like the JSON edit payload above, and reproduce the compile time and memory figures on your own machine rather than taking the README's numbers as given.
Frequently asked questions
What is Tov and who is it for?
Tov is a programming language for coding agents that reads like TypeScript and compiles to a single native binary, with a compiler that returns the edit that fixes a mistake. It is at version 0.0.1, and the README describes it as early and changing every day.
How do I install Tov?
Run curl -fsSL https://tov.sh/install.sh | sh, which builds Tov from source and therefore needs git and a C compiler. To build from a checkout instead, clone the repository and run cargo install --path crates/tov, which puts the tov binary in the cargo bin directory.
How does Tov handle errors?
Every call that can fail must be marked try or caught, and a function's errors are part of its type. The compiler reports a code such as T0831, and tov check --json returns the exact edit with a safe label when the fix is clear.
Can Tov use npm packages and run Bun apps?
Yes. Packages are installed with npm or Bun, resolved at build time, bundled into the binary and run on JavaScriptCore, and Node-API native addons are supported. Some features are still missing, including TLS sockets, worker threads, Promise.allSettled, any, and the then and catch methods.
Does Tov run on Windows?
No. The status table in the README lists Windows as not yet supported, with macOS arm64 and Linux as the supported platforms.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/richiemcilroy-tov)Was this useful?