Skip to content

situ

situ situ

Site your state, derive the wire.

situ lets a Python developer write a reactive web UI as one component — real HTML on top, Python signals and handlers below — and declare, per piece of state, where it lives. A real Python→JS compiler reads that declaration and emits a small, app-specific client island; the client/server boundary stays explicit and is enforced at compile time. You author no client JavaScript, and you can read every line the compiler ships.

situ's compiler and mount core are framework-neutral; it ships a Litestar adapter (the reference) and a Flask one, and a component mounts on either unchanged. It is built for Python full-stack developers who reach for hypermedia (htmx, Datastar) and hit the wall where a piece of state wants to live in the browser — a live search, a selection, an open dialog.

Alpha software

situ is a young, alpha library extracted from a research programme (the webui repository). The compiler accepts a bounded dialect of Python and fails closed on anything outside it. See Status & roadmap for the current limits.

The one idea: site each piece of state

Every signal declares its site, and the transport follows from that — you never write a fetch, a target, or an SSE wire.

Site Where it lives What the compiler derives
Local[T] the browser compiled to JS — zero network
Url[T] the query string a shareable link the server re-renders
Server[Facade] the database a POST command that re-renders one region
Synced[T] a local-first replica reserved — see Status

The boundary is a compile-time invariant: a client read of Server-sited state is a CompileError, so database-backed state cannot reach the browser by accident.

Sixty seconds of situ

A component is two sibling files sharing a stem:

from situ import Local

count: Local[int] = 0  # client state — compiled to JS, no network


def bump() -> None:
    global count       # names the local signal this handler writes
    count = count + 1
<div data-region>
  <button @click="bump">+1</button>
  <strong :text="count"></strong>
</div>

One mount_static_component(...) call serves it; the compiler emits the island. The Quickstart walks through the whole thing, and Server components adds the database seam.

The flagship demo: a master-detail issue tracker whose entire client is a single generated island

What makes it different

Four properties hold simultaneously, and each ships with its own falsifier:

  1. The seam is proven at build time. Client access to server state fails the build — read, write, or loop (Sites & the seam). There is no code-generation path that could ship database I/O to the browser.
  2. What compiles means in the browser what it means in Python. The client dialect is specified as a table of typing rules, each verified against CPython, so ==, in, arithmetic, and truthiness behave the way the Python reads — no "passes the test, breaks in the browser" surprise. A differential oracle drives the disagreement count to zero, and knowing the types lets the compiler accept more (k in d, xs[-1], 'ab' * 3, n % m all work).
  3. The wire is legible. In the unified idiom, a reactive loop declares exactly which per-row fields cross to the client; referencing anything else is a CompileError, so over-fetching is impossible by construction.
  4. Decomposition is free. Composition — props, events, slots, provide/inject, per-instance state, scoped CSS — resolves entirely at compile time into one island. However you slice a page into components, it emits the same program as the hand-written monolith — pinned by a property test over generated trees. No runtime layer, no extra generated code; only a private namespace where a component needs one.

The generated island for every shipped demo measures 5–12 KB unminified, over a ~700-line shared runtime shim that contains no expression interpreter.

What's in the box

  • situ — the Python→JS compiler (pure standard library) and a framework-neutral mount core, with a Litestar adapter (mount_component, the reference) and a Flask one (situ.mount.flask.mount_flask). API reference.
  • situ_ui — a dense-enterprise component kit: 24 components, a CSS class contract, compiled interactions.
  • situ.decluideclui, a compile-time declarative-UI generator: a typed model + a small Screen become a working form, list, or master-detail tracker.
  • A gallery of demos and declui examples, each browser-verified — run them.

Where next