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
├── 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§ 01Start here
Where to go next.
Documentation
File format
Security model
Specification 1.0
SDK and CLI
idop validate, inspect and pack, built on the reader’s core.
API
Examples
Write with AI
Changelog
§ 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
{
"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
<!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
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
# 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
§ 04The Runtime API
Everything a document can ask of its reader.
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.