Rabbithole

Every click goes deeper.

Rabbithole is an open-source Rust webserver that generates entire websites on the fly using LLMs. You give it a single seed prompt. When someone visits a URL, the model generates the HTML from scratch — along with a set of links to new pages, each with their own generation prompts. Those pages are generated on demand when clicked. Those pages generate more pages. It is, charitably, the least efficient way to build a website ever devised, and it works surprisingly well, modulo the moments when it does not. The site you are reading was generated by Rabbithole itself, which is either a proof of concept or a cautionary tale about unsupervised AI. Possibly both.

Source code: github.com/ajbt200128/rabbithole  —  Live demo: isarabbithole.com

Note: This page — and every page on this site — was generated by Rabbithole on first visit and permanently cached. Open your browser's developer console (F12) to see generation metadata: prompt, depth, token count, cost, and timing.

How it works

  1. Write a seed prompt. Describe your homepage in a sentence or a paragraph. Pass it via --seed "..." or point to a file with --seed-file prompt.txt.
  2. Start the server. Run cargo run -- --seed "...". The server starts on port 8080 by default. Set your ANTHROPIC_API_KEY first. Consider --max-cost unless you enjoy surprise API bills.
  3. Click and explore. Visit http://localhost:8080/. The model generates your homepage and a set of linked subpages, each with its own prompt. Click a link — that page generates on demand. Click another. Each page goes one level deeper, up to the configurable depth limit (default: 5). Pages are cached permanently after first generation.

Features

  • Streaming SSE — real-time generation progress logs with token throughput and timing
  • Two storage backends — in-memory (default) or SQLite (--db path.db) for persistence across restarts
  • Web tools (on by default) — server-side web_search and web_fetch so the model can look up real content and hotlink real images; disable with --no-web-tools
  • Retry logic — retries up to 3 times if the model returns something that doesn't parse as HTML (this happens more often than you'd hope)
  • Debug console — every generated page logs prompt, depth, token count, cost, API rounds, and generation time to the browser devtools (F12)
  • Cost tracking & budget cap — atomic cost counters; use --max-cost <dollars> to halt generation once exceeded. Strongly recommended.
  • Depth limiting — configurable recursion cap (default 5); pages at the limit generate content but produce no new links
  • Fly.io deployment — Dockerfile, fly.toml, and litefs.yml included for SQLite replication via LiteFS
  • CI/CD — GitHub Actions for build/test/clippy/fmt, cross-compiled releases (Linux/macOS, amd64/arm64), and auto-deploy to Fly.io
  • No frontend frameworks — all generated HTML is fully self-contained; no external CSS or JS dependencies

Quick start

# Prerequisites: Rust toolchain installed
git clone https://github.com/ajbt200128/rabbithole
cd rabbithole

# Set your Anthropic API key
export ANTHROPIC_API_KEY=sk-ant-...

# Run with a seed prompt (set a budget cap — seriously)
cargo run -- --seed "A homepage about space exploration" --max-cost 2.00

# Or use a seed file
cargo run -- --seed-file my-prompt.txt --max-cost 2.00

# With SQLite persistence (survives restarts)
cargo run -- --seed "..." --db site.db --max-cost 2.00

# Custom port, model, and depth limit
cargo run -- --seed "..." --port 3000 --model claude-sonnet-4-5 --depth-limit 3

Pricing (Anthropic API)

ModelInput (per M tokens)Output (per M tokens)
claude-opus-4-5$15.00$75.00
claude-sonnet-4-5$3.00$15.00
claude-haiku-4-5$0.80$4.00

Each page view that hits an uncached URL triggers one (or more, if web tools are used) API call. On a busy site with web tools enabled, costs accumulate quickly. Set --max-cost to a sensible limit before exposing the server publicly.

Tech stack

Documentation

  • Getting Started — installation, first run, seed files, SQLite, budget setup
  • Architecture — Store trait, SSE parser, tool use loop, depth tracking, loading page, cost tracker
  • Configuration Reference — all CLI flags and environment variables
  • Web Tools — web_search, web_fetch, tool use loop, performance considerations
  • Deployment — Fly.io, LiteFS, Dockerfile, GitHub Actions auto-deploy
  • Examples — seed prompts and the sites they generate
  • About — the story, the absurdity, and why this exists
  • GitHub — source code, issues, releases

Contributing

Bug reports, pull requests, and suggestions are welcome at github.com/ajbt200128/rabbithole. CI runs on every push: cargo build, cargo test, cargo clippy, and cargo fmt --check. Tagged releases are cross-compiled and published as GitHub Releases for Linux and macOS on amd64 and arm64.