Cased
Tomás González Tomás González

How We Build Generative UI

Ask for a view, get a small app that keeps fetching real data. The AI generates once, then gets out of the way.
How We Build Generative UI

If you’re building tools for developers or operations teams, you’ve probably hit the same wall we did: either you build fixed UIs that can’t adapt to each customer’s unique setup, or you reach for AI to generate everything on-the-fly and accept the latency, cost, and unpredictability that comes with it.

We found a third option.

Two extremes that don’t quite work

Static dashboards work great for the happy path but struggle when customers have different AWS regions, unique naming conventions, or integration patterns you didn’t anticipate. You end up building configuration screens on top of configuration screens.

Real-time generation means calling an LLM on every user interaction. Click a button, wait for the model. Load a page, wait for the model. The UX suffers, costs spiral, and debugging becomes a nightmare when the AI decides to render things differently each time.

We wanted something in between.

Generate a controller, not a snapshot

When you ask Cased for a view “show me open PRs with failing checks” you’re not getting a static report. You’re getting a small application that knows how to fetch that data.

We use an LLM to generate a controller function, validate it against real data, and store it. Every future render executes that controller directly, no AI in the loop. The view might be useful for ten minutes during an incident, or it might become something you check every morning. Either way, the data is always current.

Constrained output

The controller can’t render arbitrary HTML. It returns structured data that maps to a fixed set of components we’ve designed. This constraint is what makes filtering, sorting, and drilling down feel immediate rather than waiting for the model to figure out how to render each interaction.

But constrained doesn’t mean limited. The combinations are endless. HTML itself is just a combination of preset elements. A small set of well-designed components can express anything you need.

Iterative refinement

Once a view exists, you can modify it through conversation. “Add a column for comments.” “Filter to PRs from the last week.” Each modification generates a new controller derived from the existing one, more precise than starting from scratch because the system knows what data is available and what the current view does.

Why this matters for DevOps

Operational tools need to pull from GitHub, AWS, Sentry, Datadog, services where auth is per-customer and data shapes vary. Static UIs can’t anticipate every setup. Real-time generation can’t provide the snappy interactions you need during an incident.

Generated controllers adapt to each customer without sacrificing responsiveness. The AI does the heavy lifting once, then gets out of the way.