Kimo
Docs
v1.0
Changeloggetkimo.design
Docs
v1.0
File format spec
§6

Sizing and layout

On this page3 sections
  1. 6.1 Size
  2. 6.2 Layout (frames)
  3. 6.3 Radius
Status
Stable (format version 1.0.0, frozen 2026-10). Backward compatible within 1.x (§16.4). Supersedes the draft v0.1, kept as a historical record; 0.1 files open through the 0.1 → 1.0 migration (§16.2).
Schema
https://getkimo.design/schema/kimo-1.0.json (JSON Schema draft 2020-12), generated into packages/core-schema/schema/kimo-1.0.schema.json. The 0.1 schema stays published at …/kimo-0.1.json (schema/kimo-0.1.schema.json, frozen).
Reference
@kimo/core-schema (packages/core-schema). Where this document and the implementation disagree, that is a bug in one of them; file an issue.
Plan of record
docs/teardown.md §10. Every place where this spec resolves an ambiguity in, or deviates from, that section is listed in §20.
License
MIT

6.1 Size

A Size is one of:

  • a number ≥ 0 or a number binding — a fixed size in px;
  • { "mode": "fit", "fallback"?: n, "min"?: n, "max"?: n } — size to the content. A frame fits its children (with layout: the flex content size; without: their bounding box). When there is nothing to fit (no children), fallback is used, else 0;
  • { "mode": "fill", "fallback"?: n, "weight"?: n, "min"?: n, "max"?: n } — take the space of a parent with layout along the relevant axis (main axis: shared by weight, default 1; cross axis: stretch). On the main axis the space left after the parent's padding, gaps and non-fill siblings is shared by weight from a zero basis: the fill items' content size is ignored (CSS flex: <weight> 1 0, as pen.dev and Figma; two fill texts in a row get equal widths whatever their length). The shares are outer sizes: padding (and includeStroke insets) does not add to a fill item's share, so a padded and an unpadded fill sibling end equal; padding larger than the share is a floor. This needs a definite main size: when the parent fits that axis (a fill parent is definite only if its own parent is, along the same chain) or wraps (layout.wrap), the content size is the basis and only the free space beyond it is shared (CSS flex: <weight> 1 auto), so fill items do not collapse in a hug parent and lines still break (§20 row 34). When the parent has no layout or the node is absolute, fallback is used, else the content size.

min / max clamp the result and need feature size/min-max; fill items that violate them are frozen at the bound and the others share what is left (CSS "resolving flexible lengths"). Exporters map fallback to min-width/min-height or document it as ignored.

A frame whose size on an axis is fit and whose flowing children all fill that axis is circular (lint FIT_ALL_FILL); readers SHOULD resolve it by sizing those children as fit on that axis.

Text sizes follow grow (§8.1). An instance has no size fields; it takes its component root's size unless props overrides w/h.

Keywords:
MUST
MUST NOT
SHOULD
MAY
set in small mono caps wherever they are normative

6.2 Layout (frames)

FieldTypeDefaultMeaning
dir"row" | "column"— (required)Main axis.
gapNum0Space between children on the main axis (may be negative).
crossGapNum0Space between wrapped lines. Feature layout/wrap.
padNum | [v, h] | [t, r, b, l]0Padding; entries are non-negative.
justifystart center end between around evenly"start"Main-axis distribution.
alignstart center end stretch baseline"start"Cross-axis alignment. stretch and baseline need feature layout/stretch-baseline.
wrapbooleanfalseWrap onto several lines. Feature layout/wrap.
includeStrokebooleanfalseInclude the frame's stroke width in its padding box.
dir
Type "row" | "column"
Default — (required)
Meaning Main axis.
gap
Type Num
Default 0
Meaning Space between children on the main axis (may be negative).
crossGap
Type Num
Default 0
Meaning Space between wrapped lines. Feature layout/wrap.
pad
Type Num | [v, h] | [t, r, b, l]
Default 0
Meaning Padding; entries are non-negative.
justify
Type start center end between around evenly
Default "start"
Meaning Main-axis distribution.
align
Type start center end stretch baseline
Default "start"
Meaning Cross-axis alignment. stretch and baseline need feature layout/stretch-baseline.
wrap
Type boolean
Default false
Meaning Wrap onto several lines. Feature layout/wrap.
includeStroke
Type boolean
Default false
Meaning Include the frame's stroke width in its padding box.

Absent layout means children are placed by x/y. Children with position: "absolute" or visible: false do not take part in the flow. A property equal to its default never requires its feature (e.g. wrap: false).

6.3 Radius

radius is one Num ≥ 0 or [topLeft, topRight, bottomRight, bottomLeft].