Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Document Structure

A dashboard document is a single JSON object validated against schemas/dashboard.schema.json ($id: https://lattice.dev/schemas/dashboard/1.0.0). It has two required members and two optional ones:

{
  "manifest": { ... },
  "root": { ... },
  "variables": [ ... ],
  "theme": { ... },
  "connections": [ ... ]
}

No other top-level keys are allowed (additionalProperties: false).

manifest (required)

Document-level metadata.

FieldRequiredNotes
formatVersionyesSemver of the document format, e.g. "1.0.0" (pattern ^\d+\.\d+\.\d+$).
idyesStable machine-readable identifier for the dashboard.
titleyesHuman-readable title.
descriptionnoLonger-form description.
authornoAuthor or owner.

The manifest is passed through verbatim into the resolved tree.

root (required)

The root item instance. Every item in a dashboard — including the root — is an instance node of this shape:

{
  "$ref": "https://lattice.dev/schemas/items/container/1.0.0",
  "id": "root",
  "config": { ... },
  "placement": { ... },
  "variables": [ ... ],
  "children": [ ... ]
}
FieldRequiredNotes
$refyesURI of the item-type schema this node instantiates.
idnoInstance-local identifier, unique within the document.
confignoPer-instance configuration; its shape is defined by the referenced item type and is opaque at the document level.
placementnoLayout hints interpreted by the parent container’s grid.
variablesnoVariable declarations scoped to this node and its descendants (meaningful on containers).
childrennoChild instances.

The root is conventionally a container, and under the tree grammar (below) it must be a positional region type.

The tree grammar

children is structurally permitted on any instance by the schema, but where each kind of node may actually appear is governed by the tree grammar, a fail-fast resolver pass over the assembled tree. In short: the root holds only positional regions; a container holds nested regions or block wrappers (a bare content leaf must be wrapped in a block); a variable-box holds variable widgets directly; a block wraps exactly one content leaf and never re-wraps a block; and a region carries no theme. The full set of rules, the block wrapper, the positional marker, and the grammar error codes are documented on the Blocks & the Tree Grammar page.

The container is a positional region: it arranges its children on a relative-weight grid (config.grid) — unitless column and row track weights plus a gap — and children place themselves with explicit, 1-indexed placement coordinates (colStart, colSpan, rowStart, rowSpan, each defaulting to 1). The resolver normalizes the tracks to fractions summing to 1 per axis and validates each placement against the grid bounds (LAYOUT_PLACEMENT_INVALID, LAYOUT_PLACEMENT_OUT_OF_BOUNDS). No CSS keywords or absolute units appear anywhere — the grid is renderer-agnostic.

variables (optional)

An array of document-scope variable declarations. They are visible to every node unless shadowed by a same-named declaration on a descendant container.

theme (optional)

The document-scope default theme — the document’s base presentation choices, drawn from the shared semantic-token vocabulary. It is the default layer; per-block theme overrides are emitted side by side and never merged into it. See Theme.

connections (optional)

An array of document-scoped connection instances — data sources that items bind to by id. Connections are declared and validated only; they are never dialed.

The resolved tree

lattice resolve emits a resolved tree whose shape is a stable, JSON-tagged contract (additive changes only). Its top-level members are:

{
  "manifest": { ... },
  "root": { ... resolved instance ... },
  "defaultTheme": { ... },
  "connections": [ ... resolved connections ... ]
}

defaultTheme is the document’s default theme (the default layer only — per-block overrides ride on their own block nodes, never merged here); omitted when the document declares no theme.

A resolved instance records more than the source node, because resolution has already validated and computed several things:

FieldMeaning
idCopied from the source instance (omitted if none).
typeThe resolved type identity: the raw ref, the canonical id, and the parsed name/version.
containertrue when the resolved type is a container. Surfaced so consumers need not re-derive it.
configThe interpolated, schema-validated config (variable references already substituted).
placementVerbatim placement hints.
layoutFor containers only: the normalized grid (fractional track sizes + each child’s validated placement).
childrenResolved child instances, in document order.
varEnvThe variable environment visible at this node (see Variables).
bindingFor bound items only: the resolved data binding (see Connections).

Because the resolved tree is fully validated, downstream consumers (a renderer, the serve inspector, a future dependency tracker) may assume every node is structurally valid and type-checked.