29637
Programming

Migrating Your Flutter GenUI App to Version 0.9.0: A Step-by-Step Guide

Posted by u/Tiobasil · 2026-05-18 20:02:01

Introduction

Generative UI (GenUI) allows your Flutter app to leverage an AI agent that not only generates content but also decides how to display and interact with users. The genui package, built on the A2UI protocol, has recently been updated to version 0.9.0. This update introduces a major architectural shift from a “Structured Output First” approach to a “Prompt First” philosophy, and it decouples the framework into distinct layers—giving you more control over your large language model (LLM) interactions. If you’re migrating an existing app from version 0.7.0, this guide will walk you through every necessary step.

Migrating Your Flutter GenUI App to Version 0.9.0: A Step-by-Step Guide

What You Need

  • An existing Flutter project using package:genui version 0.7.0 or earlier
  • Familiarity with Flutter and Dart
  • Access to an LLM provider (e.g., Google Generative AI, Firebase AI, or a custom endpoint)
  • The latest Flutter SDK and Dart 3.x
  • A code editor (VS Code, Android Studio, etc.)

Migrating Your GenUI App: Step by Step

  1. Step 1: Update the genui package dependency

    Open your pubspec.yaml file and update the genui package to the latest version. Replace the version constraint for genui with ^0.9.0 (or the specific version you need). Also remove any provider-specific packages such as genui_dartantic, genui_google_generative_ai, or genui_firebase_ai—they are no longer needed in version 0.9.0. Then run flutter pub get to fetch the updated dependencies.

  2. Step 2: Remove old ContentGenerator references

    In version 0.7.0, you likely created a ContentGenerator instance (e.g., FirebaseAiContentGenerator) and passed it to a SurfaceController. Search your codebase for any import or usage of ContentGenerator and delete those lines. Because the framework now decouples agent interaction from UI rendering, you no longer need this wrapper class.

  3. Step 3: Set up direct connection to your LLM agent

    Without ContentGenerator, your app is responsible for establishing a connection to your chosen LLM. You can use any HTTP client or SDK (e.g., the google_generative_ai package directly, or a custom REST client). The key is to create a function that sends a prompt (including the A2UI JSON instructions as text) and returns the agent’s response. For example, if you were using Google’s Gemini, instantiate the model and configure generation parameters like temperature and system instructions.

  4. Step 4: Implement an A2UI TransportAdapter

    The new architecture introduces A2uiTransportAdapter as a bridge between your agent and the UI renderer. Create a class that extends or implements this adapter. In your adapter, you’ll define how messages are sent to the agent and how responses (containing the A2UI JSON blocks) are streamed back. For instance, your adapter might call the LLM API, parse the response for JSON blocks, and yield them as A2uiMessage objects. This gives you full control over retry logic, error handling, and chat history.

  5. Step 5: Update SurfaceController to use the new layers

    The SurfaceController (now called the Engine) manages UI state and rendering. In your code, replace the old SurfaceController(…) constructor with the new one. Instead of passing a ContentGenerator, pass your custom A2uiTransportAdapter instance. The controller will automatically listen to the adapter’s stream and update the UI accordingly. You may also need to adjust how you initialize the controller—check the updated documentation for required parameters.

  6. Step 6: Wire up your new chat loop

    With the decoupled architecture, you manage conversation state separately. Create a Conversation facade that holds the chat history and coordinates between the user input and the transport adapter. For example, when the user sends a message, add it to the conversation, call your adapter to generate a response, and then update the conversation with the assistant’s reply. Finally, pass the conversation to your UI widget so that the SurfaceController can render the appropriate widgets.

  7. Step 7: Test and fine-tune your implementation

    Run your app and ensure that the UI renders correctly and that the agent’s responses are displayed as interactive widgets. Verify that error states and retries work as expected. Since you now have direct control over the LLM call, you can adjust generation parameters (temperature, top-p) or even switch providers without changing your UI code. Perform edge-case testing—like empty responses or malformed JSON—to make your app robust.

Tips for a Smooth Migration

  • Start with a simple proof of concept – Before migrating your entire app, create a minimal test project with the new architecture to understand the flow from agent to renderer.
  • Leverage the prompt-first approach – In version 0.9.0, you embed A2UI JSON as text inside the agent’s response. Make sure your system prompt instructs the agent to output valid JSON blocks for widget definitions.
  • Keep your chat history manageable – The new Conversation facade stores history. Implement a strategy to trim old messages (e.g., keep the last N exchanges) to avoid exceeding token limits.
  • Use any LLM provider you prefer – Since you now control the network call, you are no longer tied to a specific provider. Experiment with different models or even local LLMs for testing.
  • Review the A2UI protocol specification – Understanding version 0.9.0 changes in A2UI (e.g., message format) will help you debug unexpected rendering issues.
  • Update your UI widget catalog – The genui package provides a set of default widgets. If you have custom widgets, ensure they comply with the new A2UI schema.

By following these steps, you’ll successfully migrate your Flutter GenUI app to version 0.9.0 and unlock greater flexibility and control over your AI-powered user interfaces.