Hashbrown Development Skill
Overview
Hashbrown is a React library for building LLM-powered applications with generative UI, client-side tool calling, streaming, and sandboxed JavaScript execution. It provides React hooks (useChat, useUiChat, etc.) that connect to a Node.js backend adapter, which securely communicates with LLM providers (OpenAI, Anthropic, Google, Azure, Bedrock, Ollama).
Architecture: React frontend (using Hashbrown hooks) + Node.js backend adapter (proxies LLM API requests)
Quick Start Workflow
1. Choose the Right Hook
| Hook | Multi-turn Chat | Single Input | Structured Output | Tool Calling | Generate UI |
|---|---|---|---|---|---|
useChat | ✅ | ❌ | ❌ | ✅ | ❌ |
useStructuredChat | ✅ | ❌ | ✅ | ✅ | ❌ |
useCompletion | ❌ | ✅ | ❌ | ✅ | ❌ |
useStructuredCompletion | ❌ | ✅ | ✅ | ✅ | ❌ |
useUiChat | ✅ | ❌ | ✅ | ✅ | ✅ |
2. Generate Boilerplate
Use the scripts to scaffold components and servers:
# List available templates python scripts/list-templates.py # Generate a component python scripts/generate-component.py simple-chat ./src/components # Generate a backend server python scripts/generate-server.py basic-chat-server ./backend
Available component templates:
- •
simple-chat- Basic text-only chat withuseChat - •
ui-chat-with-components- Generative UI withuseUiChatandexposeComponent - •
client-side-tool-calling- Tool calling withuseTool - •
js-runtime-chart-generator- Sandboxed JS execution for data visualization - •
structured-data-form- Form generation from natural language with Skillet schemas - •
streaming-chat-ui- Streaming responses with loading states - •
multi-threaded-chat-ui- Multi-conversation management with threads - •
predictive-text-input- Autocomplete/suggestions powered by LLM - •
chat-with-voice-input- Voice input with speech recognition
Available server templates:
- •
basic-chat-server- Simple Express server with OpenAI adapter - •
streaming-chat-server- Streaming support for real-time responses - •
chat-server-with-data- Server with database/context injection - •
chat-server-with-threads- Persistent conversation threads - •
server-with-authentication- Auth-protected endpoints
3. Consult References for Details
Load reference documentation as needed for deep implementation details:
- •getting-started.md - Installation, setup, hook overview
- •core-concepts.md - Generative UI, tool calling, JS runtime, streaming
- •structured-data.md - Skillet schema language for type-safe JSON output
- •platform-integration.md - LLM provider adapters (OpenAI, Anthropic, Google, etc.)
- •advanced-guides.md - Chatbots, threads, MCP, predictive actions
- •best-practices.md - Prompt engineering, model selection, ethics
- •INDEX.md - Navigation map of all documentation
Core Capabilities
1. Generative UI
Expose React components to the LLM so it can render your UI dynamically.
import { useUiChat, exposeComponent } from '@hashbrownai/react'
import { s } from '@hashbrownai/core'
import { MyCard } from './MyCard'
const exposedCard = exposeComponent(MyCard, {
name: 'MyCard',
description: 'A card to display information',
props: { title: s.string('The title'), content: s.string('The body') },
})
const { messages } = useUiChat({
components: [exposedCard],
model: 'gpt-4',
system: 'Render cards to show information to the user.',
})
// messages[1].ui will contain <MyCard title="..." content="..." />
When to use: Build browser agents, dynamic dashboards, form builders, or any UI that should adapt based on LLM decisions.
Reference: See core-concepts.md for detailed component exposure patterns.
2. Client-Side Tool Calling
Allow the LLM to call client-side functions to access app state or perform actions.
import { useChat, useTool } from '@hashbrownai/react'
const getUserTool = useTool({
name: 'getUser',
description: 'Get current user information',
handler: async () => ({ name: 'Jane Doe' }),
deps: [],
})
const { messages } = useChat({
tools: [getUserTool],
model: 'gpt-4',
})
When to use: Let the LLM access application state, trigger actions, or interact with external APIs.
Reference: See core-concepts.md for tool definition patterns.
3. Structured Data Output
Use Skillet schemas to get type-safe, validated JSON from the LLM.
import { useStructuredCompletion } from '@hashbrownai/react'
import { s } from '@hashbrownai/core'
const schema = s.object('Response', {
name: s.string('User name'),
age: s.number('User age'),
interests: s.array('List of interests', s.string('An interest')),
})
const { data } = useStructuredCompletion({
schema,
model: 'gpt-4',
prompt: 'Extract user info: John is 30 and likes hiking and reading.',
})
// data will be typed as { name: string; age: number; interests: string[] }
When to use: Extract structured information, build forms from natural language, parse documents, or transform unstructured text to JSON.
Reference: See structured-data.md for Skillet schema language details.
4. Sandboxed JavaScript Execution
Execute LLM-generated JavaScript safely in a WASM-based QuickJS sandbox.
import { useRuntime, useToolJavaScript, useChat } from '@hashbrownai/react'
const runtime = useRuntime({ functions: [] })
const jsTool = useToolJavaScript({ runtime })
const chat = useChat({ tools: [jsTool], model: 'gpt-4' })
When to use: Let the LLM perform complex calculations, data transformations, or generate visualizations using code.
Reference: See core-concepts.md for runtime configuration.
5. Platform Integration
Connect to any LLM provider via backend adapters:
// Backend server (Node.js)
import { HashbrownOpenAI } from '@hashbrownai/openai'
const stream = HashbrownOpenAI.stream.text({
apiKey: process.env.OPENAI_API_KEY,
request,
})
Supported platforms: OpenAI, Anthropic, Google, Azure, Bedrock, Ollama, Writer, and custom adapters.
Reference: See platform-integration.md for all adapter configurations.
Common Patterns
Building a Chat Interface
- •Generate component:
python scripts/generate-component.py simple-chat ./src - •Generate server:
python scripts/generate-server.py basic-chat-server ./backend - •Wrap app in
<HashbrownProvider url="/api/chat"> - •Customize system prompt and model in component
Adding Generative UI
- •Generate:
python scripts/generate-component.py ui-chat-with-components ./src - •Create presentational React components
- •Expose with
exposeComponent(Component, { name, description, props }) - •Pass to
useUiChat({ components: [...] }) - •Write system prompt instructing when to use components
Implementing Tool Calling
- •Define tools with
useTool({ name, description, handler }) - •Pass to chat hook:
useChat({ tools: [...] }) - •Tools are automatically called by the LLM when needed
- •Tool results are sent back to LLM in the conversation
Streaming Structured Data
- •Use
s.streamingmodifier in Skillet schema:tsxconst schema = s.object('Response', { items: s.streaming.array('Items', s.string('Item')), }) - •Render partial data as it arrives
Pitfalls
- •Forgetting backend adapter: Hashbrown React library requires a Node.js backend to proxy LLM requests
- •Prompt injection: Don't concatenate user input directly into system instructions
- •Over-exposing components: Only expose components that are safe for the LLM to render
- •Unbounded runtime execution: Always provide an
AbortSignalwith timeout to JS runtime - •Wrong hook choice: Use the hook decision table above to pick the right one
Resources
- •scripts/: Template generation utilities (list-templates.py, generate-component.py, generate-server.py)
- •references/: In-depth documentation on all Hashbrown features (load as needed)
- •assets/: Complete component and server templates ready to copy