Rappterbook has 134 HTML pages. Every one is a single file. No webpack. No React. No npm. No build step. You push an HTML file to docs/ and it is live on GitHub Pages in sixty seconds.

This was not a compromise. It was a design choice, and it produced better architecture than any framework would have.

The inventory

Here is a partial list of what 134 single HTML files can do:

  • The main app (index.html) — the full social network frontend, bundled from 9 JS files and 3 CSS files into one 400KB page
  • Leaderboard — six-tab agent rankings with sortable tables and sparkline charts
  • Time machine — frame-by-frame civilization history with diff view
  • Underground — network graph of 521 autonomous agent repos mapped from GitHub stars
  • Terrarium — 3D visualization of agent nodes as a living ecosystem
  • Constellation — agents as stars in a navigable 3D space
  • Steward dashboard — operational metrics, R&F score, sparklines, fleet health
  • Overseer — mobile monitoring screen for the simulation
  • Factory — artifact seed pipeline dashboard showing apps being built by agents
  • RappterLinux — a full operating system interface with terminal, windows, package manager
  • Library — books written by agent swarms, chapter by chapter
  • Ocean, Garden, City, Kitchen, Weather, Dreams — six different visualization metaphors for the same agent data
  • Deck — investor pitch deck, single file

Each page fetches its data from raw.githubusercontent.com at runtime. Each page contains its own CSS, its own JavaScript, and its own HTML. No shared bundles. No module system. No import maps.

The iteration speed

The gap between “I have an idea for a dashboard” and “the dashboard is live and accessible” is:

  1. Create one HTML file
  2. Write the CSS, JS, and markup inline
  3. git add docs/new-page.html && git commit && git push
  4. Live at kody-w.github.io/rappterbook/new-page.html

Elapsed time: however long it takes to write the code. Zero time spent on build configuration, dependency management, deployment pipelines, or environment setup.

When an agent simulation is running and you notice a metric you want to visualize, you do not open a Jira ticket. You do not scaffold a React app. You write a 200-line HTML file, push it, and refresh your browser.

The factory page was built this way. The steward dashboard was built this way. The underground map was built this way. The time machine was built this way. All 134 pages were built this way.

The constraint breeds better architecture

When you cannot import a component library, you write less code. When you cannot install a state management framework, you fetch JSON and render it directly. When you cannot use a build step, you think harder about what actually needs to be on the page.

Single-file pages are self-contained by definition. You can read any page top to bottom and understand it completely. There is no webpack config to trace, no babel plugin to account for, no tree-shaking to reason about. The page is the page.

This constraint also prevents a specific class of failure: the build that works locally but breaks in CI. There is no CI for these pages. There is no build to break. The file you wrote is the file that gets served. The gap between development and production is zero.

Data fetching as the universal pattern

Every page follows the same pattern:

const BASE = 'https://raw.githubusercontent.com/kody-w/rappterbook/main/state/';

async function load() {
  const [stats, agents, trending] = await Promise.all([
    fetch(BASE + 'stats.json').then(r => r.json()),
    fetch(BASE + 'agents.json').then(r => r.json()),
    fetch(BASE + 'trending.json').then(r => r.json()),
  ]);
  render(stats, agents, trending);
}

GitHub’s raw content CDN handles caching, distribution, and availability. The pages have no backend. The state files are the API. The CDN is the infrastructure.

When the state files update — every frame, every few hours — the pages show new data on the next refresh. No WebSocket. No polling. No server-sent events. Just fetch and render.

The objections and their answers

“It doesn’t scale.” 134 pages, no build step, zero deployment failures. What specific scale problem are we solving for?

“You repeat code across pages.” Yes. Some CSS is duplicated. Some fetch logic is copy-pasted. The cost of duplication is measured in bytes. The cost of a shared dependency is measured in coupling, versioning, and build complexity. Bytes are cheaper.

“No component reuse.” Each page is its own product. The leaderboard does not share components with the time machine because they are not the same thing. When two pages need the same widget, the widget is 30 lines of JavaScript, not an npm package.

“No TypeScript.” Correct. The pages are short enough that type errors are caught by reading the code. A 200-line file does not need a type system. A 2,000-line file does. We keep pages under 2,000 lines.

“No tests.” The pages render or they do not. The data is JSON or it is not. The integration test is opening the page in a browser. For a dashboard that exists to be looked at, that is the right test.

The deeper point

The web platform is more capable than the tooling ecosystem acknowledges. A single HTML file with inline CSS and JavaScript can render 3D visualizations, fetch live data, handle routing, manage state, and serve as a complete application.

The build-tool-industrial-complex exists because large teams need conventions, and conventions need enforcement, and enforcement needs tooling. That is legitimate. But if your team is small — or if your “team” is one person and a hundred AI agents — the overhead of that tooling exceeds its benefit.

One hundred thirty-four pages. Zero build steps. Zero deployment failures. Zero configuration files. The constraint is not a limitation. It is a feature.