Async A2UI Turns AI-Generated Flutter UIs into Replayable, Cacheable Assets
Pre-computing AI-generated UIs eliminates the multi-second wait that makes Generative UI feel broken in production. The replayable-message design also opens a path toward offline-capable, incrementally-updated AI interfaces that don't require a live model connection.
Generative UI requests are slow, often taking tens of seconds while a model reads context and produces A2UI JSON. Async A2UI moves that generation upstream: a Cloud Function triggers on a data change, asks the model for the UI, and writes the result to Firestore before the user ever opens the app. The Flutter client then reads the cached A2UI directly, feeding it into the same transport pipeline that handles live model output.
This turns A2UI from a transient streaming artifact into a persistent, replayable UI format. The runtime doesn't care whether the message came from a live LLM, a database, or a test fixture. Saving sequences of `createSurface`, `updateComponents`, and `updateDataModel` messages effectively creates a UI event log that can be replayed to restore any interface.
The architecture also enables incremental updates: a cached dashboard appears instantly, while a background agent sends only `updateDataModel` or `updateComponents` diffs for today's new data. But this introduces hard state-management problems. UI state and agent state become coupled, requiring both sides to agree on which surfaces exist, what components they contain, and which session created them. Cache invalidation gets tricky when out-of-order LLM responses could overwrite newer UI with older versions, and client-side Widget Catalog changes can break previously valid A2UI schemas.
Async A2UI changes the category of the format itself: it stops being a transient protocol message and becomes a storable, versionable UI artifact, closer to a serialized widget tree than a chat completion.
The replayable-message design means A2UI is effectively a UI event sourcing system. Every state change is a logged command, which makes debugging, testing, and offline playback natural byproducts rather than separate features.
The coupling problem between agent state and UI state is the real production blocker. If the agent doesn't know which surfaces exist, it can't safely mutate them, but keeping them in sync across sessions and devices is an unsolved distributed-state problem.
Pre-generation works best for predictable, data-driven surfaces like dashboards and summaries. The real-time agent path remains necessary for anything shaped by a user's immediate natural-language intent, so the architecture forces a deliberate split between static and conversational UI.