HTML for structure. CSS for style. JavaScript only where behavior needs it.
โ
HTML-only by default
Bindings, conditions, and loops render on the server without browser state or hydration. Add a sibling TypeScript or JavaScript class only when a component owns behavior.
โ
Hydrate only what matters
Defer bindings and listeners until viewport relevance, or keep an optional application graph out of startup JavaScript until first interaction. One template policy declares the boundary.
โ
Stream interactivity early
Place boundaries where readiness changes. WebUI flushes and hydrates a complete child region while its parent and slower content keep rendering, without a virtual DOM.
โ
Low browser cost, measured
HTML-only components hydrate nothing, exact state projection keeps payloads focused, and deferred policies postpone work. The benchmark below reports LCP, JavaScript heap, and renderer memory alongside throughput.
โค
Skip offscreen work
Lazy rendering uses native content-visibility to defer offscreen style, layout, paint, raster, and hydration while preserving server-rendered content and scroll geometry.
โฏ
Compile once. Serve anywhere.
Templates and Web Components compile into a binary protocol. Rust, Go, Python, C#, Bun, Deno, Node.js, WASM, service workers, and edge runtimes only fill holes and write bytes.
Performance, measured.
Compare WebUI with production frameworks on the same workload across complete SSR, streaming SSR, LCP,
JavaScript heap, and renderer memory.
100 todos ยท 13 component types ยท 32 warm structural variants ยท current UTC state materialized per request ยท 64 connections from 2 load workers ยท 1 server process/worker pinned to 1 CPU ยท 1 ร 20 s measured round ยท dynamic SSR ยท natural bytes
No Streaming RPSDynamic SSR throughput when each framework sends one fully collected HTML response without progressive boundaries.
Peak RSS MiBCPU / req ms
1WebUI / Light DOM / Rust / Actix1,593.4 req/s
Peak128.12MiBCPU0.63ms/req
Details
Benchmark data
webui-handler render (Rust) ยท actix-web ยท MAD 0 req/s ยท p95 44.81 ms ยท 329,202-329,899 B natural
Server resource lifecycle
Startup
68.28MiB
Post-warmup
105.77MiB
Peak
128.12MiB
Post-settle
128.12MiB
CPU / request
0.63ms/req
2WebUI / Shadow DOM / Rust / Actix1,261.65 req/s
Peak153.42MiBCPU0.79ms/req
Details
Benchmark data
webui-handler render (Rust, Shadow DOM) ยท actix-web ยท MAD 0 req/s ยท p95 55.55 ms ยท 483,598-485,019 B natural
Server resource lifecycle
Startup
49.77MiB
Post-warmup
115.77MiB
Peak
153.42MiB
Post-settle
145.42MiB
CPU / request
0.79ms/req
3WebUI / FAST V3 / Rust / Actix976.75 req/s
Peak133.2MiBCPU1.03ms/req
Details
Benchmark data
webui-handler render (Rust, FAST V3, single response) ยท actix-web ยท MAD 0 req/s ยท p95 72.13 ms ยท 596,601-598,231 B natural
react-dom/server renderToString ยท node:http ยท MAD 0 req/s ยท p95 235.72 ms ยท 334,118-334,824 B natural
Server resource lifecycle
Startup
311.79MiB
Post-warmup
301.49MiB
Peak
382.64MiB
Post-settle
353.81MiB
CPU / request
3.13ms/req
8Preact317.6 req/s
Peak375.95MiBCPU3.15ms/req
Details
Benchmark data
preact-render-to-string renderToString ยท node:http ยท MAD 0 req/s ยท p95 228.15 ms ยท 333,940-334,646 B natural
Server resource lifecycle
Startup
289.32MiB
Post-warmup
328.78MiB
Peak
375.95MiB
Post-settle
365.94MiB
CPU / request
3.15ms/req
9Solid280.7 req/s
Peak563.66MiBCPU3.56ms/req
Details
Benchmark data
solid-js/web renderToString ยท node:http ยท MAD 0 req/s ยท p95 266.84 ms ยท 378,043-378,863 B natural
Server resource lifecycle
Startup
293.49MiB
Post-warmup
520.95MiB
Peak
563.66MiB
Post-settle
548.67MiB
CPU / request
3.56ms/req
10Vue265.2 req/s
Peak430.88MiBCPU3.77ms/req
Details
Benchmark data
@vue/server-renderer renderToString ยท node:http ยท MAD 0 req/s ยท p95 281.61 ms ยท 341,230-341,908 B natural
Server resource lifecycle
Startup
311.21MiB
Post-warmup
343.74MiB
Peak
430.88MiB
Post-settle
405.75MiB
CPU / request
3.77ms/req
11React + TanStack Router239.25 req/s
Peak445.49MiBCPU4.19ms/req
Details
Benchmark data
react-dom/server renderToString + @tanstack/react-router renderRouterToString ยท node:http ยท MAD 0 req/s ยท p95 300.07 ms ยท 334,661-335,367 B natural
Server resource lifecycle
Startup
337.07MiB
Post-warmup
335.57MiB
Peak
445.49MiB
Post-settle
412.28MiB
CPU / request
4.19ms/req
12SvelteKit198.7 req/s
Peak372.59MiBCPU5.04ms/req
Details
Benchmark data
SvelteKit production SSR (buffered synchronous route) ยท @sveltejs/adapter-node ยท MAD 0 req/s ยท p95 340.34 ms ยท 303,353-303,887 B natural ยท saturation warning: the 128-connection probe was 16.3% faster
Server resource lifecycle
Startup
165.48MiB
Post-warmup
316.41MiB
Peak
372.59MiB
Post-settle
371.81MiB
CPU / request
5.04ms/req
13Next.js138.4 req/s
Peak456.79MiBCPU7.24ms/req
Details
Benchmark data
Next.js production App Router SSR (fully collected at the framework's own Node http.Server response boundary before the response completes) ยท next start ยท MAD 0 req/s ยท p95 511.95 ms ยท 313,487-314,060 B natural
Server resource lifecycle
Startup
188.46MiB
Post-warmup
388.91MiB
Peak
456.79MiB
Post-settle
412.05MiB
CPU / request
7.24ms/req
14Nuxt76 req/s
Peak473.44MiBCPU13.2ms/req
Details
Benchmark data
Nuxt production SSR (buffered synchronous route) ยท nitro node-server ยท MAD 0 req/s ยท p95 552.62 ms ยท 280,229-280,941 B natural
Server resource lifecycle
Startup
293.46MiB
Post-warmup
430.12MiB
Peak
473.44MiB
Post-settle
446.88MiB
CPU / request
13.2ms/req
15Astro + Preact70.5 req/s
Peak580.63MiBCPU14.23ms/req
Details
Benchmark data
Astro production SSR + @astrojs/preact island (fully collected at the framework's own Node http.Server response boundary before the response completes) ยท @astrojs/node standalone ยท MAD 0 req/s ยท p95 911.86 ms ยท 463,485-464,344 B natural ยท saturation warning: the 128-connection probe was 9.6% faster
Server resource lifecycle
Startup
326.39MiB
Post-warmup
368.86MiB
Peak
580.63MiB
Post-settle
536.42MiB
CPU / request
14.23ms/req
16Lit69.9 req/s
Peak339.64MiBCPU14.33ms/req
Details
Benchmark data
@lit-labs/ssr render (collected RenderResult) ยท node:http ยท MAD 0 req/s ยท p95 559.83 ms ยท 1,357,852-1,363,128 B natural