# 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`](https://idoplabs.com/downloads/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.

```bash
node idop.mjs --version
```

## 2. Start a document

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

This creates:

```text
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`](https://idoplabs.com/spec/idop/1.0/idop-runtime.d.ts)
and put `/// <reference path="./idop-runtime.d.ts" />` at the top of a file.

## 4. Check and build

```bash
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](https://idoplabs.com/spec/idop/1.0/errors/). `pack` is
deterministic: the same folder always gives the same bytes.

## 5. Open it

Drag `counter.idop` onto [IDOP Cloud](https://cloud.idoplabs.com), or open it
with any IDOP Reader. Click around, save, close, open again: the count is still
there, because it is in the file.

```bash
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:

```json
"optionalCapabilities": [{
  "id": "weather", "type": "network",
  "origins": ["https://api.example.com"], "methods": ["GET"],
  "purpose": "Show today's forecast"
}]
```

```js
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](https://idoplabs.com/developers/ai-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

- [IDOP Format Specification 1.0](https://idoplabs.com/spec/idop/1.0/) — the rules
- [Conformance suite](https://idoplabs.com/spec/idop/1.0/conformance/) — test your own Reader or tool
- [Manifest schema](https://idoplabs.com/spec/idop/1.0/schemas/manifest.json)
