Validation
validate() returns errors for structural problems and warnings for things that render fine and are probably still wrong.
Validation
validate() returns { valid, errors, warnings }: errors are things the renderer cannot make sense of, warnings are things that render fine and are probably still wrong.
Examples
Validating a good spec:
The same shape with a dangling navigate — structurally valid, warning on the button:
Anatomy
import { validate } from "@framewerk/spec";
const result = validate(spec);
result.valid; // boolean
result.errors; // structural problems — the spec is wrong
result.warnings; // suspicious but renderable
Errors are things the renderer cannot make sense of: an unknown node type, a malformed layout tree, an invalid enum value ("variant": "zzz" on a button).
Warnings are things that render fine and are probably still wrong:
navigate(nope) targets an unknown screen "nope"
Unrecognized action "frobnicate(9)" — expected navigate(screenId), back(),
setState(key, value), toggleState(key), scrollTo(anchor), or openUrl(address)
Screen "home" has an empty layout with no children
Note where the line falls. A dangling navigate() and an unparseable action are warnings, not errors — the spec is structurally valid and the screen draws correctly; the button just does nothing when clicked. That is the most expensive class of bug in a wireframe and the easiest to miss by eye, so treat warnings as failures in CI unless you have a specific reason not to. validate() reports them; it does not rank them for you.
The package also exports the pieces the validator is built from — parseAction, evaluateExpression, normalizeLayoutTree, resolveId, lintActionStrings, collectReachableScreenIds — so you can build your own tooling on the format without reimplementing its semantics. See the API reference.
Stability
The format versions with @framewerk/spec under semver. A change that invalidates a previously-valid document is breaking, even when the TypeScript surface is untouched. The checked-in api-report.md in each package is the machine-checked record of the exported surface.
Adding a node type or an optional prop is additive. Removing one, or narrowing what an existing field accepts, is not.
Styles and tokens
A StyleDef is a token set plus selector rules; tokens become CSS custom properties and rules apply to every matching node.
Introduction
Framewerk is a JSON format for what an application must do and the screens that answer it, rendered by the Framewerk renderer into interactive screens.