Skip to content

Architecture & research

The repository map

src/situ/
  siting/        the Signal / Signals / Site contract + the X-Siting-Signals header
  compiler/      the Python→JS compiler (stdlib, plus astero for hygienic composition)
    frontend/      parse the .py/.html pair · :each row scopes · region split · splice_tree
    lang/          the typed dialect: rules (verified vs CPython) · types · check · IR · lower
    emitter/       the owned back end: expression / statement / binder visitors (over lang/)
    markers.py     Local · Url · Server · Synced · Prop · Emit · Provide · Inject
    resolve.py     Context + static tree resolution (situ check)
    unified.py     the unified idiom desugarer (opt-in: { expr } · :each ~ · :if / :else)
  mount/         core.py the framework-neutral runtime (dispatch/render + command/region/feed/window) · runtime.py+factories.py the Litestar adapter · flask.py the Flask adapter
  static/        _rt.js — the ~700-line client shim (no expression interpreter)
  declui/        the declarative generator: spec · generate · predicates · mount
  infra/         Jinja string rendering; [sqlalchemy]: engine + Dishka session provider
  check.py       python -m situ.check
src/situ_ui/     the component kit: ui.css (the class contract) · widgets.js · components/
demos/           showcase apps under one umbrella (demos.app:app)
examples/declui/ generator examples under a second umbrella
examples/flask/  a declui server tracker served on plain Flask (situ.mount.flask)
tests/           a_unit (per-package: compiler/ declui/ mount/ infra/ siting/) · b_integration
                 (in-process HTTP) · c_browser (uvicorn + Chromium) · fixtures/ · apps/
notes/           the design log — one numbered note per design round

Sizes, for orientation: the compiler is ~6,200 lines (its typed-dialect core, compiler/lang/, is ~2,000), declui ~4,500, the mount ~1,400 (a framework-neutral core plus the Litestar, generic-ASGI and Flask adapters), and the shim ~700 lines of JS. The test suite is larger than src/ itself.

How it holds together

flowchart LR
    subgraph authoring["Authoring"]
        PY["name.py"]
        HTML["name.html"]
    end
    subgraph compile["Compile time"]
        FE["FrontEnd"]
        SPL["splice_tree"]
        EA["EmittedApp"]
    end
    subgraph runtime["Runtime"]
        MOUNT["mount: neutral core + adapter (Litestar / Flask)<br/>page · island · /cmd · /feed"]
        BROWSER["_rt.js + generated island"]
    end
    PY --> FE
    HTML --> FE
    FE --> SPL --> EA --> MOUNT
    MOUNT <--> BROWSER

declui sits in front of this pipeline: it generates ordinary component source (situ's own language is its intermediate representation) and hands it to the unmodified compiler.

The research record

situ is the productized core of a documented research programme:

  • TR-002: "situ: A Verified-Dialect Compiler for Site-Declared Python Web UIs", the current technical report (the typed-dialect edition): the programming model, the compiler and its correctness against CPython, the wire projection, zero-runtime composition, declui, the derived context() type contract, the evaluation, and the enforcement-class method. In this repository at docs/papers/TR-002.md. It supersedes TR-001 (docs/papers/TR-001.md), a valid pre-typed-dialect snapshot that carries the detailed measurement tables.
  • TR-003: "Derive, Don't Declare: Static Checking of Template Contexts in a Bounded Web Dialect", a companion report on one seam: how the compiler derives a component's context() contract from its template, what that derivation cannot see, plus what both measure on the mounted corpus (fault injection, coverage, cost). In this repository at docs/papers/TR-003.md, with its measurement harness at docs/papers/assets/tr-003/measure.py.
  • The design log (notes/14–notes/43): one note per design round, covering the unified template idiom and the wire projection (14–16), the component kit (17–20), the composition redesign with its golden-bytes invariant (21–23), the backlog compass (24), the declui line (25–27) with per-slice build and adversarial-review records, the fail-closed audit (34), the typed dialect (35) with the TR followup (36), the typed-template phases (40–41), and a reader's map of the compiler itself (43).
  • The upstream webui repository, the original demo programme: fifteen TodoMVC implementations over one backend (five controls, ten inventions), the four-way issue-tracker comparison, plus the adversarial prior-art audit that grades this project's novelty claims.

The same issue tracker costs 130 hand-written client lines as a vanilla SPA, 36 as htmx+Alpine, ~30 inline expressions as Datastar, and 0 with situ (a 76-line island is generated); every generated island across the shipped apps measures 5–12 KB unminified.

Lineage, in one paragraph

The placement idea (annotate where a value lives, derive the wire) descends from two decades of multi-tier programming research (Links, Hop, Eliom, ML5, ScalaLoci, Electric Clojure), recombined here at per-signal granularity in unmodified Python. The compile-away stance is Svelte's, taken further (no per-instance runtime at all). The region-swap transport is hypermedia's (htmx, Datastar). declui recycles AribaWeb/MetaUI's rule model with resolution moved to build time. The new constructs, per that audit: the template wire projection, the byte-identity composition invariant, the compile-time predicate cascade, and, since the typed dialect, its verified form. TR-002 cites all of it properly.