# Dynamic HTML Rendering with Ktor and kotlinx.html

How to implement server-side HTML updates using Molecule

- **Source:** [Jake Wharton](https://brifing.si/source/7d1b0da7-380b-4c0f-ba89-66d9375ce42b)
- **Published:** 2026-08-26
- **Topic:** [Software & Engineering](https://brifing.si/c/engineering)
- **Original article:** <https://jakewharton.com/compose-and-kotlinx-html/>
- **On Brifing:** https://brifing.si/s/b61e7282-019a-441b-a7da-51c37848e575

## The Classic HTML Rendering Problem

Using kotlinx.html with Ktor server allows simple page rendering, but static HTML becomes stale quickly. For example, a user list endpoint might continue showing outdated data even after database updates. While client-side frameworks solve this, abandoning HTML entirely isn't suitable for all projects. This creates a need for solutions that maintain HTML delivery while adding dynamism.

## Compose for HTML Solution

Compose for HTML's isomorphic rendering feature is under development. It will enable initial server-side rendering followed by client-side DOM reconstruction. Until this becomes stable, the Molecule library offers a practical alternative combining state management with HTML fragments. Molecule bridges the gap by providing reactive updates while keeping the HTML rendering approach.

## Real-time Rendering with Molecule

Molecule manages state through StateFlow and can render HTML fragments as strings. Using launchMolecule in WebSocket endpoints enables listening to database changes and regenerating HTML automatically. For instance, a /users.ws endpoint can stream updated user lists whenever the database changes. This approach maintains the simplicity of HTML while adding reactivity where needed.

## Client-side Integration

Processing HTML fragments on the client requires minimal JavaScript. WebSocket messages can directly update an element's innerHTML. For more advanced use cases, libraries like Idiomorph enable incremental DOM updates, preserving interactive elements like form fields. This demonstrates how server-rendered updates can coexist with client-side interactivity.

## Production Environment Optimizations

While suitable for low-traffic admin pages, high-traffic applications need optimizations. Establishing a single long-lived connection and multiplexing updates reduces resource usage. Implementing an envelope structure that specifies target HTML IDs helps route updates. Server-Sent Events (SSE) often prove more efficient than WebSockets for read-heavy applications with unidirectional data flow.

## Per-connection vs Shared Composition

Deciding whether rendering logic runs per-connection or shared impacts scalability. Authenticated user data typically requires per-connection handling, while public data can use shared composition. This decision balances resource usage against data consistency. Creating helper functions can reduce code duplication regardless of the chosen approach.

## HTTP/2 and SSE Advantages

Server-Sent Events offer HTTP/2 multiplexing capabilities, allowing multiple SSE streams over one TCP connection. By separating event names from payloads, SSE simplifies routing updates to different page sections. Compared to WebSockets, SSE provides a lighter solution particularly suited for content updates where bidirectional communication isn't required.

## Choosing the Right Technology

Molecule with WebSocket works well for small-scale admin panels requiring quick implementation. High-traffic production applications benefit more from SSE and shared composition. When Compose for HTML reaches stability, it may replace these solutions. During transition, the ability to reuse existing kotlinx.html functions provides valuable flexibility for incremental adoption.

## Sources covering this story

- https://jakewharton.com/compose-and-kotlinx-html/ — 

---

_Summary written by Brifing from the original reporting. Copyright in the original article belongs to its publisher; read the full piece at the link above._
