Flutter GenUI SDK and A2UI: a 2026 developer guide to server-driven, agent-generated UIs

A working guide to Flutter's GenUI SDK and the A2UI protocol: architecture, real Dart code, the security model, and the alpha caveats.

Read time
12 min
Word count
1.6K
Sections
12
FAQs
8
Share
Smartphone rendering AI-generated UI cards, a date picker and buttons above a data node
Flutter's GenUI SDK renders agent-generated A2UI components as native app widgets.
On this page · 12 sections
  1. What GenUI and A2UI actually are
  2. Why "UI as data, not code" is the core idea
  3. How the pieces fit: the GenUI architecture
  4. Build it: a minimal GenUI screen
  5. Add your own widgets to the catalog
  6. The A2UI wire format and data binding
  7. A2UI versus MCP Apps and ChatKit
  8. What to watch before you ship
  9. India-specific considerations
  10. FAQ
  11. How eCorpIT can help
  12. References

Summary. On December 15, 2025 Google made A2UI public, an open, Apache 2.0 protocol that lets an AI agent describe a user interface as declarative JSON instead of text. Flutter's GenUI SDK uses A2UI as its wire format so an agent can compose real Flutter widgets from your app's own catalog. The pitch: instead of a wall of chat text, a booking agent returns a date picker, a time selector, and a submit button that the user can tap. This guide covers how the pieces fit, working Dart code from the official docs, the "UI as data, not code" security model, a comparison with MCP Apps and OpenAI ChatKit, and the honest caveats: the genui package is still alpha, and PromptBuilder.chat() can emit a 3,000 to 5,000 token system prompt on every request, which at Gemini 3.5 Flash's roughly $1.50 per million input and $9.00 per million output tokens (May 2026) is a real cost at scale. Target reader: Flutter and mobile developers building AI features on top of Flutter 3.44.

A2UI ships at format version 0.8 with early client libraries for Flutter, Web Components, and Angular, and it renders through your existing widgets rather than an iframe. That last point is the whole design. Below is the shortest possible A2UI component an agent can send:


            {
  "id": "welcome-text",
  "component": "Text",
  "text": "Welcome to GenUI",
  "variant": "h1"
}
          

What GenUI and A2UI actually are

GenUI, generative UI, is a paradigm where the model responds with real, interactive UI instead of prose. A2UI (Agent-to-UI) is the protocol underneath it: an open specification that defines how an agent and a client collaborate on the composition and state of an interface. Google's A2UI team describes it as a way to transmit UI that is "safe like data, but expressive like code."

The GenUI SDK for Flutter is the client-side orchestration layer. Per the official Flutter docs, it is a suite of packages that coordinates the flow of information between your user, your Flutter widgets, and an AI agent, using a JSON format to compose a UI from your existing widget catalog. As the user interacts, state changes flow back to the agent, which is the loop that turns a chat into an app screen. The SDK reflects Flutter 3.44 and, as of the docs update on June 26, 2026, the genui package is still in alpha.

The separation matters: A2UI defines the message format, GenUI is one renderer of it. The same A2UI JSON payload can be rendered by Lit, Angular, Flutter, and community renderers for Android Compose and Apple SwiftUI. Write the agent once, render it on every client.

Why "UI as data, not code" is the core idea

Historically, showing UI from a remote, untrusted agent meant shipping HTML or JavaScript and sandboxing it in an iframe, which is heavy and rarely matches your app's styling. A2UI takes a different route. Google's three design principles are worth stating plainly:

  • Security first. A2UI is a declarative data format, not executable code. Your client keeps a catalog of trusted, pre-approved components (for example Card, Button, TextField), and the agent can only request components from that catalog. That reduces the risk of UI injection because the model never ships runnable code.
  • LLM-friendly and incrementally updateable. The UI is a flat list of components with ID references, which a model can generate and revise incrementally for progressive rendering.
  • Framework-agnostic. A2UI separates UI structure from implementation. The agent sends a component tree plus a data model; your client maps it to native widgets.

For anyone who has fought an untrusted embed, the catalog model is the headline. The agent proposes; your client disposes. The same instinct drives our note on agentic browser and enterprise data-security controls: keep model output on the data side of the boundary, never the execution side.

How the pieces fit: the GenUI architecture

The genui package exposes a small set of classes. You wire them once and then talk mostly to Conversation.

Component What it does You provide
SurfaceController Holds the widget catalogs and manages generated UI surfaces Your Catalog list
Catalog and CatalogItem The set of widgets the agent may generate, each with a schema Widget name, schema, builder
PromptBuilder Builds the system prompt and the tools the agent can call System instruction fragments
A2uiTransportAdapter Parses A2UI messages and pipes model chunks in An onSend handler
A2uiAgentConnector Low-level connection to a remote A2A server The server URI
Conversation Orchestrates transport and controller; your main handle The controller and transport
Surface The widget that renders one agent-generated surface A surface ID
DataModel Observable store for dynamic UI state; drives data binding Nothing; widgets bind by path

There are three ways to connect an agent provider: Firebase AI Logic for a client-only app where Firebase manages the Gemini API key, GenUI A2UI for a client/server setup where the agent runs on a server, and a build-your-own adapter for any other LLM.

Build it: a minimal GenUI screen

Add the packages. For a client-only Firebase path:


            $ dart pub add genui firebase_ai
          

Then create the controller, a prompt builder, and a conversation. This is the shape the docs use, trimmed to the essentials:


            import 'package:genui/genui.dart';
import 'package:firebase_ai/firebase_ai.dart';

// 1. The catalog is the ONLY set of widgets the agent may generate.
final surfaceController =
    SurfaceController(catalogs: [BasicCatalogItems.asCatalog()]);

// 2. The system prompt tells the model to answer in UI, not text.
final promptBuilder = PromptBuilder.chat(
  catalog: BasicCatalogItems.asCatalog(),
  systemPromptFragments: ['You are a helpful assistant.'],
);

// 3. Pick a model. The docs example uses gemini-3.5-flash.
final model = FirebaseAI.vertexAI().generativeModel(
  model: 'gemini-3.5-flash',
  systemInstruction: Content.system(promptBuilder.systemPromptJoined()),
);

// 4. Wire transport -> controller.
late final A2uiTransportAdapter transportAdapter;
transportAdapter = A2uiTransportAdapter(onSend: (message) async {
  // stream model output back with transportAdapter.addChunk(...)
});

final conversation = Conversation(
  controller: surfaceController,
  transport: transportAdapter,
);
          

To render, listen to conversation.events for ConversationSurfaceAdded and build a Surface for each surface ID:


            Surface(surfaceContext: surfaceController.contextFor(surfaceId));
          

For a client/server build, swap in genui_a2a and point A2uiAgentConnector at your A2A server:


            final connector = A2uiAgentConnector(url: Uri.parse('http://localhost:8080'));
connector.stream.listen(surfaceController.handleMessage);
          

On iOS or macOS, add the com.apple.security.network.client entitlement so the app can make outbound requests, or the connection fails silently.

Add your own widgets to the catalog

The core catalog is fine for a demo. Real apps register their own widgets so the agent generates on-brand UI. A CatalogItem binds a name, a JSON schema, and a builder. Here is a RiddleCard, following the docs example:


            import 'package:json_schema_builder/json_schema_builder.dart';
import 'package:genui/genui.dart';

final _schema = S.object(
  properties: {
    'question': S.string(description: 'The question part of a riddle.'),
    'answer': S.string(description: 'The answer part of a riddle.'),
  },
  required: ['question', 'answer'],
);

final riddleCard = CatalogItem(
  name: 'RiddleCard',
  dataSchema: _schema,
  widgetBuilder: (itemContext) {
    final json = itemContext.data as Map<String, Object?>;
    return Card(
      child: Column(children: [
        Text(json['question'] as String),
        Text(json['answer'] as String),
      ]),
    );
  },
);
          

Register it, then tell the system prompt to use it by name:


            final controller = SurfaceController(
  catalogs: [BasicCatalogItems.asCatalog().copyWith(newItems: [riddleCard])],
);
          

The agent now knows one more move. Because the widget name and schema are yours, the model cannot generate anything outside that contract.

The A2UI wire format and data binding

genui centers on a DataModel, an observable store for UI state. Widgets bind to it by path, so when a bound value changes only the dependent widgets rebuild. An input widget such as a TextField bound to /user/name updates the model directly, and every widget on that path rebuilds. That reactive loop between the user, the UI, and the agent is the point of the whole SDK. It is the same server-driven-UI idea Flutter teams already know from patterns in our Flutter AI features with Gemini and the Dart MCP guide, now standardized as a protocol.

A2UI versus MCP Apps and ChatKit

A2UI is not the only agentic-UI approach shipping in 2026. The Model Context Protocol added MCP Apps on November 21, 2025, and OpenAI has ChatKit. They solve overlapping problems differently.

Approach How UI is delivered Best for
A2UI (Google) Declarative component blueprint rendered by your native widgets Cross-platform, multi-agent meshes where the client keeps styling and security
MCP Apps UI as a resource via a ui:// URI, usually pre-built HTML in a sandboxed iframe Tool-returned interfaces inside MCP hosts
OpenAI ChatKit Integrated, optimized UI inside the OpenAI ecosystem Teams standardizing on OpenAI

Google's own framing is that A2UI is "native-first": instead of fetching an opaque payload for a sandbox, the agent sends a blueprint of native components, so the UI inherits your app's styling and accessibility. "A2UI was a great fit for Flutter's GenUI SDK because it ensures that every user, on every platform, gets a high quality native feeling experience," said Vijay Menon, Engineering Director for Dart at Google. A2UI also has day-zero support in AG UI and CopilotKit; "We're excited to provide day-0 compatibility between AG-UI and A2UI," said Atai Barkai, founder of CopilotKit and AG UI.

What to watch before you ship

Three caveats keep this out of production for many teams today.

First, it is alpha. The Flutter docs label the genui package experimental and "likely to change," and A2UI is at format 0.8. Expect breaking changes; pin versions and budget for churn.

Second, the system prompt is heavy. The docs warn that PromptBuilder.chat() can generate a system prompt of 3,000 to 5,000 or more tokens, which can exceed the context window of small or on-device models. That is also a cost line: Gemini 3.5 Flash lists at about $1.50 per million input tokens and $9.00 per million output as of May 2026, so a multi-thousand-token prompt on every turn adds up at volume. The docs suggest a compact custom prompt or passing only the schema fragments you need through systemPromptFragments.

Third, on-device limits. If you target an on-device LLM, the full schema prompt may not fit, so plan for a trimmed catalog. Teams weighing model cost against capability should read our LLM hybrid routing and API-spend decision framework before wiring a frontier model into every screen.

None of this is a reason to ignore A2UI. It is a reason to prototype now and productionize when the format stabilizes.

India-specific considerations

For Indian product teams, the client/server split has a data-protection angle. In the GenUI A2UI setup, user input travels to a remote agent that decides what UI to return, so if that input includes personal data you must account for the Digital Personal Data Protection Act, 2023 (DPDP): where the agent runs, what it retains, and whether processing has a lawful basis. The catalog model helps, because the client, not the remote agent, still owns rendering, branding, and accessibility.

The upside is real for teams shipping to a wide device range across Bharat. One agent can compose the right form for a feature phone-class Android and a flagship alike, using your own widget catalog, without a store update per layout change. Flutter teams already running the Flutter 3.44 production upgrade have the baseline to try GenUI behind a feature flag.

FAQ

How eCorpIT can help

eCorpIT (eCorp Information Technologies Private Limited), founded in 2021 in Gurugram, is a CMMI Level 5 and MSME-certified engineering organisation with senior-led Flutter and AI teams and partnerships across Google, AWS, and Microsoft. We help product teams evaluate generative UI safely: designing a trusted widget catalog, wiring the GenUI SDK to a server-side A2UI agent, keeping the client in control of branding and DPDP-aligned data handling, and shipping it behind a feature flag rather than betting a release on an alpha package. If you want a build-or-wait recommendation for your app, talk to our Flutter team.

References

  1. Introducing A2UI: an open project for agent-driven interfaces, Google Developers Blog (Dec 15, 2025)
  1. GenUI SDK for Flutter, official Flutter docs
  1. Get started with the GenUI SDK for Flutter, Flutter docs
  1. A2UI project on GitHub, Google
  1. Flutter GenUI SDK on GitHub
  1. A2UI protocol site and quickstart
  1. genui package on pub.dev
  1. Google introduces A2UI, MarkTechPost (Dec 22, 2025)
  1. AG UI protocol and CopilotKit
  1. What's new in Flutter 3.44, Flutter blog
  1. MCP Apps announcement, Model Context Protocol blog (Nov 21, 2025)
  1. Gemini pricing 2026, CloudZero

_Last updated: July 26, 2026._

Frequently asked

Quick answers.

01 What is the Flutter GenUI SDK?
The GenUI SDK for Flutter is an orchestration layer, a suite of packages that coordinates information between your user, your Flutter widgets, and an AI agent. It uses a JSON format to compose UI from your existing widget catalog, turning a text conversation into interactive screens. As of June 2026 the genui package is in alpha.
02 What is the A2UI protocol?
A2UI (Agent-to-UI) is an open, Apache 2.0 protocol Google made public on December 15, 2025. It defines how an agent describes a user interface as declarative JSON so a client can render it with native widgets. It is framework-agnostic, with early renderers for Flutter, Web Components, and Angular, and is at format version 0.8.
03 How does A2UI keep agent-generated UI secure?
A2UI is a declarative data format, not executable code. Your client keeps a catalog of trusted, pre-approved components, and the agent can only request components from that catalog. Because the model never ships runnable code, the approach reduces UI injection risk compared with sandboxing remote HTML or JavaScript inside an iframe.
04 How do I add my own widgets?
Define a JSON schema with the json_schema_builder package, wrap it in a CatalogItem with a name and a widget builder, then add that item to your SurfaceController catalog. Finally, update the system prompt so the agent knows the widget's name and when to generate it. The model cannot generate anything outside your catalog.
05 Which AI models work with GenUI?
GenUI can connect through Firebase AI Logic for a client-only app, through a GenUI A2UI adapter for a client/server agent, or through a custom adapter for any LLM. The official get-started example uses gemini-3.5-flash, but A2UI is model-neutral, so any agent that emits valid A2UI messages can drive the UI.
06 How is A2UI different from MCP Apps?
MCP Apps, added on November 21, 2025, treat UI as a resource fetched via a ui:// URI and usually render pre-built HTML in a sandboxed iframe. A2UI is native-first: the agent sends a blueprint of native components that your client renders with its own widgets, so the UI inherits your styling and accessibility rather than living in a sandbox.
07 Is GenUI ready for production?
Not for most teams yet. The Flutter docs mark the genui package as experimental and likely to change, and A2UI is at version 0.8. The system prompt from PromptBuilder.chat() can run 3,000 to 5,000 tokens, which raises cost and can break small models. Prototype now, productionize once the format stabilizes.
08 What does the heavy system prompt cost?
PromptBuilder.chat() can emit a 3,000 to 5,000 token system prompt on every request. With Gemini 3.5 Flash at about $1.50 per million input tokens as of May 2026, that overhead is small per call but compounds at scale. The docs recommend a compact custom prompt or trimming to only the schema fragments your feature needs.

About the author

Manu Shukla

Founder & Director

Founder of eCorpIT. Hands-on engineer leading senior-only delivery for AI apps, custom software, and cloud systems for global clients.

Subscribe

One engineering note a week. No fluff, no spam.

Senior-architect playbooks on AI agents, mobile apps, cloud, security, data, and marketing — delivered every Wednesday.

Past the reading

Read enough. Let's build something.

A senior architect responds in 24 working hours with scope, indicative cost, and a timeline. NDA before any technical conversation.