Ask "Downtown Berkeley → SFO, leave now" and a language model streams back real Flutter cards — trip plans, live departure boards, place lists, service alerts — rendered live on top of an interactive map.
Your message goes to the model and comes back not as prose but as a structured description of an interface. The genui package renders that description into widgets on screen.
What the model can build. The model can only ever describe widgets you've registered — so it can never ask for something the app can't draw. BayHop ships 8 transit and 7 explore components.
How the model should behave — persona, tone, domain rules. One system prompt per tab. Reshape most of the experience by editing just the catalog and the prompt; everything else is plumbing.
Each tab builds its own GenUI session with its own catalog and prompt — over a shared IndexedStack shell that owns location and itinerary state.
A full-bleed OpenStreetMap map with a draggable, frosted bottom sheet that hosts the live generated UI.
A "Bay Area Explorer" that turns a vibe or neighborhood into a transit-friendly mini-adventure.
Departures, places and routes are pulled from public transit and mapping APIs. Missing optional keys degrade per feature — the app still launches.
Ask "Plan a playful Oakland food crawl" and the Explore prompt drives the model to compose a whole surface — a hero, a summary, a mosaic of real places, branches to drill deeper, and an itinerary you can route. Seven components, assembled on demand.
Every provider sits behind one ModelClient abstraction that owns conversation history and exposes the streaming response. To switch, pass a different modelClientBuilder — nothing else changes.
A fixed palette, transit-line bullets, a blue→purple AI gradient, and Space Grotesk / Hanken Grotesk / JetBrains Mono type. The same tokens render every generated card.
Targets macOS, iOS, Android and web on the Flutter SDK shipping Dart 3.12. BART real-time departures work out of the box; other keys are optional.