///
Better UI is built around a few fundamental concepts that streamline the development of AI-first tools with integrated user interfaces. These concepts ensure type-safety, robust execution, and seamles
39 views
~39 views from guests
Guest views are estimated from total page views. These include anonymous visitors and users who weren't logged in when they viewed the page.
Better UI is built around a few fundamental concepts that streamline the development of AI-first tools with integrated user interfaces. These concepts ensure type-safety, robust execution, and seamless visual feedback, bridging the gap between AI capabilities and human interaction. For an overarching perspective on the framework, refer to the [Better UI Overview].
The tool function is the entry point for creating any capability within Better UI. It's where you formally declare a tool's identity, purpose, and the structure of its data. This definition serves as a contract for both human developers and AI models, making the tool discoverable and predictable.
A tool definition formally declares:
name for identification.description that explains its functionality, crucial for AI models to understand when to use it.input and output schemas, defining the exact data types and structures the tool expects and produces.tags for categorization and cache settings for performance.Tools can be defined using either a configuration object or a fluent builder API:
zod schemas for input and output, Better UI provides end-to-end type-safety. This means your code benefits from compile-time checks, and runtime data is automatically validated, significantly reducing errors and improving code reliability.name and description fields are directly consumable by AI SDKs (via tool.toAITool()), allowing AI models to intelligently select and execute the appropriate tool based on user prompts.cache configuration allows you to define caching strategies for tool results, improving performance by avoiding redundant computations or API calls for frequently requested data.The server implementation defines the core logic of a tool that must run in a secure, backend environment. This is where a tool can interact with sensitive resources such as databases, environment variables, or other backend services.
To encapsulate the privileged operations of a tool that require server-side execution due to security concerns, access to non-public APIs, or intensive computational requirements.
You define the server-side logic using the .server() method on your tool instance:
ctx object provided to the server handler includes server-only context such as ctx.env (environment variables), ctx.headers (request headers), ctx.cookies, ctx.user, and ctx.session. This allows your tool logic to leverage the full capabilities of your backend environment.The client implementation allows you to define custom logic for a tool that runs directly in the browser. This is useful for scenarios requiring immediate feedback, optimistic updates, or interactions with browser-specific APIs.
To specify how a tool should behave when executed from a client-side environment. This can involve custom data fetching, optimistic UI updates, or leveraging client-side caching mechanisms.
You define the client-side logic using the .client() method on your tool instance:
ctx.optimistic function (client-only) allows you to update the UI immediately with an assumed result, improving perceived performance while the actual operation completes in the background..server() implementation but no .client() implementation, Better UI will automatically make an API call to a designated endpoint (defaulting to /api/tools/execute) to trigger the server-side execution and fetch its results. This ensures that server-only tools are still callable from the client in a secure manner without any extra code from the developer. This automatic behavior simplifies integrating server-side tools into client-side UIs.ctx object for client handlers includes ctx.cache (a client-side cache for deduplication) and ctx.fetch (a customizable fetch function).The view implementation is the core differentiator of Better UI. It allows you to define a React component that dictates how a tool's results are rendered in the user interface. This integrates presentation directly with functionality, making tools truly AI-first and UI-aware.
To provide a built-in, customizable React component that automatically renders the output of a tool. This ensures that every tool, once executed, has a visual representation, whether invoked by an AI or a human.
You define the view component using the .view() method on your tool instance:
Once defined, this view component can be directly rendered in your React application:
weather tool, and its results are not just returned as raw data but are immediately presented to the user through a rich, pre-defined UI component.tool definition becomes a single source of truth for its logic, data schemas, and presentation. This significantly reduces development overhead and ensures consistency across your application. You define a tool once, and it brings its UI with it.data but also the loading and error states, allowing for sophisticated loading indicators and error messages. Crucially, it also receives an onAction callback, enabling users to interact with the rendered tool (e.g., increment a counter, refine a search) which can trigger a re-execution of the tool with updated inputs.tool.View component is memoized internally, ensuring it only re-renders when its core visual props (data, loading, error) actually change, optimizing performance in dynamic environments like AI chat streams..view() for a tool, the tool.View component will intelligently fall back to rendering the raw JSON output, which is helpful for debugging and ensures that every tool always has some visual feedback.