Skip to content

Conversation

@dflantz
Copy link

@dflantz dflantz commented Jan 21, 2026

useUITree Hook

Overview

This MR adds a new hook for iteratively managing UI tree state when patches come from external sources rather than a dedicated fetch endpoint.

Motivation

The existing useUIStream hook is tightly coupled to its own fetch lifecycle:

const { tree, send } = useUIStream({ api: "/api/generate" });
send("Create a dashboard"); // fetches from /api/generate

The use case I am working on relies on supporting patches from non-api sources and iterating on an existing tree without incurring a full regeneration.

API

import { useUITree } from "@json-render/react";
import type { JsonPatch } from "@json-render/core";

function Dashboard() {
  const { tree, applyPatch, setTree, clear } = useUITree();

  // Apply patches from your stream
  const handlePatch = (patch: JsonPatch) => {
    applyPatch(patch);
  };

  return <Renderer tree={tree} registry={registry} />;
}

Notes

  • This would be 90% unnecessary if applyPatch was exported, but I wasn't sure if that change would be pattern-breaking / if it is better practice to expose a hook here

  • I purposefully avoided making changes to useUIStream() to reduce scope, but if there is appetite for consolidating the tree management layer into its own exportable primitive and reusing it within useUIStream() I'm happy to work on that too.

(Also happy to help with docs if this ends up being considered)

Adds useUITree hook for managing UI tree state when patches come from
external sources (e.g., AI SDK, WebSocket) rather than a dedicated endpoint.

Benefits:
- initialTree option enables iteration on existing trees within a conversation
- Transport-agnostic: patches can come from any source, not just fetch
@vercel
Copy link
Contributor

vercel bot commented Jan 21, 2026

Someone is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

applyPatch already returns a new object, so the spread was creating
an unnecessary extra allocation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant