Getting Started

This page walks you through installing Rabbithole, writing your first seed prompt, running the server, and understanding how pages are generated and cached on demand. If you want a deeper understanding of the internals, see the Architecture page.

Prerequisites

Before you begin, make sure you have the following:

Installation

Option A: Install from crates.io

The simplest way to install Rabbithole is via Cargo:

cargo install rabbithole

This downloads, compiles, and installs the rabbithole binary into ~/.cargo/bin/, which should already be on your PATH if you installed Rust via rustup.

Option B: Build from source

git clone https://github.com/ajbt200128/rabbithole
cd rabbithole
cargo build --release

The compiled binary will be at target/release/rabbithole. You can copy it anywhere on your PATH, or invoke it directly:

./target/release/rabbithole --help
Note: On first build, Cargo will download and compile all dependencies. This may take a few minutes. Subsequent builds are incremental and much faster.

Creating Your First Seed Prompt

A seed prompt is a plain text file that describes the homepage of the website you want Rabbithole to generate. The LLM receives this prompt and produces the full HTML for / (the root path). Everything else on the site grows outward from this starting point.

Create a file called prompt.txt:

A homepage for "Solar System Explorer" — an educational website
about the planets, moons, and other bodies of our solar system.
Plain, clean HTML. White background. Blue links. Navigation bar with:
Home | Planets | Moons | Asteroids & Comets | History | About.
Include a brief introduction, a table listing all eight planets with
their distance from the Sun and number of moons, and links to
individual planet pages. Footer with a note that content is
AI-generated for educational purposes.

A good seed prompt describes:

The richer your seed prompt, the more coherent the generated site will be. Because each subsequent page is generated in isolation (with only the prompt Rabbithole writes for it), all style and context must flow from the seed. See Examples for more seed prompt ideas.

Running the Server

export OPENAI_API_KEY="sk-..."          # or whichever provider you use
rabbithole --seed prompt.txt --port 8080

You should see output similar to:

Rabbithole starting up
Seed prompt loaded from: prompt.txt
Database: rabbithole.db (SQLite)
Listening on http://127.0.0.1:8080

Now open http://localhost:8080/ in your browser.

Common flags

FlagDefaultDescription
--seed <file>requiredPath to the seed prompt text file
--port <n>8080TCP port to listen on
--db <path>rabbithole.dbSQLite database file for the page cache
--model <name>gpt-4oLLM model identifier to use for generation
--base-url <url>OpenAI APIOverride the API base URL (for Anthropic, Ollama, etc.)

For the full list of configuration options, see the Configuration reference.

How the First Page Gets Generated

When you visit http://localhost:8080/ for the first time:

  1. Rabbithole checks the SQLite cache for a stored page at path /. Nothing is found.
  2. The server calls the LLM with your seed prompt, asking it to produce a complete HTML document.
  3. The LLM also outputs a ---MAPPINGS--- block: a JSON array of { "url": "/some-path.html", "prompt": "..." } objects — one for each link in the generated page.
  4. Rabbithole parses the HTML and the mappings, stores both in the SQLite database, and serves the HTML response to your browser.
  5. All subsequent requests to / are served directly from the cache — no LLM call is made again for that URL.
Cache is permanent. Once a page is generated, it is cached forever until you manually delete it (or delete rabbithole.db). This means each URL is only one LLM call, no matter how many times it is visited.

How Clicking Links Triggers New Pages

Each link in a generated page points to a local path like /planets/mars.html. When you click such a link:

  1. Your browser requests that path from Rabbithole.
  2. Rabbithole looks up the path in the mappings table of the SQLite database.
  3. It finds the prompt that was written for that URL during the generation of the page that contains the link. This prompt was authored by the LLM itself — it encodes the site's theme, style, navigation, and the specific content for that sub-page.
  4. Rabbithole calls the LLM with that prompt, generating the new page.
  5. The result is cached and served.

This means the site grows lazily — only pages that are actually visited are ever generated. A site can have thousands of potential URLs, but only the ones a visitor clicks will trigger LLM calls.

If a visitor navigates directly to a URL that has no mapping (i.e., it was never linked from any generated page), Rabbithole returns a 404. The only way to reach a page is to follow the link graph from the seed.

Watching It Grow

Try this workflow after starting Rabbithole with a seed prompt:

  1. Visit the homepage. Wait a moment for the first generation (typically 5–20 seconds depending on model and prompt length).
  2. Click any link on the generated page. Watch a new page appear.
  3. Continue navigating. Each new path you visit causes a new LLM generation.
  4. Return to a page you have already visited — it loads instantly from cache.
  5. Open rabbithole.db with any SQLite viewer (e.g. sqlite3 rabbithole.db ".tables") to inspect what has been stored.

Recommended First Seed Prompts

If you are not sure where to start, here are some seed prompts that produce interesting results:

More complete examples with full seed prompts are available on the Examples page.

Next Steps