Available

Ten minutes, Node.js 20 or later, no installation.

Markdown

Your first IDOP document, from scratch

An IDOP document is a folder of ordinary web files — HTML, CSS, JavaScript, optionally WebAssembly — plus one manifest, packed into a single .idop file. Anyone can open it in an IDOP Reader, and the data it saves travels inside the file. This guide takes ten minutes and needs only Node.js 20 or later.

1. Get the tool

Download idop.mjs — one file, no installation, no dependencies, no network. It carries the same validator as IDOP Cloud, so a file it accepts is a file every conforming Reader accepts.

node idop.mjs --version

2. Start a document

node idop.mjs init counter --title "Counter"

This creates:

counter/
  idop.json          the manifest: who made it and what it needs
  code/index.html    the entry point
  code/style.css
  code/main.js       an ES module; it counts how often the document was opened

idop.json says "auto" where the document’s identity goes. The first pack fills in a document id, a revision id and the dates, and writes them back, so the document keeps the same identity from one build to the next.

3. Write it like a web page

Edit the files as you would a small website, with three differences:

  • The outside world goes through idop. There is no network: fetch reads files from your package (fetch('data.json')), never from the internet. If the document needs an API, declare it as a capability (step 6).
  • State lives in the file. idop.storage.write('notes.json', text) and idop.storage.writeBytes('photo.png', bytes) store data that the Reader writes into the .idop file when the user saves.
  • No inline scripts, no remote URLs, no eval. Put scripts in files; bundle fonts and images.

Everything else works as you expect: ES modules importing each other, CSS, SVG, canvas, <dialog>, WebAssembly (WebAssembly.instantiateStreaming(fetch('engine.wasm'))), and dedicated workers (new Worker('worker.js')). To let the user keep a copy of something, call idop.ui.saveFile({ name, data }); to read one of their files, idop.ui.openFile({ accept: ['.csv'] }); to print, idop.ui.print(). Each of these opens the Reader’s own dialog — the user stays in control.

For editor help, add the types: idop-runtime.d.ts and put /// <reference path="./idop-runtime.d.ts" /> at the top of a file.

4. Check and build

node idop.mjs validate counter
node idop.mjs pack counter -o counter.idop

A refusal names a stable code — look it up in the error registry. pack is deterministic: the same folder always gives the same bytes.

5. Open it

Drag counter.idop onto IDOP Cloud, or open it with any IDOP Reader. Click around, save, close, open again: the count is still there, because it is in the file.

node idop.mjs inspect counter.idop   # what the file declares and asks for
node idop.mjs unpack counter.idop -o counter-copy   # back to a folder

6. When it needs the network

Declare exactly what it needs in idop.json; the Reader asks the user and attaches any key itself — the document never sees it:

"optionalCapabilities": [{
  "id": "weather", "type": "network",
  "origins": ["https://api.example.com"], "methods": ["GET"],
  "purpose": "Show today's forecast"
}]
const { status, body } = await idop.network.request({
  capability: 'weather',
  url: 'https://api.example.com/today',
});

Prefer optionalCapabilities, and make the document useful without them.

7. Let an AI write it

Give any capable model the IDOP builder prompt and describe what you want; paste its files into a folder and run step 4. With an MCP-capable assistant connected to IDOP Cloud, it can create the document in your cloud directly.

Reference