Skip to main content

ViewSpec

Universal UI from semantic data.

ViewSpec is a declarative language for describing what data means. The compiler figures out how it looks. Every pixel has a birth certificate.

🌐 viewspec.dev — Live hosted compiler playground, demos, and pricing

from viewspec import ViewSpecBuilder, compile
from viewspec.emitters.html_tailwind import HtmlTailwindEmitter

builder = ViewSpecBuilder("invoice")
table = builder.add_table("items", region="main", group_id="rows")
table.add_row(label="Design System Audit", value="$4,200")
table.add_row(label="Component Library", value="$8,500")
table.add_row(label="API Integration", value="$3,100")

ast = compile(builder.build_bundle())
HtmlTailwindEmitter().emit(ast, "output/")

# That's it. Full UI. Full provenance. No CSS.

What ViewSpec Does

Before ViewSpec: You manually bridge the gap between data and UI. Every component, every prop, every layout decision — hand-wired by a developer.

After ViewSpec: You declare what the data means. The compiler determines the visual structure. Rendering is a pluggable backend.

Data → ViewSpec (semantic intent) → Compiler → CompositionIR → Emitter
                                                                ├── HTML/Tailwind (shipped)
                                                                ├── Canvas/Pretext
                                                                ├── PDF
                                                                ├── Native mobile
                                                                └── Your custom emitter

Three Invariants

ViewSpec enforces three mathematical guarantees:

  1. Exactly-once provenance. Every data binding is routed exactly once. Nothing dropped. Nothing duplicated. Nothing hallucinated.

  2. Semantic grouping. Data is grouped by meaning, not by visual adjacency.

  3. Strict ordering. The original data order is preserved as a mathematical guarantee.

Install

pip install viewspec

Requires Python 3.11+.

Hosted Playground

The home page at viewspec.dev runs a live hosted compile against https://api.viewspec.dev/v1/compile. It uses anonymous free-tier requests by default and shows the request, response, measured compile_ms, active derivation tokens, and provenance chain.

Agent and crawler entrypoints are published with the static site:

  • https://viewspec.dev/llms.txt — concise LLM-facing product map
  • https://viewspec.dev/llms-full.txt — expanded AI context and canonical facts
  • https://viewspec.dev/agent-system-prompt.txt — system prompt for agents that emit IntentBundle JSON
  • https://viewspec.dev/agent-intent-bundle.schema.json — JSON schema for agent-authored compiler input
  • https://viewspec.dev/openapi.json — hosted compiler OpenAPI description
  • https://viewspec.dev/sitemap.xml — canonical page sitemap

Runtime landing-page config is read from window.VIEWSPEC_LANDING_CONFIG:

Key Purpose
apiUrl Hosted compiler endpoint. Defaults to https://api.viewspec.dev/v1/compile.
fallbackApiUrls Optional fallback compiler endpoints for landing-page availability during custom-domain cutovers.
endpointStaggerMs Delay before starting fallback endpoint requests. Defaults to 120.
endpointFailureTtlMs How long the browser session keeps a failed endpoint out of the hot path. Defaults to 300000.
publicApiKey Optional browser-safe public/demo key. window.PUBLIC_LANDING_API_KEY is also accepted. Omit it to use anonymous free-tier demo traffic.
proStripeUrl Pro checkout link. Defaults to the live Stripe payment link.
scaleStripeUrl Scale checkout link. Defaults to the live Stripe payment link.
signupUrl Free CTA or pricing URL. Defaults to https://viewspec.dev/#pricing.
requestTimeoutMs Hosted compile timeout. Defaults to 6000.

Keep secret API keys server-side; only browser-safe public/demo keys belong in static landing-page config.

Demos

The hosted playground plus six reference demos are available at viewspec.dev:

Demo What it shows
Same Data, Three Motifs One dataset → table, dashboard, or comparison. Change one parameter.
Provenance Inspector Hover any element. Trace DOM → IR → binding → address → raw data.
Live Builder Browse ViewSpec JSON, IR tree, and rendered output in sync.
The Invariants Watch the compiler enforce — and refuse — each guarantee.
15 Lines → Full UI An invoice table builds itself from 15 lines of Python.
Style Derivation Same structure, different feel. Toggle four visual presets.

Text rendering powered by Pretext canvas surfaces.

Core Concepts

Semantic Substrate

The raw data graph. Nodes with typed attributes, slots, and edges. This is WHAT the data is — no visual intent.

builder = ViewSpecBuilder("my_view")
builder.add_node("user_1", "person", attrs={"name": "Alice", "role": "Engineer"})
builder.add_node("user_2", "person", attrs={"name": "Bob", "role": "Designer"})

ViewSpec

The declarative intent layer. Regions (WHERE data can go), bindings (WHICH data goes WHERE), motifs (HOW it should be structured), and styles (how it should FEEL).

table = builder.add_table("team", region="main", group_id="members")
table.add_row(label="Alice", value="Engineer")
table.add_row(label="Bob", value="Designer")

CompositionIR

The compiler's output. A strict hierarchical tree of 12 UI primitives (root, stack, grid, cluster, surface, text, label, value, badge, image_slot, rule, svg) with full provenance tracking. Every IR node knows which semantic addresses and intent refs produced it.

Emitters

Pluggable renderers that turn CompositionIR into concrete output. Subclass EmitterPlugin:

from viewspec.emitters.base import EmitterPlugin

class MyEmitter(EmitterPlugin):
    def emit(self, ast_bundle, output_dir):
        # Walk ast_bundle.result.root.root and produce output
        ...

The included HTML/Tailwind emitter produces standalone HTML with full Tailwind styling, provenance data attributes on every DOM element, action event dispatch, and a JSON provenance manifest.

Motif Types

Builder Motif Use case
add_table() table Tabular data with label-value rows
add_dashboard() dashboard KPI cards with label-value pairs
add_outline() outline Hierarchical outlines and trees
add_comparison() comparison Side-by-side comparisons

Each builder returns a chained sub-builder. Compose them freely within a single ViewSpec.

Compilation

Reference Compiler (free, offline)

Handles the four standard motifs locally. No API, no network, no LLM. Deterministic.

ast = compile(builder.build_bundle())

Hosted Compiler (api.viewspec.dev)

For complex layouts, novel data shapes, and advanced derivation. The hosted compiler was evolved (not hand-written) using reinforcement learning:

  • 13/13 on a static validation suite
  • 50/50 on novel, randomized out-of-distribution layouts (one-shot)
  • Level 2 derivation tokens — data-aware emphasis, narrative routing, palette energy
  • Zero LLM calls at runtime — deterministic Python compile path; the live playground reports measured compile_ms for each request
from viewspec import compile_auto

# Try local first, fall back to hosted for unsupported motifs
ast = compile_auto(builder.build_bundle())
Tier Price Hosted Calls/Day
Free $0 500
Pro $39/mo 25,000
Scale $99/mo 250,000

Wire Format

Protocol Buffers for language-agnostic serialization. The same ViewSpec can be constructed in Python, Rust, Go, TypeScript, or any language with protobuf support.

bundle = builder.build_bundle()
json_data = bundle.to_json()           # JSON round-trip
proto_bytes = bundle.to_proto().SerializeToString()  # Protobuf round-trip

Examples

See examples/:

  • invoice_table.py — Build a table in 15 lines
  • kpi_dashboard.py — KPI dashboard with style tokens
  • comparison_view.py — Side-by-side comparison
  • emit_html.py — Load a compiled AST and emit HTML

License

MIT

Release files for viewspec 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for viewspec 0.2.0
File Size Uploaded
viewspec-0.2.0.tar.gz 162.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for viewspec 0.2.0
File Interpreter ABI Platform
viewspec-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 198.2 kB

Release files / viewspec-0.2.0.tar.gz

Download URL viewspec-0.2.0.tar.gz
Size 162.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2270dfd88f9d9056edae9bb2febfb353bfa700865629f468dbc61b5fb7e93a8b
BLAKE2b-256 checksum
How to use checksums
01f3b1a366ec841ad44a252992ec16818f73d9b32ccd9f14d159cc6bd35e3300
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / viewspec-0.2.0-py3-none-any.whl

Download URL viewspec-0.2.0-py3-none-any.whl
Size 35.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cf56bb9a5f242173125b2e838b97a3389adf2ccef03bce12ee4f781f5e32fd61
BLAKE2b-256 checksum
How to use checksums
ee60dd3e88f3d30f061b23c4cddd07ddcd3ac4c6edd6b7dbc14cb8cde44fb8ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page