Wardian docs

How Wardian works

Wardian is a small web server that runs on your computer, and a page in your browser that shows its apps. The server keeps the apps and their data. The browser runs them, each one sealed.

The parts#

TermMeaning
hostThe Wardian server and its main page.
packageOne folder that the host shows as one entry in its app list. The folder name is the app's name.
module appA package whose main part is app.wasm, a WebAssembly file.
pageAn HTML page in a package, shown as the app's interface.
suiteA package with a suite.json: several small suite apps on one screen.
kernelThe host page that runs a suite and passes messages between its apps.
frameThe sandboxed browser frame that one page or one suite app runs in.
capabilityA named thing an app may use, such as storage or db. An app gets only what it declares.
channelA named line between two separate packages. You allow each one.

One folder, one app#

A package is a folder you can read. Nothing is hidden in a database or a build server.

loan-planner/
  suite.json            the parts and their contracts
  apps/inputs/app.js    one part's code
  apps/inputs/view.html one part's markup
  shared/format.js      code every part gets its own copy of
  engine.wasm           the WebAssembly the engine part loads
  ui/                   the components, copied in

You can zip it, mail it, commit it or put it on Google Drive. wardian check reads the folder and tells you what is wrong without running it.

Sealed by the browser, not by trust#

Wardian does not ask apps to behave. It asks the browser to make misbehaving impossible.

Three routes stay open in both: a pop-up after a click, navigating the frame away, and WebRTC. A content policy cannot close them, and a test proves they are still open, so the docs stay honest. See Security model.

So an app you did not write, or one Claude wrote a minute ago, can do only what its frame allows and what its contract declares. Security model lists every rule.

The kernel and the contract#

In a suite, each app states what it does in suite.json:

{ "name": "chart", "slot": "main",
  "listens": ["plan:ready"], "needs": ["engine.curve"] }
FieldMeans
emitstopics this app may send
listenstopics this app may receive
providesmethods other apps may call on this app
needsmethods this app may call, as "app.method"
capscapabilities, such as storage or db
channelschannels to other packages (format 2)

The kernel enforces this copy. A message on a topic the app did not declare is refused. A call to a method the app does not need is refused. Each refusal is a fault, and faults show at the bottom of the suite page.

Think of the kernel as a post office in a town where nobody may visit anybody. Every letter goes through the counter. The clerk checks that the sender may send that kind of letter and that the receiver signed up for it. Then the clerk makes a copy and delivers the copy. Nobody ever holds another person's original.

That copying matters. Every message and every call result is copied (structured clone). No two apps ever share an object, so one app cannot reach into another through a shared reference.

Topics and methods#

There are two ways for suite apps to work together.

Where things live#

ThingKept in
The appsthe working folder, DATA_DIR/apps
Each app's versionsDATA_DIR/history/<app>/
Layouts, storage data, latest channel messagesDATA_DIR/state/
Each app's database (db)DATA_DIR/db/<app>.sqlite
Your permission answersDATA_DIR/grants.json
Keys for Claude, Splunk and DriveDATA_DIR, readable by their owner only, never sent to the browser

The full list is in Settings and environment.

Format versions#

app.json and suite.json may state a "format". Format 1 is the base. Format 2 adds channels between packages. A host never runs a package whose format is newer than it knows; it says "Update Wardian" in the app list instead. Within one format, changes only add things.

This page is docs/site/concepts.md in the repository. Something wrong or missing? Change that file.