> ## Documentation Index
> Fetch the complete documentation index at: https://iii.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Registry

> Registry publishing, versioning, and the bundle artifact contract for iii workers.

The iii registry at [workers.iii.dev](https://workers.iii.dev/) serves the artifacts of published
workers. A worker published as a native binary, an OCI image, or a bundle archive is installable by
name from any iii project. For the consuming side, see
[Worker Registry](https://iii.dev/docs/using-iii/workers-registry.md).

## Publish a worker

Publishing a worker uploads its artifact to the registry and records its semver version. The
registry then resolves the worker by name for every project that requests it.

## Version your worker

Workers in the registry follow semver. Patch bumps for bug fixes, minor bumps for additive
capability, major bumps for breaking changes to function signatures or `args_format`.

## Build binary artifacts for multiple platforms

Binary workers can publish artifacts for multiple platform targets in a single registry entry (macOS
arm64/x64, Linux arm64/x64/armv7, Windows arm64/x64/x86). One published version covers every
supported host without separate publications per platform.

## Bundle archives

A bundle worker publishes a single `tar.gz` archive that contains the worker's bundled source plus
an `iii.worker.yaml` manifest at the archive root.

Use a bundle when:

* You ship a pre-built JavaScript bundle or a packaged Python worker, and you do not want to publish
  a Docker image.
* You want artifacts measured in KB, not MB. Only the bundled source travels in the archive. The
  runtime ships with the engine-allowlisted base image (`docker.io/iiidev/node:latest` or
  `docker.io/iiidev/python:latest`).

> [!NOTE]
>
> A bundle archive is not a binary artifact and not an OCI image. The archive carries source plus a
> manifest, and the engine runs that source inside the sandbox VM.

### Registry response shape

```json theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
{
  "type": "bundle",
  "name": "my-worker",
  "version": "1.2.0",
  "archive_url": "https://cdn.workers.iii.dev/my-worker/1.2.0/bundle.tar.gz",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
```

The engine GETs `archive_url`, streams the bytes through a SHA-256 hasher, and compares the result
against `sha256`. A mismatch, an HTTP error, a content type without an `application/` prefix, or a
download above 64 MiB aborts the install with `W142`, and the engine deletes the downloaded archive.

### Archive layout

The archive root MUST contain `iii.worker.yaml`.

```text theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
my-worker-1.2.0.tar.gz
├── iii.worker.yaml
├── bundle.js
└── assets/
    └── logo.png
```

### Manifest contract (`iii.worker.yaml`)

Every sample below is a complete manifest.

#### Rejected fields

`scripts.setup` is rejected with `W180 BundleManifestRejected`. Provisioning belongs in the base
image. Pre-build the bundle and ship it ready to run.

```yaml theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
name: my-worker
scripts:
  setup: npm install
  start: node bundle.js
```

#### Required fields

* `name`: must equal the registry package name without an `@version` suffix. For example, use
  `my-worker` for both `worker=my-worker` and `worker=my-worker@1.2.0`.
* `scripts.start`: a non-empty shell string. The engine `exec`s this inside the sandbox VM.

```yaml theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
name: my-worker
scripts:
  start: node bundle.js
```

#### Optional fields

* `scripts.install`: a shell string. The engine runs it inside the sandbox VM one time, before it
  starts the worker. Python bundles use it for a pip bootstrap that cannot be vendored into the
  archive.
* `runtime.base_image`: an OCI image reference. The engine accepts any reference with alphanumerics
  and the characters `._-/:@+`, for example `docker.io/iiidev/python:latest`. A malformed reference
  is rejected with `W180`.
* `resources.cpus`: defaults to `2`, capped at `4`.
* `resources.memory`: defaults to `2048` MiB, capped at `4096` MiB.

```yaml theme={"theme":{"light":"catppuccin-latte","dark":"dark-plus"}}
name: my-worker
runtime:
  base_image: docker.io/iiidev/python:latest
scripts:
  start: python -m my_worker
  install: pip install -r requirements.txt
resources:
  cpus: 4
  memory: 4096
```

A resource value above the cap is clamped to the cap, and the install prints a
`W182 BundleResourceClamped` warning. A resource value is never rejected for its size. Keys outside
the subset above are ignored: the bundle install does not reject unknown keys.

> [!NOTE]
>
> The bundle manifest is a subset of the [worker manifest](https://iii.dev/docs/creating-workers/worker-manifest.md). It rejects
> `scripts.setup` and ignores every key outside the classes above.

### Archive safety policy

Bundle archives are extracted with tighter limits than OCI layers:

| Limit | Value |
| - | - |
| Total uncompressed size | 64 MiB |
| Largest single file | 32 MiB |
| Maximum entry count | 1024 |
| Maximum directory depth | 16 |
| Manifest size | 64 KiB |
| Allowed tar entry types | Regular, Directory |

Archives that contain symlinks, hard links, character devices, FIFOs, absolute paths, or paths with
`..` components are rejected with `W181 BundleArchiveUnsafe`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.