UI-heavy web applications

This page collects architecture notes for browser-heavy products: dashboards, maps, messaging, marketplace flows, and suite shells where the client stays open for a long time and state fans out across many views. It is informed by comparisons among Bonsai (OCaml, js_of_ocaml), Leptos (Rust, SSR and WASM), vibe.d (D, server-first), and by how large integrated mail products tend to behave in practice.

Roles: client UI, API, and database

Bonsai is a client-side UI library. It does not host a database or enforce authentication by itself; it renders in the browser and talks to backends over HTTP or WebSockets, like any SPA stack.

  • Database access belongs on a server (or managed backend). In OCaml that often means Caqti with PostgreSQL or SQLite, behind Dream (or similar), not inside the compiled browser bundle.

  • Authentication splits naturally: UX and tokens in the client, trust and authorization on the server (sessions, JWT verification, OIDC code exchange, row-level rules). There is no single “Bonsai auth” package; many teams pair an OCaml API with hosted identity (Auth0, Clerk, Supabase, and so on) when OIDC/JWKS churn outpaces hand-maintained OCaml clients.

vibe.d fits the HTTP service side: async I/O, routing, WebSockets, templates, and native drivers—orthogonal to whether the browser UI is Bonsai, React, or something else.

Leptos is different in packaging: it is a full-stack framework with SSR, hydration, and server functions, so database and auth can sit in the same Rust project with less hand-written REST glue—still with secrets on the server.

Bonsai, Leptos, and vibe.d (where each wins)

Dimension Bonsai Leptos vibe.d

Sweet spot

Complex in-browser state and incremental view updates

Full-stack reactive sites, SSR/SEO, shared Rust types end-to-end

High-throughput native services, classic web apps, APIs

In the browser

JavaScript from OCaml

WebAssembly (with optional SSR first paint)

Not the default model for rich SPA chrome

SSR

Bring your own; often SPA-first

First-class

Natural for server-rendered HTML

Suite integration

Client calls your APIs; suite modules are separate bundles or pages you design

Same, plus server functions for tighter coupling

Strong as the API + HTML tier; pair with a separate SPA if needed

None of these choices removes the need for a deliberate load budget: what ships on the critical path before the inbox (or map, or list) is interactive.

Creative stack: 3D, scroll, and advanced text layout

Libraries such as Three.js, Lenis / Locomotive-style smooth scrolling, and Pretext (layout and measurement for kinetic typography) are npm-first and assume a JavaScript execution model.

  • Bonsai path: raw WebGL via js_of_ocaml, or FFI to the JavaScript library. There is no mainstream equivalent to React Three Fiber; AI-assisted “vibe coding” and copy-paste examples are far thinner than in TypeScript.

  • Motion-heavy marketing often ships faster as a small TypeScript island (or static pages) next to a structured app, rather than reimplementing every trendy package in OCaml bindings.

Case study shapes (not insider postmortems)

Dense webmail (for example Gmail-class clients)

A mail client benefits from incremental UI and disciplined state, which is the class of problem Bonsai targets. Rewriting a product the size of Gmail is dominated by scope, integrations, protocols, experiments, and initial payload, not only the renderer. A framework swap does not by itself fix loading time if the critical path still pulls large bundles, telemetry, feature flags, and many subsystems before first interaction.

Why another suite (for example Zoho Mail) can feel faster than Gmail

Perceived speed usually mixes initial load, main-thread jank, and what is deferred after the core list is usable. Integrated suites can integrate lightly (SSO, links, APIs, embeds) without loading every sibling product inside the same tab on the first navigation. Consumer Gmail also sits inside a broader Google surface (experiments, ads on consumer tiers, multiple products in one shell), which routinely adds variability and weight unrelated to “JavaScript is slow.”

These points are architectural hypotheses, not claims about proprietary codebases.

Practical guidance

  • Match the framework to the tier: server-first (vibe.d) for APIs and HTML; Leptos when Rust should own SSR and client with minimal boundary boilerplate; Bonsai when you want OCaml in the browser and accept a separate server and SSR story.

  • Treat ecosystem and AI assistance as a risk line item for OCaml client work: fewer examples and weaker codegen than for React or Rust web stacks.

  • For food-truck style products (live location, favorites, geo notifications, event marketplaces), most risk is in data, auth, maps, and notifications—keep the initial route lean regardless of UI library.

See also