Skip to content

Fable UI

Trusted product UI for AI, without letting the model invent the product.

Live MVP with installable surfaces, typed tools, manifests, and a working playground.

New Chat

Fable UI playground

Click the arrow button to try this demo.

I kept seeing the same awkward moment in AI products.

A user asks for a number, some records, or a refund. The assistant understands the request, then answers with a paragraph, a markdown table, or a confident sentence where a real interface should be.

The language is intelligent. The product suddenly feels missing.

Fable UI started from one question:

How can an agent use product UI without being allowed to invent the product?

The problem

Chat is good when intent is still messy. It is good for asking, explaining, and narrowing a problem.

It is weaker as the final surface for structured work. A number needs hierarchy. Records need search and filters. A risky action needs an explicit confirmation state.

Letting the model generate arbitrary UI at runtime creates the opposite problem. Now the model is acting as designer, frontend engineer, and security boundary at once. That may be useful in a sandbox. I would not make it the default inside a product with real users and permissions.

So the problem was not chat versus UI.

It was finding the right boundary between flexible intent and trusted interaction.

The contract

The component alone was not enough.

A useful Fable surface travels with its contract:

  • React UI
  • a Zod payload schema
  • an AI SDK tool definition
  • safe loading, empty, error, and invalid states
  • a model-facing manifest
  • examples and eval prompts
  • guidance for when another surface should win

The model can choose a surface and provide typed intent. The host still owns authentication, authorization, data access, validation, business rules, and side effects.

That gives the agent agency, not authority.

How it works

The runtime is deliberately small.

The model selects an installed tool. Its payload is validated. A renderer maps the streamed tool state to the installed React component. Unknown tools and invalid payloads fall back safely instead of crashing the conversation.

The same boundary applies to data. The model may select an allowlisted resource such as orders. It can see safe fields, filters, and sorting options. It never sees private endpoints, Firestore paths, secrets, or permission rules. The host resolves the resource using its own user and organization context.

This matters during streaming because tool input can be partial. It also matters later because old conversations may contain a tool that the app no longer installs. The render boundary has to stay boring in both cases.

What I built

I built the registry, docs, playground, manifests, renderer helpers, and the first set of installable surfaces:

  • MetricCard for one important number
  • charts for trends and comparisons
  • tables and DataBrowser for records
  • FormCard for small structured inputs
  • ConfirmationCard before host-owned actions
  • SuggestedActions for safe conversation paths
  • optional REST and Firebase adapters for registered resources

The surfaces are narrow on purpose. A metric should not pretend to be a table. A form should not become a whole application. A confirmation records a decision, but it never grants permission.

Decisions

Copy and own the source. Tool descriptions, schemas, and manifests change product behavior. Teams should be able to inspect and tune them instead of trusting a black box.

Use the shadcn registry before building a CLI. The distribution model already existed. I wanted to spend the early work on the contract, not another installer.

Validate at the render boundary. Model output is input, not trusted component props.

Keep data and actions host-owned. Fable can carry safe intent. It should not become a database abstraction, permission system, or hidden backend.

Test selection, not only rendering. A perfect metric card is still a product failure if the model chooses it for "show the last ten orders."

Stay protocol-light. AG-UI, A2UI, and MCP Apps are useful layers. Fable first needs to prove that one installed surface can be selected, rendered, and owned well.

Limits

Fable UI is a working MVP, not a proven standard.

The first surfaces need more installation tests inside real products and existing design systems. Selection quality also needs repeatable eval runs across models and prompt changes.

The current examples are strongest in Next.js with the Vercel AI SDK. Portability is part of the direction, but I do not want to claim it before the adapters exist.

There is also a natural scope limit. Long transactions, complex workflows, and domain permission models still belong to the host application. That is both a constraint and the reason the boundary stays trustworthy.

What proves it

The next milestone is not a bigger component count.

It is the full external loop: install a surface into several Next.js apps, replace the demo data with authorized host data, exercise every renderer state, tune the manifest, and run selection prompts that catch regressions.

If that works, Fable UI has proved both sides of its idea:

  • developers can own the surface
  • models can choose it reliably enough to help

The durable model is simple: the agent expresses intent, the registry exposes trusted surfaces, and the host enforces reality.