Streaming a coding agent's UI in Flutter: what broke and how we fixed it GetPullRequest streams a coding agent's replies, tool cards and diffs into its Flutter phone app by flattening typed Agent Client Protocol JSON-RPC frames into a single string per agent turn, then parsing that string back into structured data with a tag parser, a streaming JSON parser and a namespace-based widget registry. The company abandoned Flutter's GenUI package because it only renders UI after the model's full response has arrived and been parsed, which is unworkable for coding agent turns that can run for twenty minutes; GenUI's README has listed streaming UI support as a future consideration since August 2025. GetPullRequest adapted the `` tag syntax from the `streaming_gen_ui` Flutter package and modified it to make live streaming work. We turned a perfectly good protocol back into a string, and I'd probably do it again How GetPullRequest streams a coding agent's replies, tool cards and diffs into a Flutter app live, why Flutter's GenUI didn't fit, and what we changed in streaming gen ui to make it work. I want to talk about the dumbest-looking decision in our Flutter app, because I've gone back and forth on it more times than I'd like to admit, and because defending it taught me most of what I now know about how Flutter behaves under pressure. Some context first. We build GetPullRequest https://www.getpullrequest.com . A coding agent Claude Code, Codex, Cursor, whatever you already pay for runs on your own machine, and you watch it and talk to it from your phone. The phone app is Flutter. The agent speaks the Agent Client Protocol https://agentclientprotocol.com , which means everything it does arrives as nicely typed JSON-RPC frames: here's a piece of my reply, here's a piece of my reasoning, I've started a tool, that tool's status changed. Typed frames. Clean discriminated unions. Exactly what you'd want. And the first thing our app does with them is flatten them into one long string. The string Every agent turn gets its own Stream