Like MCP - but for your app’s UI

Let your users
personalize the UI
as they like.

Your users just describe the page they want, and AI builds it for them on the spot. You stay in control: it can only use the data and actions you allow.

AMTP
0+ builders already joined

Three steps. That’s the whole thing.

STEP 01

You set the rules

Declare the data and actions your app allows in plain natural language. Pass the real implementations; they remain completely private to your server.

veneer.config.js
const registry = {
dataSources: [{ id: 'tasks' }],
actions: [
{ id: 'createTask', desc: 'Create task.' },
{ id: 'updateTask', desc: 'Update task.' }
]
};
STEP 02

Users describe it

Your users just say how they want the page to look. No settings to dig through, no templates to memorize—Veneer invents the layout on the fly.

USER REQUEST

“Show me a board of my tasks grouped by due date, with high priority tasks at the top”

compiling sandboxed UI…
STEP 03

AI builds it, safely

Generated code runs in a sandboxed interpreter that can only describe what to draw. The model can style anything, but can only invoke the native functions you exposed.

SECURE SANDBOX BOUNDARY
Origin Handshake✔ VERIFIED
Capability Registry✔ SECURE
Data Source Bridge✔ ENFORCED
Live · this is the real open-source package running

Try it yourself, right here

Below is an ordinary task app built with the @veneer/react. Click the button in the corner and tell the AI how you want it to look. Everything it invents runs inside the sandboxed canvas.

app.yoursaas.com/tasks
Adding a task deletion like “add a delete button” will be politely refused, because no deleteTask is registered.
Why Veneer

One app. A perfect fit for everyone.

A manager wants a dashboard; a teammate just wants today’s checklist. Instead of building both, you ship the pieces — and each person shapes the page to fit how they work, while you stay in control of what’s possible.

Kanban

Full creative freedom over the UI

Change the UI to your liking with AI

Hard security sandbox

An interpreter with no browser in it, an allowlisted renderer, a validated bridge — three independent layers.

veneer.action('updateTask')

MCP for the UI layer

A typed, described capability surface the model composes against.

Per-user & private

Each person's layout is saved to their own browser. Nobody else sees it.

$ npm i @veneer/react @veneer/server

Open-source React package

A provider, a canvas, a hook. Drop them in and you're live. (Note: Package naming is a placeholder subject to change on release.)

Bring your own model

One endpoint returns { code, reply }. Use any LLM you like.

The security model

Free-form code. Bounded power.

The model can write anything. It still can’t do anything you didn’t allow. Three independent layers enforce the same contract, plus a static scan before any code runs, a CPU deadline on every entry, and a watchdog that terminates the worker and resets the canvas if a generation ever hangs.

1

An interpreter, not a browser

QuickJS (WebAssembly) · Web Worker

Generated code runs in a JavaScript interpreter inside a Web Worker. There is no window, document, fetch, location or cookie in there — not blocked, simply nonexistent. All it can do is describe what to draw.

2

Allowlisted rendering

ops → allowlist → your DOM

Your page redraws that description with its own React. Only safe elements, attributes and styles pass; links, images, scripts, url() and anything that could escape the canvas are dropped. Tailwind is compiled per view and scoped to the canvas.

3

Validated bridge

veneer.action(id) → registry.actions[id]

Every action is checked against the registry — id, declared args, types, rate — before the real implementation runs. Only declared return values and registered data cross back into the interpreter.

deleteTask→rejected on every layer

No deleteTask is registered, so the scanner refuses the code before it runs, the interpreter has no network to reach your API, and the bridge rejects the call. Deletion fails on every layer.

For developers

Three components. Your real implementations.

No new backend, no source-code delivery, no rebuild. Register what your app can do in plain natural language, hand over the functions, and drop in the open-source package.

  • Typed capability surface
    Data sources and actions, each described for the model and enforced by id at runtime.
  • Your code stays yours
    You pass the real implementations. The model never sees them — only the registry.
  • Model-agnostic
    One endpoint returns { code, reply }. Wire up Gemini, Claude, or anything else.
  • Persisted per user
    Generated UI is saved under a per-user storage key and reloaded automatically.
page.jsx
// 1. Register the capabilities your app exposes const registry = { dataSources: [ { id: 'tasks', description: 'The user’s tasks.' } ], actions: [ { id: 'createTask', description: 'Create a task.' }, { id: 'updateTask', description: 'Update a task.' }, // no deleteTask → generated UIs can never delete ], }; // 2. Pass the REAL implementations + live data <VeneerProvider registry={registry} actions={actions} data={{ tasks }}> <VeneerCanvas minHeight={620} /> <YourChatBox /> // built on useVeneerGenerate() </VeneerProvider>

That’s the whole integration. The registry is the contract; the sandbox is the guarantee.

If you know MCP, you already get Veneer.

MCP gives an AI model a typed, described set of capabilities to work with. Veneer is the same idea — just pointed at your interface.

MCP

Model Context Protocol

Lets a model use the tools and data your systems expose — through one typed, described surface. It can only ever call what’s on it.

  • Exposes your tools & data
  • Each described in plain language
  • The model can only call what you exposed
Veneer

An MCP for the UI layer

The exact same shape — but the surface is your interface. The model composes a real UI against your registered data and actions, inside a sandbox.

  • Exposes your data sources & actions
  • Each described in plain language
  • The model can only use what you registered
Same protocol-shaped idea: a typed capability surface the model composes against. MCP points it at your tools — Veneer points it at your UI.
FAQ

Questions, answered.

Is the generated code actually safe to run?+

That’s the core of the product. Generated code runs in a JavaScript interpreter (QuickJS compiled to WebAssembly) inside a Web Worker, where window, document, fetch, location and cookies simply do not exist. It can only describe what to draw; your page redraws that through an allowlist that drops links, images, scripts and url() styles, and a bridge that only runs actions you registered with the args you declared. Code is statically scanned before it runs, every entry has a CPU deadline, and if a generation ever hangs the worker is terminated, the canvas is reset and your app is notified. Only push data you would show that user on screen anyway — the SDK docs spell out every residual.

Do I have to ship my source code?+

No. You keep your code and pass the real action implementations into the provider. The model only ever sees the registry’s plain-English descriptions and ids — never your implementations.

Which AI model does it use?+

Whichever you want. Your generator endpoint returns { code, reply }, so you can wire up Gemini, Claude, or any other model. The demo uses gemini-2.5-flash.

Can a user break something or delete data?+

Only if you registered an action for it. If there is no deleteTask in the registry, the scanner refuses code that calls it and the bridge rejects the call at runtime. Registered actions are validated against their declared args and rate-limited before your implementation runs.

How does the waitlist work?+

Veneer is in private beta. Join the waitlist and we’ll send an invite as access opens up in batches — no spam, just your invite.

Give your users a canvas,
not just a theme picker.

Rethink the last mile of software delivery. Ship the primitives — let your users design the interface they actually want. Join the waitlist for early access.

AMTP
0+ builders already joined