I’m not a professional writer, and this is a relatively new problem space, so I’ll do my best to explain it.
I think a lot of developers are overlooking this because Generative UI isn’t standard yet, but once you run into it, it becomes incredibly frustrating.
For those unfamiliar, Generative UI (GenUI) usually means an AI agent sending a view definition (often JSON) to the frontend. The frontend renders components based on that definition and wires actions back to the agent.
These views are inherently temporary. The moment you refresh the page or the agent regenerates the layout, the previous structure is often replaced.
The upside is amazing. Interfaces in complex apps can adapt instantly to your workflow.
Need three extra fields? No problem.
Prefer the data displayed in a table instead of cards? Done.
But this flexibility introduces a serious problem.
The Ephemerality Gap
I started calling this problem The Ephemerality Gap.
Maybe someone has used the term before, but here’s how I define it:
The barrier to Generative UI adoption isn’t streaming tokens or model latency.
It’s data loss.
Imagine a user filling out a 50-field form that an AI just generated.
Halfway through they realize they need one more field. They ask the AI to add it.
The AI tries to be helpful and regenerates the interface.
And suddenly every single input they typed is gone.
Not because the user deleted it.
Not because the AI meant to delete it.
The framework simply rebuilt the UI and wiped the state.
Why “just store it in a database” doesn’t work
A lot of people suggest:
“Just save the user’s data in a database.”
It doesn’t work like that.
This problem behaves much closer to a git merge than a simple database read/write.
The UI structure itself is evolving every time the agent modifies the interface.
The technical problem
Most UI frameworks track state by matching structural keys.
If the structure changes enough, the framework assumes the old nodes are gone and resets everything.
Current View Definition
{
"section": {
"key": "section_1",
"children": [
{
"key": "input_2",
"type": "string",
"value": "John Doe"
}
]
}
}
Agent returns a new view
The AI decides to wrap the input in a new group or change the hierarchy.
{
"section": {
"key": "section_1",
"children": [
{
"group": {
"key": "group_99",
"children": [
{
"key": "input_3",
"type": "select",
"value": "???"
}
]
}
}
]
}
}
Because the keys or types no longer match the previous frame, the framework essentially says:
“I don’t know what this is. Delete it.”
The nodes reset and your data disappears.
If the keys match but the types change (for example string → object), the application can even crash at runtime.
This is the Ephemerality Gap: the disconnect between user intent and the constantly changing structural state of the UI.
The approach
The solution I landed on is conceptually simple:
User state must be durable and separate from the view structure.
Instead of tying user data to UI nodes, the system tracks user input using persistent semantic identity.
Whenever the view structure changes, a reconciliation step compares:
• the previous view
• the new view
• the user’s current state
If a piece of data no longer maps to the new view, we don’t delete it.
We detach and store it safely.
If the AI later reintroduces that control, the data is immediately rehydrated.
If the AI tries to overwrite something the user typed, it goes into a suggestion cache and the user can choose whether to accept it.
The AI doesn’t get to clobber user input.
What I built
I built a runtime for this called Continuum.
It’s a new layer in the stack that sits between the AI agent and your frontend framework.
• TypeScript based
• Framework agnostic
• 100% open source
• React starter kit (you can run a demo in about 10 minutes)
• Openai, Google, Ahthropic adapters included in the starter-kit (all open source)
GitHub
https://github.com/brytoncooper/continuum-dev
Website
https://continuumstack.dev
Curious if others have hit this yet
If you’re building agent-driven interfaces, how are you handling state persistence when the UI isn’t hardcoded?
Are you:
• storing everything server-side
• locking the layout after generation
• building your own reconciliation layer
If you’re interested, try the repo and break it.
Fork it.
Report bugs.
Tell me why this idea is terrible.
I’d genuinely like to see how other people are approaching this problem.
Top comments (0)