khal-app.json at its root. The schema lives in @khal-os/types — this page is a field-by-field reference.
The @khal-os/dev-cli tool validates your manifest at build time; invalid manifests fail CI before they ship.
Top-level fields
Unique pack identifier. Must match the package directory name. Lowercase, dash-separated.
Human-readable pack name shown in the desktop launcher.
Semantic version. Normally kept in sync with
package/package.json.Short description for the marketplace listing.
Author name or organization.
Path to the pack icon, relative to the pack root.
Permission strings the pack requires. Examples:
"nats:publish", "nats:subscribe", "user:read". Permissions are checked by the platform before the frontend loads and before services are started.Frontend package declaration.
Backend configuration. Omit entirely for frontend-only packs.
Environment variables customers configure per install. See Customer install for the customer-side flow.
Optional. If your pack exposes multiple windows or view modes, declare them here with per-view permission and role requirements. Most packs have a single implicit view from
frontend.package.Alternative to
backend for multi-service packs. Each entry declares a named service with optional command, entry, runtime (node or python), health, restart, and ports. See Backend overview.Advanced. Provision a per-user container when the pack is installed. Used for high-isolation packs (e.g., ephemeral workspaces). See the
app-kit/packages/types source for full field shape.Complete example
khal-app.json
For fields this page does not enumerate (e.g.,
views, sandbox, desktop), consult app-kit/packages/types/src/manifest.ts directly. The Zod schema there is the canonical source.What’s next
Example packs
Reference packs grouped by pattern — read the manifest that ships in each.
Anatomy of a pack
How the manifest fits into the rest of the pack structure.