Open-source project
antithesishq/bombadil avatar
antithesishq/bombadil

Bombadil fuzzes browser and terminal UIs instead of asserting one scripted path

Property-based testing for web and terminal UIs

1,592 stars69 forksRustMIT

At a glance

What is it?
Bombadil is a Rust property-based testing toolkit that drives web pages and terminal programs with generated input sequences and checks correctness properties over the traces, from Antithesis. It is young, pre-1.0, and split across nineteen workspace crates that reveal how much of the browser stack it reimplements.
Who is it for?
Bombadil earns its place when your UI has states no script enumerates, particularly a terminal program or a browser app with session state, because it is aimed squarely at the bugs a fixed Playwright script cannot reach. Hold off if you need a stable API or a 1.0 promise, since the workspace version is 0.7.8 and the crates are still moving, and note that the LTL checker implies some learning curve before a property failure means anything to your team.
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 last received commits 1 day ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • antithesishq/bombadil1,592 ★ · +44
Star history
Repository2026-10-162026-11-07
antithesishq/bombadil1.5k1.6k

44 Stars in the last 22 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Properties over traces, not assertions over one path

The unit of work is a property, evaluated over a trace of generated inputs rather than an assertion at a fixed point. Bombadil's description says it autonomously explores and validates correctness properties, and the `bombadil-ltl` crate in the workspace gives that a concrete meaning: linear temporal logic properties over the sequence of states, which is a way of saying "this must always hold", "this must eventually happen", and "after A, B" without pinning them to specific interaction steps.

That is the substantive difference from a scripted browser test. A Playwright script encodes the paths its author imagined; anything off those paths is untested. A property-based run generates input sequences and keeps the ones that violate a stated invariant, so a path nobody wrote down can still produce a failure with the input sequence attached.

The Rust side of the project is unusually large for a toolkit at version 0.7.8. The workspace declares nineteen members, and the names describe the architecture more clearly than any prose would. There is `antithesis-fuzzer`, the engine. There is `bombadil`, `bombadil-browser`, `bombadil-browser-keys`, `bombadil-terminal` and `bombadil-inspect` for the two targets. `bombadil-cli`, `bombadil-schema`, `bombadil-ltl` and a `cli-reference` crate handle the command line, the specification schema and documentation that stays in step with it.

The remaining members are infrastructure the project had to write rather than depend on: `cdp` with sub-crates for types, `pdl` and `protocol`, plus `small-string`, `stdx` and `stdx-derive`. The cdp crate is a Chrome DevTools Protocol implementation, which is the clearest single fact about the scope here.

Nineteen crates, including a CDP implementation and a JS engine

The workspace dependency list explains where the effort went, and it is worth reading as a statement of scope.

For the browser target, the project pulls in `oxc` with its codegen, semantic and transformer features, along with `oxc_resolver` 11.19.1, `oxc_codegen`, `oxc_str` and `oxc_traverse` at 0.125.0. That is a full JavaScript and TypeScript toolchain used to instrument the code under test. Alongside it sit `boa_engine` 0.22.0 as an embedded JavaScript engine, `html5ever` 0.39 for HTML parsing, `gloo-net`, `gloo-timers` and `gloo-console` for the WebAssembly side, and `js-sys` bindings.

For the terminal target, the dependencies are `portable-pty` 0.9.0 for spawning programs under a pseudo-terminal, `mio` for polling the file descriptors that come back, `libghostty-vt` 0.2.2 for terminal emulation, and `ctrlc` for signal handling. Driving a TUI means emulating a terminal and reading its screen, not spawning a shell and capturing stdout.

Shared machinery includes `rand` 0.10.1 with `rand_chacha`, `rand_distr` and `rand_regex` for input generation, `insta` for snapshot testing, `hotpath` 0.16.1 for profiling, `axum` 0.8.8, `reqwest` 0.13.4, `clap` 4.5.46, and the `antithesis_sdk` at 0.2.9 with its `rand_v0_10` and `full` features.

The last dependency deserves a note. The SDK is the bridge to Antithesis, the commercial service that builds the project, so the toolkit is designed to run both standalone and inside that environment. The README states both modes explicitly: local developer environment, CI, and inside Antithesis.

Specifications are TypeScript, and the examples name their targets

The example files are the clearest window into how a specification is written, because the file names state what is being tested. `examples/` holds `btop.ts`, `cat.ts`, `nano.ts`, `tb.ts`, `tetris.ts`, `text_editor.ts` and `wikipedia.ts`, alongside a `tsconfig.json`, plus `claude.ts`.

Six of those seven are terminal programs: btop, cat, nano, tb, tetris and a text editor. `wikipedia.ts` is the browser case. That split reflects where the project is strongest, and it is worth noticing for a reason beyond curiosity. Terminal UIs have no accessibility tree and no DOM, so there is no cheap way to assert on their state, and a script that asserts on output text breaks on every reflow. The `libghostty-vt` and `portable-pty` dependencies exist precisely to solve that, and a target like tetris or nano is close to a worst case for conventional UI testing.

`claude.ts` suggests the author uses the toolkit against a terminal-based assistant as well.

On getting started, the README routes you to the Bombadil Manual, with an installation page and a specification-language page carrying examples. It gives no install command of its own, so take the installation steps from that manual rather than assuming a package name or a CLI flag. Development setup is described separately in `docs/development/contributing.md`, and the repository includes `flake.nix` and `flake.lock` for a Nix-based environment, plus an `.envrc` for direnv.

What will not work well

Three limitations deserve stating plainly, none of them hidden in the repository.

First, the API surface is pre-1.0 and moving. The workspace version is 0.7.8 on Rust edition 2024, and three releases landed inside three weeks in September and October 2026: v0.7.6 on 2026-09-18, v0.7.7 on 2026-09-22 and v0.7.8 on 2026-10-01. A `CHANGELOG.md` exists, which is the right thing to read before every upgrade. Pin the version in CI.

Second, this is not a test framework in the usual sense. It finds inputs that violate a property you state; it does not assert a business requirement you have not written down. If your team has no practice of writing invariants over state sequences, the hard part is authoring properties, not running the fuzzer. The `bombadil-ltl` crate raises the ceiling on what you can express and the floor on what you have to learn.

Third, the browser target carries the weight of that hand-written `cdp` stack. Two ways to be wrong at once, a DevTools Protocol version that moves with Chromium and a property layer above it, means browser-target issues may take more digging than terminal ones.

A practical fourth constraint: this is not a smoke test substitute. A fuzzer run is unbounded in time and non-deterministic in what it finds, so it complements a fast deterministic suite rather than replacing it.

Against Playwright, against a terminal fuzzer like tmux-pilot

The alternative for web UIs is Playwright, and the comparison is about intent rather than capability.

Playwright is a driver: you write steps, it executes them, and a failure is reproducible because the input was written down. That property is exactly what Bombadil gives up. A property-based run produces a failing input sequence rather than a fixed script, which is harder to fold into a regression suite but far better at surfacing a state machine bug on page nine of a checkout flow that nobody thought to script.

Teams usually end up with both: Playwright for the paths that must keep working on every commit, Bombadil for the paths nobody enumerated.

For terminal programs the comparison is different, because there is no dominant tool. Writing assertions against raw stdout means fighting carriage returns, cursor moves, colours and box drawing. The usual workaround is tmux, run the program in a pane, capture the pane, grep the text. That approach is what Bombadil's terminal crates replace: a real pseudo-terminal via `portable-pty`, a real terminal emulator via `libghostty-vt`, so you assert on the rendered screen rather than on the byte stream. The difference is that the emulation is part of the harness instead of something you bolted on, which is why terminal targets dominate the example list.

Neither approach replaces the other for CI cost either. A fuzzer needs a time budget, and that budget competes with your test suite for the same runners.

MIT, weekly cadence, and a contribution policy worth reading

The licence file is `LICENCE` in the repository root and the project is MIT, so the code can be used, modified and shipped inside a product with the notice retained. Nothing in the repository indicates a separate licence for the specification language or for the examples.

Maintenance is active and visible. The repository is not archived, the last push was on 2026-10-16, one day before today, and the release cadence in September and October 2026 was roughly weekly. A version this young with this cadence should be treated as fast-moving.

The contribution guidance is more specific than most. The README says the project prefers GitHub issues and Discord discussions over drive-by pull requests, and asks contributors to read a Gen AI policy document at `docs/development/gen-ai-policy.md` before using LLMs in contributions. For an open source project in 2026, having that policy written down is unusual enough to mention, and it means the terms are set by the project rather than left to interpretation.

The README also carries a recruiting link, since Antithesis is a company building this. That does not affect the licence or the roadmap you can rely on, but it does explain the pace and the fact that the toolkit is the free surface of a commercial offering.

Editorial conclusion

Bombadil earns its place when your UI has states no script enumerates, particularly a terminal program or a browser app with session state, because it is aimed squarely at the bugs a fixed Playwright script cannot reach. Hold off if you need a stable API or a 1.0 promise, since the workspace version is 0.7.8 and the crates are still moving, and note that the LTL checker implies some learning curve before a property failure means anything to your team. Verify first that your target is reachable, by running one of the `examples/` specifications such as `wikipedia.ts` or `tetris.ts` against the pinned toolchain before writing your own.

Frequently asked questions

What is Bombadil used for?

It performs property-based testing for web and terminal user interfaces. It generates input sequences, explores the application, and checks correctness properties over the resulting traces to surface bugs that a fixed script would not reach.

How do I install Bombadil?

The README does not give an install command and instead links an installation page in the Bombadil Manual at antithesishq.github.io/bombadil. Take the steps from that manual. The repository includes flake.nix and an .envrc for a Nix-based development environment.

What are specifications written in?

The examples in `examples/` are TypeScript files, including btop.ts, cat.ts, nano.ts, tetris.ts, text_editor.ts and wikipedia.ts, with a tsconfig.json alongside them. The specification language itself is documented on the manual's specification-language page.

Does Bombadil test terminal programs as well as web apps?

Yes. The workspace includes a bombadil-terminal crate, and the dependencies show portable-pty for spawning programs and libghostty-vt for terminal emulation. Most of the shipped examples, including nano.ts and tetris.ts, are terminal programs.

How does Bombadil differ from Playwright?

Playwright executes steps you wrote down, so failures are reproducible but untested paths stay untested. Bombadil generates inputs and validates invariants, which finds unenumerated states at the cost of reproducibility, so the two are usually run together rather than swapped.

What licence is Bombadil released under?

MIT, with the licence text in the LICENCE file at the repository root. The workspace version is 0.7.8, so pin the version in CI and read CHANGELOG.md before upgrading.

Official sources

  1. antithesishq/bombadil on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/antithesishq-bombadil.svg)](https://hysenlabs.com/projects/antithesishq-bombadil)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/antithesishq-bombadil.svg)](https://hysenlabs.com/projects/antithesishq-bombadil)

Was this useful?