# GenUI Overview

> The entry point for building generative UI (GenUI) applications in Flutter — what GenUI is, who decides what, and the three pieces you assemble.

- Source: https://engineering.verygood.ventures/ai/genui/overview/

---

Generative UI, or GenUI for short, **is the process by which an LLM assembles a user interface in real time**.

GenUI enables the **hyper-personalization of user experiences**: a tailored interface for each user and their context.

These are the main actors in a GenUI setup:

- An LLM deciding what interface should be displayed. This can and should be informed by whatever context might be relevant for the particular application.
- A backend. While it's technically possible to get a frontend to talk directly to the LLM, this architecture has all sorts of issues, as discussed below.
- A frontend rendering what the LLM has decided to display to the user.

GenUI can be implemented using many different technical stacks, but for Flutter the Google team has the [official GenUI SDK](https://github.com/flutter/genui), which implements the open source [A2UI protocol](https://a2ui.org/).

#### What GenUI is not

It is easy to be confused by the nuances of what GenUI is and is not.

For example, using an AI assistant at **build time** to generate a **single interface** that is the same for every user is not GenUI.

Similarly, if your server is choosing what interface to display to your users from **a finite number of templates**, that is not GenUI either. It's Server-Driven UI (SDUI).

Please note that there is nothing wrong with either approach. Both serve a purpose and fill a particular need very well.

## The LLM

The LLM is the engine of GenUI experiences. Let's go over the pieces it requires to do its job.

### A model

A2UI is a JSON-based format, and all major providers support structured output, so any of them will work with the official GenUI SDK.

When trying things out you can use almost any model, but once you are past the basics and ready to move on to the next step, you should carefully assess your options. To help you in that regard, VGV maintains a [GenUI Model Benchmark](https://verygood.ventures/resources/genui-benchmarks/) comparing the most common models on the market.

### An objective

Every application has a _purpose_, and GenUI applications need to make that purpose explicit to the LLM through the system prompt.

As an example, imagine a booking flow for a travel agency. We need to tell the LLM what its objective is:

> You are a travel assistant and your objective is helping the user get to a booking in the fewest steps possible. Before allowing the user to move on to payment, you **MUST** gather the following information: number of guests, city of departure, destination, start and end dates.

You can and should provide extra information to help the LLM make the right choices:

> Most of our users alternate between two modes: browsing and booking. If the user is browsing you should favor visual catalog items that allow users to really feel and learn about destinations, including comparing them. If they are ready to book you should present a minimalistic interface that allows them to provide the information required for a booking.

### A catalog

Once the LLM understands what the objective is, it needs the means to fulfill it. **The catalog provides the LLM with a list of catalog items (components) to achieve its purpose**.

Technically, the catalog is a set of JSON schemas that describe components of your design system.

It is important to distinguish:

- Catalog item: a JSON schema representation of a design system component and its properties. **IMPORTANT**: you don't have to make every component, or every property of a component, available to the LLM. See below.
- Component: an actual visual implementation of a catalog item. For Flutter these will be widgets.

The LLM decides which catalog items are presented to the user, their order, and the content assigned to them. **The LLM does not generate code or just any type of markup**. It returns structured JSON using the components and their respective configuration defined in the catalog.

**Anything not in the catalog or in the schema of a catalog item is unreachable to the LLM.** For example, you may have a component in your design system that wraps a form to delete items from a database. **If you don't provide a catalog item for that component, the LLM can't use it because it's not aware that it even exists**.

For more information on how to build your catalog you can read [The Chemistry of GenUI](https://verygood.ventures/blog/the-chemistry-of-genui/).

## The backend

While it might be OK for local tests, **we strongly recommend against connecting your frontend GenUI application directly to an LLM**.

A backend built for GenUI applications should:

- Keep LLM API keys and configuration safe.
- Keep the system prompt and message history free from tampering.
- Be the single source of truth for the system prompt and catalog.
- Monitor token costs and third-party abuse.
- Validate message inputs and LLM responses.
- Provide both static and dynamic context to the LLM.
- Broker the integration of the LLM with your API through tool calling, including bespoke response mapping and data filtering.
- Enable advanced techniques such as dynamic catalog resolution.

## The frontend

The frontend is in charge of rendering the interface that the LLM has chosen. It does so by mapping catalog items to builders that configure and return real Flutter widgets.

One important thing to note is that **GenUI doesn't require a new architecture**. You can treat the LLM as another data source and the GenUI SDK as another API client. For detailed information on how to organize Flutter GenUI applications you can read [GenUI Meets the VGV Architecture](https://verygood.ventures/blog/flutter-genui-meets-the-vgv-architecture/).

Please note that not all of your application has to be GenUI-driven. You can limit the GenUI experience to specific screens or flows. You have full control over what is handed over to the LLM.
