Kimo
Docs
v1.0
Changeloggetkimo.design
Docs
v1.0
Agents & MCP

The .kimo model

A document is one JSON object. Its nodes member is a flat table: id → node. Each node names its parent (an id, or null at the top level). There is no nested children array. Siblings are ordered by an internal key, and you only ever deal with an index.

2 min read
·
Kimo 1.0 · format 1.0
On this page6 sections
  1. Ids
  2. Node types
  3. Common fields
  4. Pages
  5. Defaults and nulls
  6. Features
JSON
{ "type": "frame", "name": "Card", "w": 320, "h": {"mode": "fit"},
"fill": "#FFFFFF", "radius": 12,
"layout": {"dir": "column", "gap": 8, "pad": 16} }

Ids

  • Ids are 6–24 letters/digits (Hq3Lm9aZ1x). Kimo mints them. You name new nodes with key and refer to them as @key within the same call. created[] in the result maps keys to ids.
  • Names (name) are labels only. Never use them to reference anything.
  • Inside an instance, descendants are addressed by IdPath: instanceId plus the path inside its component, for example Inst000001/Label00001 (see components).

Node types

typeKey fields
framecontainer. w,h (Size), fill, stroke, radius, clip, layout, effects
groupcontainer with no box of its own; bounds = children
rect, ellipse, polygonw,h required; fill, stroke, radius / sides / innerRadius
pathd (SVG path data), viewBox, w,h, fillRule
textcontent (string), grow, style (see text)
iconset (lucide, feather, phosphor, material-*), icon (glyph name), w,h, color
instanceof (component id), props, args, overrides (see components)
note, promptcanvas annotations: content
frame
Key fields container. w,h (Size), fill, stroke, radius, clip, layout, effects
group
Key fields container with no box of its own; bounds = children
rect, ellipse, polygon
Key fields w,h required; fill, stroke, radius / sides / innerRadius
path
Key fields d (SVG path data), viewBox, w,h, fillRule
text
Key fields content (string), grow, style (see text)
icon
Key fields set (lucide, feather, phosphor, material-*), icon (glyph name), w,h, color
instance
Key fields of (component id), props, args, overrides (see components)
note, prompt
Key fields canvas annotations: content

Only frame and group hold children. Images are fill: {kind:"image", src:"./assets/…"} on a rect or frame, imported with kimo_import / kimo_assets. There is no image node.

Common fields

  • Placement: x, y (relative to the parent; ignored inside a layout frame unless position: "absolute"), name, locked, theme (pins, see tokens).
  • Look: opacity 0–1, visible, rotation (degrees CCW), blend, flipX/flipY.
  • Paint: a color string #RRGGBB / #RRGGBBAA, {space:"oklch", l, c, h}, a binding {"$ref":"name"}, or {kind:"linear"|"radial"|"angular", stops:[{color, at}]}. A list paints bottom to top. fill: [] means "no paint".
  • Stroke: {paint, width, align:"inside"|"center"|"outside", dash?}; width can be per side {t, r, b, l}.
  • Effects: [{kind:"shadow", x, y, blur, color, spread?, inner?}, {kind:"blur", radius}, {kind:"backdrop-blur", radius}].

Pages

A document can have several pages (kimo_get_state → pages[]). A page is not a node: a top-level node's page field names its page, and a top-level node without page is on the first page. Children are on their top-level ancestor's page; never set page below the top level. Read one page with kimo_query {select: {topLevel: true, page: "<id>"}}; create, rename, move and delete pages with the page op (see ops). Polygons take star: {ratio} (inner / outer radius, default 0.38) to draw stars; an image fill with fit: "crop" shows its crop region.

Defaults and nulls

A field equal to its default is the same as the field being absent, and Kimo omits it when it saves. The format never stores null. To clear a field, use update {unset:["field"]} (a null in update.set is read the same way; a null field in a new node body is dropped).

Features

Some constructs need a feature listed in the document's features: layout/wrap, layout/stretch-baseline, size/min-max, text/runs, tokens/composite. kimo_apply_ops declares them for you in the same edit that writes the gated value (for example layout.align: "stretch"), so you never set features yourself.

The normative JSON Schema is the resource kimo://schema/1.0.