Flutter GenUI Tutorial: Build an AI Shopping Assistant

Learn to build an AI-powered Flutter shopping assistant using the GenUI SDK.

Jorge Coca
Jorge Coca
Jorge Coca
February 27, 2026
3min
News
Flutter GenUI Tutorial: Build an AI Shopping Assistant

Flutter developers have done a lot to integrate AI into their apps, and somehow the best most of us have managed is replacing a search bar with a chatbot. The user asks a question, and the AI responds with a wall of text. That is not the experience anyone envisioned when they first heard "AI-powered app."

When I walked through this problem at the Flutter SF Meetup hosted by SoFi recently, the reaction confirmed what we have been seeing in our own projects at VGV: Flutter developers are ready to move past plain-text AI responses and into real, interactive interfaces that the AI itself assembles. At VGV, we have been building AI-powered Flutter experiences since before GenUI existed as a library. Projects like Ask Dash, a generative AI Flutter app we built with Google, taught us the pattern early. When we saw the Flutter GenUI SDK, we recognized it immediately: this is how you go from an LLM that talks to one that build.

Image taken by Frank van Puffelen (puf) during the Flutter SF Meetup hosted by SoFi.

This post is the beginner-friendly companion to that talk. You will get just enough context to understand what GenUI is, and then we will go straight into building a working shopping assistant with it. The full source is available in the genui_shopping_assistant repository on Github; clone it now if you want to follow along.

Why Text Responses Are Not Enough

Most AI-powered apps today respond with plain text. A user asks "show me running shoes under $150" and gets a wall of text listing options. GenUI flips this: instead of text, the AI assembles real, interactive Flutter widgets (product cards, filters, carousels) on the fly, using your own design system. The user sees a rich UI, not a chat log.

GenUI Flutter shopping assistant — text response vs. interactive product cards generated by GenUI

Before we build anything, it helps to understand the limitation GenUI is designed to fix.

What Is The Flutter GenUI SDK?

At its core, GenUI does one thing:

GenUI is a Flutter library that lets an AI build your app's UI in real time, using your widgets, your brand rules, and the user's context and intent to power the experience.

Three concepts are all you need to get started:

1. You Define A Widget Catalog

The AI can only compose from widgets you have explicitely registered: product cards, buttons, filters, and so on. Your brand stays intact. This is the key insight: the catalog is the contract between your app and the AI.

2. The AI Assembles The UI As JSON

The LLM does not generate Dart code. It returns structured data that GenUI deserializes into real Flutter widgets at runtime. This is the mechanism that powers the A2UI (App-to-UI) protocol, a structured contract where the AI describes intent, and the client renders it natively.

Flutter GenUI SDK — AI-generated JSON deserialized into interactive Flutter widgets at runtime

3. Interactions Feed Back To The AI

When the user taps, selects, or types, that state goes back to the LLM, which can refine the UI. This loop is what makes GenUI generative rather than just dynamic

GenUI Flutter interaction loop — user taps trigger state updates sent to the LLM, which refines the generative UI

You can explore these concepts in depth in the official GenUI SDK documentation and the GenUI SDK components and concepts reference. Note that the SDK is experimental and the API is still evolving. Treat it accordingly, and get yourself ready for breaking changes in future releases.

For a deeper look at how Flutter GenUI is being applied to real-world products, see how we are redefining the digital booking experience with Generative UI at VGV.

Building The Shopping Assistant: A Step-By-Step Flutter GenUI Tutorial

The best way to understand how these three pieces fit together is to build something real. Here is how to get the shopping assistant running.

A screenshot of the Shopping Assistant demo powered by GenUI

Prerequisites

Before you start, make sure you have:

  • Flutter SDK in the latest stable version: the genui package requires Dart 3.9 or later, shipped with Flutter 3.35.
  • A Firebase project with Firebase AI Logic enabled. While you can run this experience with a Spark free plan, a Blaze plan is recommended, as the token consumption limit will be more generous.
  • Clone the VGV genui_shopping_assistant repository from Github, run flutter pub get, and finish the connection with Firebase running flutterfire configure.

Note on API stability: the genui package is in alpha (v0.7.0 when this article is posted). The API is subject to breaking changes between releases. This is expected for an experimental SDK at this stage. Check the flutter/genui repository for the latest release notes before starting.

Define Your Widget Catalog

A Catalog is a collection of CatalogItem objects that tells the AI exactly which widgets it can compose. Think of it as the contract between your app and the AI: if a widget is not in the catalog, the AI cannot use it. Your design system is enforced at runtime.

Each CatalogItem requires three things: a name, a dataSchema (defined with json_schema_ builder) that tells the AI what data the widget expects, and a widgetBuilder function that turns data into a real Flutter widget.

Here is a simplified product card entry from the shopping assistant:

1import 'package:genui/genui.dart';
2import 'package:json_schema_builder/json_schema_builder.dart';
3
4// The schema tells the AI what data a ProductCard expects.
5// Mark required fields explicitly so the AI produces valid data.
6final _productSchema = S.object(
7  properties: {
8    'name': S.string(description: 'Product display name.'),
9    'price': S.number(description: 'Price in USD.'),
10    'imageUrl': S.string(description: 'URL of the product image.'),
11  },
12  required: ['name', 'price', 'imageUrl'],
13);
14
15final productCard = CatalogItem(
16  name: 'ProductCard',
17  dataSchema: _productSchema,
18  widgetBuilder: ({
19    required data,
20    required id,
21    required buildChild,
22    required dispatchEvent,
23    required context,
24    required dataContext,
25  }) {
26    final json = data as Map<String, Object?>;
27    // Build and return your ProductCard widget here,
28    // using json['name'], json['price'], json['imageUrl'].
29  },
30);

To register this item alongside the built-in GenUI core widget, pass it to A2uiMessageProcessor:

1_processor = A2uiMessageProcessor(
2  // CoreCatalogItems includes GenUI's built-in widgets.
3  // copyWith appends your custom items without replacing the core set.
4  catalogs: [CoreCatalogItems.asCatalog().copyWith([productCard])],
5);

Now that the catalog is defined, we need to connect it to an LLM.

Set Up The LLM Connection

The ContentGenerator is the bridget between your Flutter app and the AI. It decouples your app from a specific LLM provider, which matters when the model landscape is moving fast. For this tutorial, we will use FirebaseAiContentGenerator.

Flutter GenUI ContentGenerator — GoogleGenerativeAiContentGenerator and FirebaseAiContentGenerator bridging Flutter and the LLM
1/// Creates and configures a [FirebaseAiContentGenerator] backed by Firebase AI
2/// (Gemini 2.5 Flash).
3///
4/// The catalog schema is automatically sent to the AI via tool definitions.
5/// History and state management are handled by [GenUiConversation].
6FirebaseAiContentGenerator buildFirebaseAiContentGenerator() {
7  return FirebaseAiContentGenerator(
8    catalog: shoppingCatalog,
9    systemInstruction:
10        shoppingSystemInstructions + GenUiPromptFragments.basicChat,
11  );
12}

With the LLM connected, it is time to wire everything together.

Wire It Together And Run

The final step is creating a GenUiConversation, connecting it to the processor and content generator, and embedding a GenUiSurface in your widget tree. GenUiConversation is the primary facade that manages the back and forth between your app and the AI.

1@override
2void initState() {
3  super.initState();
4  _processor = A2uiMessageProcessor(
5    catalogs: [CoreCatalogItems.asCatalog().copyWith([productCard])],
6  );
7  _conversation = GenUiConversation(
8    a2uiMessageProcessor: _processor,
9    contentGenerator: contentGenerator,
10    // Track which UI surfaces the AI creates and removes.
11    onSurfaceAdded: (update) =>
12        setState(() => _surfaceIds.add(update.surfaceId)),
13    onSurfaceDeleted: (update) =>
14        setState(() => _surfaceIds.remove(update.surfaceId)),
15  );
16}
17
18@override
19void dispose() {
20  // Always dispose the conversation to avoid resource leaks.
21  _conversation.dispose();
22  super.dispose();
23}
24
25// In your build method, render each surface:
26GenUiSurface(
27  host: _conversation.host,
28  surfaceId: surfaceId,
29)
30
31// To send a user prompt:
32_conversation.sendRequest(
33  UserMessage.text('Show me running shoes under \$150'),
34);

Launch the app, type a prompt like "Show me running shoes under $150", and watch GenUI assemble a product browsing experience from your catalog widgets. The AI reads your catalog, generates a JSON layout referencing ProductCard and other registered widgets, and GenUI deserializes it into your actual Flutter components.

Check the genui package on pub.dev for the current version and changelog.

Where To Go From Here

You just built a working AI shopping assistant that renders real Flutter widgets from natural-language prompts. No chat bubbles, no text walls — just an actual product browsing experience composed by the AI from your own design system.

Here are a few directions to explore next:

  • Extend your catalog: try adding a price filter chip, a product comparison view, or a checkout summary widget. Each new CatalogItem expands what the AI can compose, and because the catalog is the contract, your brand controls stay intact.
  • Try a different LLM provider: implement a custom ContentGenerator that connects to a different model. The abstraction is there specifically because the model landscape will keep changing.
  • Explore the official docs: the GenUI SDK getting started guide covers advanced topics including the A2UI protocol, streaming AI updates, and custom ContentGenerator implementations.
  • See GenUI in a production context: read how VGV is redefining the digital booking experience with generative UI, or explore our GenUI solutions resource page for a business-oriented perspective on what this technology enables across retail, travel, banking, and QSR.

This kind of problem (making AI a native part of your product's UX layer, not just a featured bolted on) is exactly where we focus at VGV. We have shipped AI-powered Flutter experiences with Google across industries, and we have been working with Flutter since its early days. If you are thinking through what GenUI means for your product, we would be glad to think through it with you.

Name of the heading

Category
Flutter
Genui
Tutorial
Dart
Design
VGV
Share