An open file format for portable, sandboxed interactive documents. Spec + reference implementation. Like PDF — but interactive.
Quick start · How it works · Security model · Spec · Examples · Installers · Contributing
PDFs made documents portable.
Capsules make interactive documents portable.
.capsule is an open format for interactive documents. A capsule is a self-contained zip archive with a manifest, content, and integrity metadata. It opens offline, runs inside a strict sandbox, and declares every capability it wants up front. You see the contract before you click Run.
Most software sharing collapses into one of two bad shapes: a static file that cannot do much, or an installable app that gets too much trust. Capsule sits between them.
- One file to share. Email it, drop it in chat, stick it on a flash drive.
- Offline. No server required after download.
- Inspectable before it runs. The runtime shows what it can and cannot do, every time.
- Sandboxed by default. No ambient access to your files, clipboard, network, shell, environment, or tokens.
- Explicit capabilities. Network access must be allowlisted per host in the manifest. The user confirms each grant.
- Forkable with provenance. Content is hashed canonically; authors can sign.
Opening a capsule is inert. Capabilities are always denied by default and mediated by the host runtime. Capsules cannot:
- read arbitrary files
- read the clipboard
- run shell commands
- contact the network unless the manifest allowlists specific hosts
- read environment variables, cookies, tokens, or
$HOME - update themselves silently
- access camera, microphone, or location
Full details:
docs/SECURITY-MODEL.md.
Requirements: Node 20+, pnpm 9+
# install + build
pnpm install
pnpm -r build
# easiest path: make a capsule from a starter template
node packages/capsule-cli/bin/capsule.mjs make hello --template checklist
# or package an existing folder with index.html
node packages/capsule-cli/bin/capsule.mjs make ./my-site --name "My Site"
# inspect it (no execution)
node packages/capsule-cli/bin/capsule.mjs inspect hello.capsule
# run it in a sandboxed window
node packages/capsule-cli/bin/capsule.mjs run hello.capsuleTip: add a shell alias so you can drop the prefix:
alias capsule="node $(pwd)/packages/capsule-cli/bin/capsule.mjs"
The v0.1.x release artifacts are not yet code-signed (the signing
pipeline is wired up in release.yml but
the Apple Developer / Authenticode secrets aren't populated). Until they
are, your OS will flag the downloaded installers. One-time workarounds:
When you drag Capsule.app from the DMG to /Applications, the OS tags it
with a quarantine flag. Double-clicking it then fails silently — no
error dialog, no logs, just nothing.
Strip the quarantine and re-register the app:
sudo xattr -dr com.apple.quarantine /Applications/Capsule.app
/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister \
-f /Applications/Capsule.appThen double-click any .capsule file — the sandbox window opens.
Alternatively, right-click Capsule.app → Open → Open once. After
that macOS remembers your decision.
SmartScreen shows a blue "Windows protected your PC" dialog on first run. Click More info → Run anyway once.
PowerShell may also refuse to run install.ps1 due to the Execution
Policy. Use the bypass flag:
powershell -ExecutionPolicy Bypass -File .\install.ps1No signing friction. Extract the tarball and run sudo ./install.sh.
Once the release is signed (Apple notarization + Authenticode), these
workarounds go away for end users. See docs/RELEASE.md
for how signing is configured.
capsule run starts a short-lived HTTP server bound to 127.0.0.1 on a random port with an unguessable path token, then opens a chromeless browser window with the Open Screen. The capsule HTML loads inside a sandboxed <iframe> with a strict Content-Security-Policy. All capability calls cross a postMessage bridge to the host, which enforces the manifest.
┌───────────────────────────────┐
│ Open Screen (host page) │ ← shows what the capsule can/can't do
│ ┌─────────────────────────┐ │
│ │ Capsule iframe │ │ ← strict CSP, sandboxed
│ │ • no network │ │
│ │ • no shell │ │
│ │ • no ambient access │ │
│ └─────────────────────────┘ │
└───────────────────────────────┘
▲
│ postMessage bridge
▼
┌───────────────────────────────┐
│ Local runtime server │ ← mediates every capability call
│ 127.0.0.1:<random> │
└───────────────────────────────┘
| Package | Purpose |
|---|---|
capsule-core |
Format library: manifest schema, archive reader, path rules, deterministic packer, canonical content hash |
capsule-runtime |
Sandbox host: HTTP server, Open Screen UI, capability bridge, permission prompts, receipts |
capsule-cli |
Author tooling: make, pack, inspect, verify, run, receipts |
The examples/ directory contains reference capsules that exercise the format and capability model. Each is a plain directory you can capsule pack and capsule run.
pocket-notes— polished markdown notepad with live preview, persists drafts viastorage.localoffline-checklist— local-only checklist that usesstorage.localmortgage-calculator— pure-compute capsule, no capabilitiesposter-maker— canvas drawing, no network
The format is documented as a standards draft in docs/. The V1 implementation treats these files as the source of truth:
| Document | Scope |
|---|---|
CAPSULE-1.0-DRAFT.md |
High-level standard |
ARCHIVE-FORMAT.md |
.capsule archive layout |
MANIFEST.md |
capsule.json fields |
MANIFEST-1.0.schema.json |
JSON Schema |
CAPABILITY-MODEL.md |
Permission system |
SECURITY-MODEL.md |
Sandbox and threat model |
SIGNING-AND-INTEGRITY.md |
Hashing, signatures, provenance |
RUNTIME-CONFORMANCE.md |
What a compatible runtime must do |
OS-INTEGRATION.md |
File extension, MIME, icons |
AUTHORING-GUIDE.md |
How to make safe capsules |
RELEASE.md |
How releases are built, signed, and verified |
For most authors, start with capsule make. It creates a template project when the path does not exist, or packages an existing web folder when it does.
capsule make my-checklist --template checklist
capsule make ./dist --name "Interactive Report"
capsule make --list-templatesUse capsule pack when you already have a complete Capsule project with an authored capsule.json and want strict deterministic packaging.
pnpm install
pnpm -r build # build all packages (capsule-core first via workspace deps)
pnpm -r test # vitest across all packages
pnpm -r typecheck # tsc --noEmit across all packagesTests, type checks, and builds all run in CI on Ubuntu and macOS against Node 20 and 22. See .github/workflows/ci.yml.
V1 reference implementation. The format spec is a draft, not frozen. Breaking changes are possible before 1.0. See milestones for current progress.
Contributions are welcome — bugs, features, examples, and spec feedback. See CONTRIBUTING.md for the workflow.
MIT. Capsule is intended to be implementable by more than one runtime — the format, manifest, and behavior are documented independently of this implementation.
If Capsule is useful to you, consider starring the repo to help others find it.