JsonUI
Spec-first · generated · verifiedWrite the spec. Generate the code. Verify nothing drifted.screen_spec.json declares a screen's state, events, data flow and transitions. From it and a Layout JSON, JsonUI generates SwiftUI, Jetpack Compose and React natively — ViewModels, bindings and localization included — and then holds the result to the spec: jui build validates every attribute against one definition, jui verify diffs the generated tree against the spec and exits non-zero on drift, jsonui-doc validate checks the spec itself. Built for codebases where AI writes more than a reviewer can read.
$ jui verify --fail-on-diff --detail
# jui verify report
| Screen | Expected | Actual | Match | Missing | Extra | TypeMM | % |
|----------------|----------|--------|-------|---------|-------|--------|-----|
| profile_screen | 2 | 2 | 1 | 1 | 1 | 0 | 33% |
**Total: match=1, missing=1, extra=1, type_mismatch=0**
## profile_screen
**Missing (in spec but not in Layout JSON):**
- save (Button)
**Extra (in Layout JSON but not in spec):**
- nickname (TextField)
**verified 1 of 1 screen(s)**
$ echo $?
1
Actual output. The spec declares a save button; the Layout JSON on disk gained a nickname field and lost the button. jui verify --fail-on-diff lists both and exits 1.
What the JsonUI ecosystem isJsonUI is a spec-first toolchain for iOS, Android and Web. A screen is declared once — screen_spec.json for the contract, a Layout JSON for the view tree — and from those files the CLI generates native SwiftUI, Compose and React with their ViewModels, bindings and strings, while a set of verifiers keeps generated and hand-written code consistent with the spec. The agents, the test runners and the documentation generator all read those same files.It began as a JSON UI library for iOS — a replacement for storyboards, whose XML could not be diffed or reviewed — and later gained Android and Web renderers. The properties that made it useful to people (structured, diffable, generatable, checkable) are the ones an AI-driven pipeline needs, so the spec layer, the CLI, the MCP server and the agents were built on top of it. The name kept the history.
ContractSpecsscreen_spec.json declares state, events, data flow, transitions and branch contracts; OpenAPI declares the API and its DTOs. Generators, verifiers, agents and tests all derive from these files and are not allowed to disagree with them.screen_spec.json · component specs · OpenAPI · DB models
RenderersNative on three platformsThe same Layout JSON renders as SwiftUI, Jetpack Compose and React. There is no shared runtime: each renderer emits its stack's own idioms, and the ViewModel protocol, bindings and string tables are generated next to it.SwiftJsonUI · KotlinJsonUI · ReactJsonUI (built into the CLI)
ToolchainGenerate, build, verify — deterministicallyjsonui-cli carries the generators and the verifiers; jsonui-mcp-server exposes the same operations as MCP tools. A terminal and an agent session run the identical pipeline, and the result is deterministic for the same inputs.jsonui-cli (jui · jsonui-doc · jsonui-test) · jsonui-mcp-server · VS Code helper
GatesVerifiers with non-zero exitsjui build validates every attribute against attribute_definitions.json and treats a warning as failure. jui verify diffs the spec's declared components against the Layout JSON and exits 1 on drift. jsonui-doc validate checks the spec: transitions, dataFlow endpoints against OpenAPI, branch contracts. jsonui-doc check diffs the docs against a live OpenAPI or DB schema. Each runs the same in CI, in a terminal and under an agent.jui build · jui verify · jsonui-doc validate · jsonui-doc check
AgentsRole-separated, inside the gatesA conductor agent routes work to define, ground, implement, navigation, test and debug agents. Each is declared with only the tools its role needs — debug has no write tool — and each runs build and verify before it reports done.JsonUI-Agents for Claude Code · for Codex
Tests & docsRead the same contractTests are JSON, executed on real devices through XCUITest, UIAutomator and Playwright, with API mocks and recording also declared in JSON. Unit tests (vitest, JUnit, XCTest) are generated from the spec's branch table. Screen, ER, API and test documentation is generated from the same specs and diffed against the running backend.jsonui-test-runner (XCUITest · UIAutomator · Playwright) · jsonui-doc generate
What the verifiers refuseEach of these is a non-zero exit, not a lint suggestion. Four of them, with the actual output of the pinned toolchain on a fixture.
Layout
An attribute no platform can renderEvery attribute in a Layout JSON is checked against attribute_definitions.json, the single definition the three renderers share. A warning fails the build under the zero-warning invariant. This one was planted on this page's own title.
$ jui build --web-only
[WARN] Validation warnings found: 1
⚠️ [id=home_hero_title] Unknown attribute 'glowIntensity' for component type 'Label'
Drift
A green that says what it did not measureA screen whose layout is hand-authored has no generated counterpart to diff, so verify skips it and prints the count with the reason. This is the line this site prints for itself: 0 verified, 2 skipped — not 'no differences'.
$ jui verify --fail-on-diff
**verified 0 of 2 screen(s)** — 2 skipped (layout authored externally)
Spec
A contract for a method the ViewModel never declaresbranchContracts may only reference methods declared in dataFlow.viewModel.methods or stateManagement.eventHandlers. A name outside that set fails validation before any generator runs.
$ jsonui-doc validate spec docs/specs/profile_screen.spec.json
[ERROR] branchContracts.methods.onTapSubmit: Method 'onTapSubmit' not found in
dataFlow.viewModel.methods or stateManagement.eventHandlers
Result: FAILED
Tests
A branch whose state no test could arrangejsonui-test generates unit tests from the spec's branch table for vitest, JUnit and XCTest. A condition a branch depends on needs a witness that arranges the state; without one, generation stops rather than emitting a test that could not fail.
$ jsonui-test generate branch-tests profile_screen
Error: condition 'formValid' has no witness_true — test generation needs a witness
to arrange the state
Every line above was produced by the pinned toolchain on a fixture — none was written by hand.
Why verification, not a better promptGenerated code volume scales with model speed; review capacity does not. Prompting for accuracy raises the average and does nothing for the cases it misses, which are the ones that reach production. So the useful layer is the one that rejects a wrong artifact mechanically: reduce the surface that has to be free-form (the spec fixes state, events and transitions; layouts are declarative), generate deterministically what can be derived (ViewModels, bindings, DTOs from OpenAPI, tests from branch tables), and verify what can be compared (attributes, drift, contracts, live schemas). What remains for a person is the spec, the UX and the business logic.What that buys, precisely: conformance, not correctness. verify proves the code matches the spec; validate proves the spec is well-formed; neither proves the spec is what you wanted. That makes the spec the artifact to review, and the artifact where discipline has to live — a verifier that can be satisfied by loosening the contract checks nothing. Changes to specs are the changes a person reads.Scope, honestly: the spec layer costs something up front. It pays back on products with many screens of similar shape, maintained over time by several people or agents. It is not a good fit for a one-off page.
Native on every platformSwiftUI, Jetpack Compose and React, each generated from the same Layout JSON and spec. No shared runtime, no lowest-common-denominator widgets.
SwiftSwift / SwiftUISwiftJsonUI renders your spec with SwiftUI modifiers, protocol-based ViewModels, and real @Published state./platforms/swift
KotlinKotlin / ComposeKotlinJsonUI emits Jetpack Compose with StateFlow ViewModels and lifecycle-aware collectors./platforms/kotlin
ReactReact / Next.jsReactJsonUI generates TypeScript components, ViewModel classes, and Tailwind-powered layouts./platforms/react
What's newRecent docs and library changes worth a look.
Apr 2026Installation is now one lineA single curl installs the CLI, the MCP server, and the agent pack.Read the install guide
Apr 2026PC-first docs chromePersistent sidebar + top bar replace the bottom tabbar — navigate every page without scrolling back to home.Read the design notes
Apr 2026Agent pack for Claude CodeSpec-first workflow scaffolded end-to-end by conductor-routed sub-agents.Browse the agent catalog
May 2026OpenAPI → DTO + Domain, on every platform`jui build` reads `docs/api/*.json` and emits per-platform DTOs (wire-shape 1:1, regenerated every build) plus Domain scaffolds (one-time, user-owned). One schema source of truth across iOS / Android / Web.Read the concept
May 2026Per-app path filter for shared swagger`api.schemas.include_paths` / `exclude_paths` / `include_schemas` / `exclude_schemas` — scope what gets generated when many apps consume one swagger. Cookbook + filter eval order + 0-schema warning rules.Open the cookbook
May 2026MCP Group E — API model discovery from your agentThree new MCP tools — `list_api_specs`, `list_api_models`, `preview_api_model_sync` — let an agent inventory swagger files, list per-platform DTOs / Domain scaffolds / orphans, and dry-run filter changes before you commit them.See MCP Group E
Jul 2026Renderer SSoT: canonicalized layouts, typed attributesDistributed layouts now carry a `$jui` marker with alias→canonical rewrites (L1). Typed attribute extractors are generated from `attribute_definitions.json` for iOS / Android / Web.Read the concept
Jul 2026`jsonui-doc check` — verify docs against realityOpenAPI diff and DB schema checkers verify that the running server and live DB still match your `docs/api/` and `docs/db/`. Results land in the generated HTML as an implementation-contract page.Read the concept