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 demos and interactive playground

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+.

Demos

Six interactive demos 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 cost at runtime — deterministic Python, ~3ms per compile
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
Enterprise Contact Custom

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.1.0.tar.gz (116.3 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.1.0-py3-none-any.whl (26.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for viewspec-0.1.0.tar.gz
Algorithm Hash digest
SHA256 152d0a29044cca00b29adc69deed093c40fa8e94af1d3d0fc47c59846cf41a53
MD5 9369b7dae48b62bf56fe3a1e319c52f6
BLAKE2b-256 efe99c1457e8340be2309f011976ea71a6d5629128bc3ade0711c847bb3562ad

See more details on using hashes here.

File details

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

File metadata

  • Download URL: viewspec-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 26.5 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 332e6cda8a3edd35b6d1cd658eb64087de3ef51704a92d368d3b8380051fb45a
MD5 ad8ba538666b375fad06dfe649831fd0
BLAKE2b-256 ada96f5c4218ccbbab829e224391d4ceafefb5133de5f157a954a512f649a5c5

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