BayHop
Generative UI · Bay Area transit

The assistant answers in interface, not text.

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.

15
generative components
3
swappable LLM clients
4
platforms · iOS · Android · web · macOS
9:41
Downtown Berkeley
SFO
TRY ASKING
Nearby
Home
Work
Generating result…
Planning routes across BART
Downtown Berkeley SFO
3 routes · leave now · BART
MORE ROUTES
Embarcadero
Upcoming departures
Updated 9:42
Red
SFO / Millbrae
Platform 1
4
min
Yellow
Antioch
Platform 2
6
min
Blue
Dublin / Plsntn
Platform 1
9
min
Red
Richmond
Platform 2
12
min
Green
Berryessa
Platform 1
17
min
Yellow
Millbrae
Platform 2
19
min
Yellow Line
Minor Delays
Trains are running about 8–12 minutes apart between Pittsburg/Bay Point and SFO after an earlier equipment problem. Allow a little extra time this morning.
Updated 9:42
ALL LINES
Red
Good service
Blue
Good service
Green
Good service
Orange
Good service
Muni Metro
Good service
Caltrain
Minor Delays
A normal chat app
"Take the Red Line from Downtown Berkeley. It departs at 9:47 from Platform 2, arrives SFO 10:38, then walk 4 min to the terminal. Fare $11.95…"
A wall of text you have to parse yourself.
A2UI
BayHop, a GenUI app
Downtown Berkeley SFO
3 routes · leave now · BART
MORE ROUTES
The GenUI engine

A query becomes a typed UI spec — then live Flutter widgets.

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.

your message
GenUiSession
Combines catalog + system prompt and adds per-turn context: time, location, itinerary.
conversation.dart
→ prompt
ModelClient
Default Inception Mercury 2 streams back A2UI JSON chunks, not prose.
inception_model_client.dart
→ A2UI
Transport adapter
A2uiTransportAdapter feeds chunks into the SurfaceController as they arrive.
genui · SurfaceController
→ render
genui Surface
Live Flutter widgets — only ever the widgets registered in the catalog.
home_page.dart · Surface
The catalog

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.

The prompt

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.

Two surfaces, one engine

A two-tab experience.

Each tab builds its own GenUI session with its own catalog and prompt — over a shared IndexedStack shell that owns location and itinerary state.

🚆
Transit
lib/home_page.dart

A full-bleed OpenStreetMap map with a draggable, frosted bottom sheet that hosts the live generated UI.

Journey cards — origin → destination options with a step-by-step timeline and a colored route drawn on the map.
Live departure boards — real-time BART + 511 SIRI data, 60s cache and 30s auto-refresh, with labeled fallback rows.
Service alerts — delays and disruptions surfaced as their own card type.
🧭
Explore
lib/explore/explore_page.dart

A "Bay Area Explorer" that turns a vibe or neighborhood into a transit-friendly mini-adventure.

Place cards — grounded in Google Places (New) — real venues with ratings, price, hours and photos.
Exploration branches — the model suggests directions to drill into ideas.
Persistent itinerary — saved locally, then handed off to the Transit tab to be routed in order.
Grounded in real data

The cards are live, not mock.

Departures, places and routes are pulled from public transit and mapping APIs. Missing optional keys degrade per feature — the app still launches.

BART real-time api.bart.gov
Live departures with a 60-second cache and 30-second auto-refresh.
Works out of the box
511 SF Bay Open Data SIRI feed
Muni, Caltrain, AC Transit, ferries and other monitored operators beyond BART.
Optional · KEY_511
Google Places (New) Places API v1
Real place cards in Explore and place search in Transit.
Optional · key
OpenStreetMap flutter_map
Map background and route overlay via the public OSM tile server.
Built in
Explore · generative UI

Turn a vibe into a generated mini-adventure.

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.

1
A vibe becomes a surface
The Explore prompt steers the model to emit a hero, a summary and a place mosaic — not a paragraph.
2
Places are real
Every card is grounded in Google Places (New): ratings, price, hours and photos for actual venues.
3
Build, then route
Add stops to a persistent itinerary saved with shared_preferences, then hand it off to Transit to route in order.
The 7-component catalog · explore_catalog.dart
hero summary mosaic plan option place_search note
Plan a playful Oakland food crawl
Hero · Oakland
A playful Oakland food crawl
Four hops from Uptown to Jack London Square — snacks, a rooftop, and dessert — all reachable on the 12th St BART hub and the B / NL bus.
Branch the plan
More like this Nightlife nearby Cheap eats Make it rainy-day
Place mosaic · Google Places
Snail Bar
Snail Bar
★ 4.6 · $$ · Open · til 11pm
+
Kingston 11
Kingston 11
★ 4.5 · $$ · Open · til 10pm
+
Tara’s Organic
Tara’s Organic
★ 4.7 · $ · Closes 9pm
+
Your itinerary · 4 stops
Saved locally · handoff to Transit
Route in order →
Pluggable model clients

One interface. Swap the model in a line.

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.

InceptionModelClient
inception_model_client.dart
Model
mercury-2
API key
INCEPTION_API_KEY
Default · wired in
GeminiModelClient
gemini_model_client.dart
Model
gemini-3.5-flash
API key
GEMINI_API_KEY
Opt in
FeatherlessModelClient
featherless_model_client.dart
Model
Qwen2.5-72B-Instruct
API key
FEATHERLESS_API_KEY
Opt in
The BayHop design system

Atoms compose into cards the model can request.

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.

LineBullet — auto-contrast transit lines
Red Yellow Blue Green Orange
Caltrain N Judah T Third
JourneyStrip — segments · transfers · walk legs
walk 3m walk 4m
walk 3m walk 4m
Embarcadero
Upcoming departures
Updated 9:42
Red
SFO / Millbrae
Platform 1
4
min
Yellow
Antioch
Platform 2
6
min
Blue
Dublin / Plsntn
Platform 1
9
min
Red
Richmond
Platform 2
12
min
Green
Berryessa
Platform 1
17
min
Yellow
Millbrae
Platform 2
19
min
Yellow Line
Minor Delays
Trains are running about 8–12 minutes apart between Pittsburg/Bay Point and SFO after an earlier equipment problem. Allow a little extra time this morning.
Updated 9:42
ALL LINES
Red
Good service
Blue
Good service
Green
Good service
Orange
Good service
Muni Metro
Good service
Caltrain
Minor Delays
Build on it

Running in two commands.

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.

Flutter + Dart 3.12 — single codebase across mobile, web and desktop.
genui package — A2UI rendering, surfaces, transport and catalog API.
flutter_map + geolocator — OSM map, route overlay and nearest-stop lookup.
shared_preferences — local persistence for the Explore itinerary.
very_good_analysis — zero-issue static analysis and a green test run.
# clone & configure keys
cp .env.example .env
# at minimum, set INCEPTION_API_KEY
flutter pub get
flutter run -d chrome \
--dart-define-from-file=.env
Keys are baked in as compile-time constants via --dart-define — they never live in source control.