Manifest reference
Define identity, UI, Backend, service dependencies, and package contents in curio.json.
Verified September 11, 2026
On this page
A complete UI manifest#
Put curio.json at the project root. The following matches the Web template’s output paths:
{
"schemaVersion": 1,
"id": "dev.example.notes",
"name": "Notes",
"description": "A small desktop notebook.",
"version": "0.1.0",
"engine": { "trove": ">=0.1.0 <1.0.0" },
"ui": {
"entry": "dist/ui/index.html",
"window": { "title": "Notes", "width": 900, "height": 640 }
},
"development": {
"ui": { "url": "http://127.0.0.1:0", "command": ["npm", "run", "dev"] }
},
"build": { "command": ["npm", "run", "build"] },
"package": { "files": ["dist/ui"] }
}
The port-zero configuration requires the dev server to read TROVE_DEV_PORT. Run trove curio check after editing. The Manifest JSON Schema is available for editor integration; CLI semantic checks are still required.
Identity and compatibility#
| Field | Required | Rules |
|---|---|---|
schemaVersion | Yes | Exactly 1 |
id | Yes | 3–160 characters; lowercase letters, digits, dots, hyphens; alphanumeric first/last character; no host. or trove. prefix |
name | Yes | Display name, 1–100 characters |
version | Yes | Semantic version, such as 0.1.0 |
engine.trove | Yes | Supported Host version range |
description | No | Up to 1,000 characters |
icon | No | Relative packaged image path; include the file in package contents |
A manifest must contain ui, backend, or both. Curio version, service version, and schema/protocol version are separate values. Changing the Curio ID changes its identity, including its storage namespace.
UI and window#
ui.entry is required when ui exists. It points to a packaged HTML file, relative to the Curio root. Optional ui.window fields include:
| Field | Accepted value |
|---|---|
title | String, up to 200 characters |
width, height | Integer; width 240–10,000, height 160–10,000 |
minWidth, minHeight | Integer; width 120–10,000, height 80–10,000 |
resizable, transparent, alwaysOnTop | Boolean |
Paths must remain within the package after canonical resolution. Absolute paths, parent-directory escapes, and escaping symlinks are not valid packaged entries.
Backend lifecycle#
This fragment requires a real executable at backend/notes:
{
"backend": {
"entry": "backend/notes",
"args": [],
"transport": "unix",
"lifecycle": "on-demand",
"startWithUi": true,
"startupTimeoutMs": 10000,
"shutdownGraceMs": 2000,
"idleTimeoutMs": 0
}
}
entry, transport, and lifecycle are required. Transport is unix. on-demand starts when needed; closing the Curio UI stops its on-demand Backend and child processes. app-start starts with Host and may remain running after the UI closes. startWithUi defaults to false.
Startup timeout defaults to 10,000 ms (100–300,000 allowed). Shutdown grace defaults to 2,000 ms (0–60,000). Idle timeout defaults to 0 (0–86,400,000). args is a string array; optional env contains named string values. Session credentials are supplied by Host, not hard-coded in this file. See Backend integration.
Services and contracts#
services.provides contains { id, version, contract }. Every provided service requires a Backend and must use the Curio ID as its namespace prefix. contract is a relative JSON file whose service/version must match the declaration.
services.requires contains { id, version, optional? }. Here, version is a supported range and optional defaults to false. An optional dependency does not install or implement the service; your UI must handle its absence. See service examples.
Development and packaging#
| Field | Meaning |
|---|---|
development.ui.url | Loopback HTTP(S) development URL using localhost or 127.0.0.1 |
development.ui.command | Optional argv array to start the UI server |
development.ui.readyTimeoutMs | Default 20,000 ms; range 100–300,000 |
development.backend.mode | managed or external |
development.backend.command | Required for managed mode; executable and arguments |
build.command | Optional argv array run before staging a package |
package.files | Explicit relative files/directories; not glob patterns |
Commands are arrays, not implicit shell strings. Use ["/bin/sh", "build.sh"] if a build needs shell behavior. Development, build, and package configuration is removed from the published manifest, without rewriting the source file.
Unknown manifest properties are rejected. Schema validation cannot prove that a compiled entry exists or is executable; pack performs that check on staged production files. See distribution.