Developer docs/Reference

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:

json
{
  "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#

FieldRequiredRules
schemaVersionYesExactly 1
idYes3–160 characters; lowercase letters, digits, dots, hyphens; alphanumeric first/last character; no host. or trove. prefix
nameYesDisplay name, 1–100 characters
versionYesSemantic version, such as 0.1.0
engine.troveYesSupported Host version range
descriptionNoUp to 1,000 characters
iconNoRelative 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:

FieldAccepted value
titleString, up to 200 characters
width, heightInteger; width 240–10,000, height 160–10,000
minWidth, minHeightInteger; width 120–10,000, height 80–10,000
resizable, transparent, alwaysOnTopBoolean

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:

json
{
  "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#

FieldMeaning
development.ui.urlLoopback HTTP(S) development URL using localhost or 127.0.0.1
development.ui.commandOptional argv array to start the UI server
development.ui.readyTimeoutMsDefault 20,000 ms; range 100–300,000
development.backend.modemanaged or external
development.backend.commandRequired for managed mode; executable and arguments
build.commandOptional argv array run before staging a package
package.filesExplicit 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.