⬡ FRAMEWERK
Core

The document

A Framewerk spec is one JSON document whose optional top-level fields hold screens, components, styles, flows and content.

View as Markdown

The document

A spec is one plain JSON document that describes an application's screens — their layout, styling, interactive state and navigation — designed to be written by hand, generated by an agent, diffed in review, and rendered identically by any conforming renderer.

Everything below is the whole public format. There are no hidden node types and no private extensions.

Examples

The smallest useful spec is one screen with one text node:

The smallest spec
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Hello
Edit the JSON to update the rendered screen.Edits stay in this preview

A document with every top-level section populated:

A document with state and navigation
phone
SPEC.JSON
RENDERED OUTPUTFRAMEWERK RENDERER
Coffee Cart
Toggle oat milk
Order
Edit the JSON to update the rendered screen.Edits stay in this preview

Anatomy

{
  "formatVersion": "1.0",           // the version of the format this document follows
  "drafts":       [ /* string[]     — the draft parts it uses, e.g. "requirements" */ ],
  "project":      { /* ProjectMeta — name, theme, default device/style */ },
  "screens":      [ /* ScreenDef[]   — the screens */ ],
  "components":   { /* Record<string, ComponentDef> — reusable subtrees */ },
  "styles":       [ /* StyleDef[]    — token sets and rules */ ],
  "brands":       [ /* BrandDef[]    — brand identity that styles derive from */ ],
  "flows":        [ /* FlowDef[]     — screen-to-screen edges */ ],
  "flowPackages": [ /* FlowPackageDef[] — grouped multi-step journeys */ ],
  "content":      { /* ContentRegistry — localized labels and fixture data */ },
  "pages":        [ /* PageDef[]     — grouping for large projects */ ],
  "aliases":      { /* Record<string, string> — renamed-ID redirects */ }
}

Every field is optional.

FieldTypeNotes
formatVersionstringThe format version, as major.minor. See below.
draftsstring[]The draft parts the document uses. See below.
projectProjectMetaDisplay name, theme, default device/style.
screensScreenDef[]The screens; each has an id and a layout tree.
componentsRecord<string, ComponentDef>Reusable subtrees, referenced by component nodes.
stylesStyleDef[]Token sets and rules.
brandsBrandDef[]Optional identity a style can be generated from.
flowsFlowDef[]Documentation of navigation edges.
flowPackagesFlowPackageDef[]Named multi-step journeys.
contentContentRegistryLocalized labels ($c()) and fixtures ($f()).
pagesPageDef[]Grouping for large projects.
aliasesRecord<string, string>oldId → newId redirects after a rename.

formatVersion and drafts

formatVersion says which version of the format the document was written against: "1.0" today. A reader accepts any minor version of a major version it knows, and refuses a major version it does not.

A document with no formatVersion is read as "1.0". validate() reports that as a warning, never an error.

drafts names the draft parts the document uses. The one draft part of Framewerk 1 is requirements, so a document that states a formatVersion and carries requirements also carries "drafts": ["requirements"], and validate() reports an error when it does not.

A tool that writes documents can leave both to the package:

import { withFormatVersion } from "@framewerk/spec";

const document = withFormatVersion(spec); // states the version, names the draft parts in use

project

FieldTypeNotes
namestringDisplay name.
versionstringYour project's version — unrelated to the format version.
theme"wireframe" | "blueprint" | "high-fidelity"Rendering register. wireframe is the low-fidelity default.
defaultDevicestringA device preset ID — see Screens & devices.
defaultStylestringID of the StyleDef applied when a screen names none.

aliases

A map of oldId → newId. When a screen or component is renamed, the old ID keeps resolving instead of breaking every navigate() that pointed at it. Resolution follows chains up to a bounded depth (ALIAS_CHAIN_DEPTH), so a cycle cannot hang a renderer.

Stability

The document shape versions with @framewerk/spec under semver. Adding a top-level field or making an existing one optional is additive; removing one, or narrowing what it accepts, is breaking. The checked-in api-report.md in each package is the machine-checked record of the exported surface.