---
name: bijection-openui-convex
description: "Evaluate and integrate the OpenUI Generative UI component with Bijection."
---

# OpenUI Generative UI

Durable, reactive state for OpenUI generated interfaces on Convex. Forms keep their values across reloads and stay in sync across clients.

This is an upstream package. It has not been adapted or qualified for Bijection.

- Package: openui-convex
- Source: https://github.com/aayush962/openui-convex
- npm: https://www.npmjs.com/package/openui-convex
- Directory: https://bijection.com/components/openui-convex

Read the upstream README for setup, license, and compatibility before using it.

## Integration workflow

1. Read the source README and package manifest at the recorded revision.
2. Confirm the required SDK, dependency availability, and runtime compatibility.
3. Follow the component's documented setup and configuration. Never invent an npm install command from a catalog package name.
4. Keep credentials in the project's existing secret store.
5. Follow the project's execution rules for verification and report what was actually checked.

## Original upstream skill

The following guidance describes openui-convex. Its installation commands and APIs refer to the upstream package. Evaluate compatibility with the Bijection source separately.


> Agents: read this skill fully before writing code that uses OpenUI Generative UI. Follow the installation and configuration steps exactly.

# OpenUI Generative UI

## Instructions

Use OpenUI Generative UI to persist and sync openui generated interface state across reloads and clients using a single convex table with debounced writes and conflict resolution. This Convex component integrates directly with your backend.

### Installation

```bash
npm install openui-convex
```

Current npm version: `openui-convex@0.1.1`

### Capabilities

- Retain form values and interactive state in generated UIs across page reloads without any client-side storage logic
- Synchronize interface state across multiple browser clients with last-write-wins versioning and focus-aware remote update deferral
- Integrate with Convex Agent by scoping state to thread and message IDs so thread authorization automatically guards interface state
- Control rendering, actions, and AI generation yourself while the hook handles hydration, debouncing, and snapshot encoding

## Examples

### how to persist OpenUI generated form state across page reloads in Convex

The openui-convex package provides a useOpenUIState React hook that loads a saved snapshot from Convex before mounting the Renderer, so the form hydrates from persisted state instead of defaults. It debounces writes at 400ms by default and encodes the state as a JSON envelope to handle OpenUI's $binding keys, which Convex would otherwise reject as invalid object keys.

### how to sync AI generated UI state across browser tabs with Convex

openui-convex stores state as a single record keyed by (scopeKey, messageId) with a version counter. The useOpenUIState hook subscribes each interface to its own record and defers applying remote snapshots while the user has focus or a write is in flight, then applies them after. This keeps two open windows consistent without clobbering in-progress edits.

### add persistent state per assistant message with Convex Agent

When using Convex Agent for streaming, pass the thread ID as scopeKey and the message key as messageId to useOpenUIState. The component stores one snapshot per assistant message and guards access through your own checkRead and checkWrite authorization hooks, so thread-level access control also applies to interface state.

### how to clean up generated UI state for a deleted thread in Convex

The openui-convex server helper clearState deletes one interface or an entire scope, processing at most 100 records per call and returning hasMore when more remain. You can use ctx.scheduler.runAfter(0) inside an internalMutation to chain calls until the scope is fully cleared without hitting transaction size limits.

## When NOT to use

- When a simpler built-in solution exists for your specific use case
- If you are not using Convex as your backend
- When the functionality provided by OpenUI Generative UI is not needed

## Troubleshooting

**Does openui-convex handle authorization, or is that my responsibility?**

Authorization is your responsibility. The OpenUI Convex component cannot access ctx.auth directly, so you must wrap its API by instantiating OpenUI and passing checkRead and checkWrite hooks that enforce your own access rules. You then export the resulting getState, setState, and clearState functions from your convex/ directory and expose only those to the browser.

**What happens to state if the user closes the tab before the debounce window completes?**

openui-convex attempts a best-effort flush on unmount and on the pagehide event, but a closed tab or lost connection can lose the last debounce window of edits. The default debounce is 400ms, and you can call the flush() method returned by useOpenUIState before app-controlled navigation to guarantee pending writes are committed.

**How does openui-convex handle conflicts when two clients write at the same time?**

openui-convex uses last-write-wins with a version counter. Every write increments the version, and the hook ignores any incoming snapshot older than the version it already saved. There is no merge strategy because the component is designed for form state, not collaborative text editing.

**What are the storage limits for a single generated interface snapshot?**

Each snapshot is limited to 64 KiB of JSON. Writes exceeding that limit or containing malformed data are rejected before reaching storage. The state is stored as a JSON envelope with the key openuiEncoding set to json-v1, which the hook and server helpers encode and decode automatically.

**Does openui-convex add any runtime dependencies to my project?**

openui-convex has no runtime dependencies. The convex package is a peer dependency, and react is an optional peer dependency used only by the openui-convex/react entry point. You import the React hook separately from the server helpers, so server-only code does not pull in React.

## Resources

- [npm package](https://www.npmjs.com/package/openui-convex)
- [GitHub repository](https://github.com/aayush962/openui-convex)
- [Live demo](https://github.com/aayush962/openui-convex/tree/main/example)
- [Convex Components Directory](https://www.convex.dev/components/openui-convex)
- [Convex documentation](https://docs.convex.dev)