Developers

Build with IDOP: web code, a manifest, a contract.

An IDOP document is HTML, CSS and JavaScript in a validated package, with a small Runtime API for storage and permissioned network access. Here is everything you need to write one — or to build a reader.

counter.idop
counter.idop
├── mimetype          application/vnd.idop+zip
├── idop.json         the manifest
├── code/
│   ├── index.html    entry point
│   └── app.js
└── storage/
    └── count.json    written by the reader on Save

§ 02A complete document

Four files. One of them is the manifest.

This is the counter from Annex C of the specification: a button whose count is saved inside the file. It is valid as written.

idop.json

idop.json
{
  "format": "https://idoplabs.com/ns/idop/package",
  "formatVersion": "1.0",
  "runtimeApiVersion": "1.0",
  "entryPoint": "code/index.html",
  "application": { "id": "com.example.counter", "version": "1.0.0", "title": "Counter" },
  "document": {
    "id": "4df56319-e383-4ae8-a519-faa7f4866f90",
    "revisionId": "2e43a209-0a66-4f54-b545-dae25d3b89d0",
    "parentRevisionId": null,
    "createdAt": "2026-10-01T00:00:00Z",
    "modifiedAt": "2026-10-01T00:00:00Z"
  },
  "state": { "schemaVersion": "1.0.0" },
  "requiredFeatures": ["idop.core-storage-v1"],
  "optionalFeatures": [],
  "requiredCapabilities": [],
  "optionalCapabilities": [],
  "environmentBindings": [],
  "credentialBindings": [],
  "extensions": {}
}

index.html

code/index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Counter</title>
    <script type="module" src="app.js"></script>
  </head>
  <body><button id="add">0</button></body>
</html>

app.js

code/app.js
const button = document.querySelector('#add');
let count = 0;
try {
  count = JSON.parse((await idop.storage.read('count.json')).text).count;
} catch (error) {
  if (error.code !== 'IDOP-STORAGE-NOT-FOUND') throw error;
}
button.textContent = String(count);
button.addEventListener('click', async () => {
  count += 1;
  button.textContent = String(count);
  await idop.storage.write('count.json', JSON.stringify({ count }));
});

Validate

terminal
# Would a reader accept it?
idop validate counter/

# What would it ask for?
idop inspect counter.idop

# Pack a directory into a deterministic package
idop pack counter/ --output counter.idop

§ 03Architecture

One core, wherever IDOP runs.

The rules of the format are implemented once, in Rust, and compiled to WebAssembly for the browser and to native code for the command line.

Web

IDOP Cloud reader

Browser shell, sandbox frames, consent prompts

Command line

idop tool

validate · inspect · pack

AI assistants

MCP connector

Validates what an assistant writes before it is saved

Reference core · Rust

One implementation of the rules

  • Independent ZIP parser and limits
  • Path, manifest and executable-boundary checks
  • Storage overlay, revisions, Runtime API dispatch
  • Stable error codes

WebAssemblyNative

"Valid here" means "opens there": the validator and the reader share one core.

§ 04The Runtime API

Everything a document can ask of its reader.

globalThis.idop
idop.runtime.getInfo()
idop.storage.read(path)            idop.storage.write(path, text)
idop.storage.delete(path)          idop.storage.list()
idop.storage.transaction(operations)
idop.network.request({ capability, url, method, headers, body })
idop.env.get(id)
idop.ui.requestSave()              idop.ui.requestConfiguration()
idop.host.getInputFile()           idop.host.putOutputFile(bytes)

There is no fetch: network access is a capability the user grants, to exact origins. Secrets are added by the reader and never reach the document. Errors carry stable codes — branch on error.code.

§ 05Source and contributions

Open specification. Source release planned.

The specification text is published under CC BY 4.0, and the schemas are free to use. The reference implementation — core, reader and command-line tool — is not yet public; we intend to publish it, and will announce it in the changelog.

Questions and proposals about the format: spec@idoplabs.com. Everything else for developers: developers@idoplabs.com.

Write your first document.

Follow the getting-started guide, or give our authoring prompt to an AI model and validate what it writes.