Examples Habit Tracker Kanban Board Leetcode Prep README.txt SandVox Tanks uApp Demo Why Maverick Meerkat?
Joshua Bemenderfer — How this site works?
How this site works?

This site looks like a normal static blog, and that’s exactly what it is when you visit it. But it’s built and hosted in an unusual way: the whole thing — content, builder code, and an AI assistant — lives in one SQLite file, shared like a spreadsheet.

One file, three layers

The archive has two directories, and a file’s location is its meaning:

  • app/ — the site itself: the generated HTML pages, the CSS, the build scripts, vendored libraries.
  • data/content/ — the source of truth: markdown files, page frontmatter, and any .vue components a post uses.

There is no server-side rendering at request time. A build reads data/content/, renders everything, and writes finished HTML into app/. Visitors get plain, crawlable pages with zero required JavaScript.

The build runs in your browser

The builder (js/build.js) is itself just a static file. When the site is opened inside the uapp editor shell, it comes alive and registers a handful of named actions — build_site, build_page, list_pages — that both the admin UI and the AI assistant call. The same code path builds a page whether a human clicks the button or the assistant is asked to.

A build does roughly this:

  1. Read every markdown file under data/content/ and parse its frontmatter into a page graph.
  2. Render markdown to HTML with markdown-it, and scan for custom components.
  3. For pages that use components, compile each Vue SFC (with the real @vue/compiler-sfc) and server-render the island with Vue’s SSR renderer — in the browser.
  4. Wrap the result in the site layout (title, TOC, footer, styles) and write it to app/<slug>/index.html.

Pages that use no components ship zero JavaScript. Pages that do get a small hydration payload so the island becomes interactive after load.

The pages are live when you’re in the editor

This is where it gets fun. The components below are ordinary Vue islands, but when this page runs inside the uapp shell they reach through to the runtime and exercise the same tools the assistant uses. Open this page as a public visitor and they show their static fallbacks instead.

Reading the database directly

uapp.query(sql) runs read-only SQL against the archive. This one counts files and bytes straight out of the sqlar table the site is stored in:

📊 Archive stats appear here when this page is opened inside the uapp editor.

Calling the site’s own actions

uapp.call(name, input) invokes the named actions the builder registers. This one calls list_pages — the exact tool an AI assistant uses to check what’s built:

🗺️ The live site map appears here inside the uapp editor.

Running your own SQL

And because every tool the assistant has is available to the page itself, you can type arbitrary SQL and run it against the archive right here. uapp.query is strictly read-only — the backend rejects anything that mutates:

⌨️ The query console appears here inside the uapp editor.

…and writing to it

uapp.exec(sql, params) performs a real write — it’s logged and replicated to every user’s device. Here’s a two-column guestbook backed by an actual demo_notes table in this site’s database. Leave a note in one editor window and the list updates in the other (the onChange demo below ticks too):

✍️ The guestbook appears here inside the uapp editor.

Who’s asking

Every uapp call is attributed — uapp.user and uapp.device say who and from where:

👤 Attribution info appears here inside the uapp editor.

Reacting to other people’s edits

uapp.onChange(cb) fires whenever any user’s write syncs to your device. Open this page in two editors and rebuild in one:

🔔 Sync events appear here inside the uapp editor.

Staleness is tracked in the archive itself

The admin page (the “Site map” linked in the footer) compares file modification times in the archive: a page is stale when its markdown — or any component it uses — is newer than its output. That’s the whole freshness model; no separate metadata database.

Why bother?

Because the editing loop collapses. Asking an assistant to “make the site dark mode and write a post about it” is one operation on one file: it edits the CSS and the markdown, triggers a build, and the deployed site is the output. Ship the file to a teammate and they have the content and the tooling.

The pages you’re reading right now were produced exactly that way.

Joshua BemenderferHow this site works?Site map