situ vs. …¶
How situ relates to the things you might use instead. Two ground rules for reading it:
- The comparisons are about fit. situ's own adversarial prior-art audit graded its concepts as recombinations of known ideas; what differs is which properties each stack holds together, and those are stated concretely below.
- Where there are numbers, they were measured — the same issue tracker built four ways over one backend, and the same TodoMVC built fifteen ways (the webui research corpus; full tables in TR-001).
Orientation¶
| Client code | Client state lives | Boundary | Runtime shipped | |
|---|---|---|---|---|
| React / Vue | you write it (JSX/SFC) | component instances | convention (RSC directives, API layer) | framework runtime + your bundle |
| Svelte / Solid | you write it, compiler shrinks it | per-instance reactive scopes | convention (kit server modules) | small per-app + hydration |
| htmx (+ Alpine) | attributes + an Alpine island | ad-hoc (Alpine, DOM) | explicit, hand-wired targets | ~14 KB htmx (+ Alpine) |
| Datastar | inline signal expressions | Datastar signals in markup | explicit, region morph | ~11 KB |
| LiveView / Livewire | mostly none | on the server, per connection | explicit, socket | client runtime + socket |
| Reflex / NiceGUI / Anvil | none (generated / widget API) | on the server (or a React bundle) | collapsed — remote looks local | substantial |
| Eliom / Ur/Web / ScalaLoci / Electric | derived by the compiler | placed by annotation or type | checked by the language | varies |
| situ | none — compiled from Python | declared per signal (Local/Url/Server) |
compile error per signal | 509-line shim + a 5–12 KB generated island |
One scoping note up front: situ targets Python developers. If your team writes TypeScript, Svelte/Solid/React already serve you well and situ does not try to compete there.
situ vs. React¶
React resolves composition at runtime — component instances, hooks, a reconciler — and its server boundary (Server Components' "use server") is a bundler convention enforced by tooling. situ resolves composition at compile time into one island (no instance layer, no VDOM) and enforces its boundary per signal as a CompileError. React's ecosystem, tooling, and hiring pool are enormous and situ has none of that.
Choose React for large SPAs, native targets, or a JS/TS team. Consider situ when the app is server-rendered Python, the client needs are tracker-scale, and you want the boundary machine-checked.
situ vs. Vue¶
The closest surface relative: situ's binder vocabulary is deliberately Vue's, regularized (v-bind:/v-on: → one :/@ rule; v-for → :each; v-model → :bind), so the template dialect costs almost nothing to learn. Underneath they diverge: Vue keeps a runtime instance tree, runtime provide/inject, and runtime scoped-style injection; situ does all three at compile time (provide/inject becomes name aliasing, instance state is monomorphized per placement, scoped CSS is stamped at build). Vue is a full language for the client; situ compiles a bounded Python dialect.
situ vs. Svelte (and Solid, Qwik)¶
The closest philosophy: "the framework is a compiler." Svelte still instantiates components at runtime (per-instance reactive scopes, hydration); Solid keeps fine-grained runtime reactivity; Qwik serializes state for resumability. situ pushes the same stance one step further — the whole page becomes one island with zero per-instance runtime, and decomposing a page into components emits byte-identical JS to the monolith (a tested invariant). The price is the envelope: a finite, statically resolved component tree and a bounded expression dialect, where Svelte gives you all of JavaScript.
situ vs. htmx (+ Alpine)¶
htmx is situ's audience: the wall it removes is htmx's incidental complexity — hand-tracking hx-target/hx-swap, one fragment endpoint per interaction, and no first-class home for client state, so a search box or modal means bolting on Alpine. In situ the update target is always the one region (derived), commands are derived routes, and client state is a Local signal compiled to JS — no second framework. Measured on the same tracker: the htmx+Alpine build hand-wrote 36 lines of Alpine driving htmx; the situ build hand-wrote 0 client lines (28 authored Python signal/handler lines; a 76-line island generated).
Stay with htmx when manual targeting has never actually hurt you and your client state fits in CSS and server round trips — it is simpler, older, and dependency-light.
situ vs. Datastar¶
The nearest transport relative — situ's region-swap-plus-SSE wire is the model Datastar proved cheap (in the measured corpus, the Datastar control beat htmx on the same app: 152+56 vs 185+75 lines, because morph-by-id removes target bookkeeping). The difference is the authoring layer above the wire: Datastar evaluates signal expression strings in your markup at runtime; situ authors signals and handlers in Python — type-checked by real checkers, compiled ahead of time, with the client/server split enforced per signal — and adds the component model (slots, instance state, scoped CSS) Datastar doesn't have. Datastar needs no compiler and no mount; situ asks for both and returns the guarantees.
situ vs. Phoenix LiveView (Livewire, Blazor Server)¶
Server-driven UI keeps all state on the server and streams diffs over a socket — a great fit for server-centric teams, and LiveView is mature and battle-tested. The cost is that interaction state is connection state: it consumes server memory per client, and anything not expressible as a pre-canned client command rides the socket's latency. situ splits by site: Server state is server-rendered exactly as LiveView would, but Local state (search, selection, an open dialog) compiles to JS and never touches the network, and the server holds no per-connection UI state — commands are plain POSTs.
situ vs. FastHTML¶
Both are Python, HTML-first, hypermedia-friendly. FastHTML authors HTML as Python functions (Div(P(...))) and delegates interactivity to htmx — there is no client compilation, so client-side reactivity has the same wall as htmx. situ keeps templates as real HTML files (native editor tooling) and compiles Python to the client island. FastHTML is lighter to adopt and has no bounded dialect to hit; situ trades that for compiled client state and the seam.
situ vs. Reflex, NiceGUI, Anvil (and Streamlit/Shiny)¶
The pure-Python app builders remove the JavaScript problem by collapsing the boundary: state lives on the server (or in a generated React bundle), events round-trip over a websocket, and remote calls look local — with the latency, failure, and scaling characteristics that hides. They are productive, batteries included, and their widget catalogs are far larger than situ's kit. situ's position is the opposite bet: keep the boundary visible, make it declared, and let a compiler remove the boilerplate around it. If "where does this state live" has never cost you anything, the collapsed model is fine; when it starts to matter, that is exactly the question situ makes into a one-word annotation.
situ vs. Eliom (Links, Ur/Web, Hop, ScalaLoci, Electric)¶
The research lineage, and the family situ descends from — annotate where things live, derive the wire is two decades old:
- Eliom (OCaml) splits by declaration sections (
client/server/shared) with typed cross-tier communication; Links, Hop, Opa, and Ur/Web are whole tierless languages, Ur/Web with the strongest static guarantees in the family; ScalaLoci puts placement types on reactive values (Var[Int] on Server) — the nearest academic match to siting; Electric Clojure splits one reactive program at expression granularity, with the network as part of the runtime dataflow. - situ's variation: placement per signal, in unmodified Python — with no new language or type system, so ordinary checkers see through the markers — over an ordinary Python web stack (a hypermedia wire on Litestar or Flask; the mount core is framework-neutral). The guarantees are correspondingly narrower than Ur/Web's whole-program typing: situ enforces placement structurally, and information-flow tracking is out of scope.
If you live in OCaml, Clojure, or Scala, those systems give you deeper guarantees in your own language. situ is the same idea made ordinary for the Python mainstream.
What situ does not give you¶
For balance, the standing gaps regardless of comparison target: a JS-scale ecosystem and component market; unbounded client logic (the dialect is bounded and fails closed); native/mobile targets; offline/local-first today (Synced is reserved); and production maturity — situ is alpha, proven at TodoMVC-to-tracker scale. The full list lives in Status & roadmap, and the complete related-work treatment with citations is §2 of TR-001 (docs/papers/TR-001.md in the repository).