Skip to main content

Universal UI from semantic data. Describe what your data means — the compiler figures out how it looks.

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

viewspec-0.2.0.tar.gz (162.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

viewspec-0.2.0-py3-none-any.whl (35.7 kB view details)

Uploaded Python 3

File details

Details for the file viewspec-0.2.0.tar.gz.

File metadata

  • Download URL: viewspec-0.2.0.tar.gz
  • Upload date:
  • Size: 162.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for viewspec-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2270dfd88f9d9056edae9bb2febfb353bfa700865629f468dbc61b5fb7e93a8b
MD5 9f0ea3e4c7eca48b4053badc43009b2f
BLAKE2b-256 01f3b1a366ec841ad44a252992ec16818f73d9b32ccd9f14d159cc6bd35e3300

See more details on using hashes here.

File details

Details for the file viewspec-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: viewspec-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 35.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for viewspec-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cf56bb9a5f242173125b2e838b97a3389adf2ccef03bce12ee4f781f5e32fd61
MD5 5a28daf8eb3ba5abf91db632b4de9178
BLAKE2b-256 ee60dd3e88f3d30f061b23c4cddd07ddcd3ac4c6edd6b7dbc14cb8cde44fb8ca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page