Start with what the browser already does
Forma’s client library connects reactive values to real DOM nodes. A component runs once to establish its structure and subscriptions. Updating a signal changes the nodes that read it; it does not require rerunning the component.
Native rendering needs an explicit contract
A Rust process cannot generally execute your TypeScript component. Forma compiles an admitted source subset into FMIR, a shared representation of the rendering work. Typed page props describe which request values can enter that work.
That boundary is deliberately visible. An unsupported expression produces a build diagnostic. The compiler does not silently ship a browser-only page while claiming native rendering succeeded.
Put application logic where it belongs
Rust can authorize a request, read storage and compute presentation values before rendering. Browser event handlers can update local state and call a service. The declared props bridge those environments without pretending they are the same runtime.
The backend guide follows an Axum API route through middleware and application services, and explains where database access and outgoing HTTP clients belong.
Interactivity is a separate choice
A native route can emit no executable JavaScript. Another can register an interactive island, initialize it from server props and adopt its existing DOM. A browser-owned route can use the full client programming model. These are explicit choices, with different costs.
The tradeoff
The native subset and typed binding add constraints. In return, the same page has inspectable native output, validated inputs and deliberate activation boundaries. If an application needs arbitrary client behavior, keep that behavior at an appropriate browser boundary.
Read the architecture guide, inspect the admitted subset, or try the running native lab.