stream-hooks
v2.0.2
Published
<div align="center"> <a aria-label="NPM version" href="https://twitter.com/dimitrikennedy"> <img alt="stream-hooks" src="https://img.shields.io/twitter/follow/dimitrikennedy?style=social&labelColor=000000"> </a> <a aria-label="GH Issues" href="h
Downloads
1,178
Maintainers
Readme
stream-hooks
stream-hooks
provides React hooks for consuming streams - specifically JSON streams coming from LLMs. Given a Zod Schema that represents the final output, you can start processing structured results immediately as they stream in.
Installation
# pnpm
pnpm add stream-hooks zod zod-stream
# npm
npm install stream-hooks zod zod-stream
# bun
bun add stream-hooks zod zod-stream
Quick Start
import { useJsonStream } from "stream-hooks"
import { z } from "zod"
export function ChatComponent() {
const { loading, startStream, stopStream, data } = useJsonStream({
schema: z.object({
content: z.string()
}),
onReceive: data => {
console.log("incremental update to final response model", data)
}
})
const submit = async () => {
try {
await startStream({
url: "/api/ai/chat",
method: "POST",
body: {
messages: [
{
content: "yo",
role: "user"
}
]
}
})
} catch (e) {
console.error(e)
}
}
return (
<div>
{data?.content}
<button onClick={submit} disabled={loading}>
Start
</button>
<button onClick={stopStream}>
Stop
</button>
</div>
)
}
Key Features
- 🔄 React hooks for streaming LLM responses
- 🎯 Progressive validation and partial results
- 📝 Built-in TypeScript support
- ⚡ Seamless integration with zod-stream
- 🌳 Path completion tracking
- 🔍 Error handling and loading states
Hook Options
interface UseJsonStreamOptions<T extends z.ZodType> {
schema: T; // Zod schema for validation
onReceive?: (data: any) => void; // Progressive update handler
onComplete?: (data: any) => void; // Stream completion handler
onError?: (error: Error) => void; // Error handler
debug?: boolean; // Enable debug logging
}
Progressive Updates
The hook provides real-time updates as data streams in:
const AnalysisComponent = () => {
const { data } = useJsonStream({
schema: z.object({
user: z.object({
preferences: z.object({
theme: z.string(),
language: z.string()
})
}),
content: z.object({
title: z.string(),
body: z.string()
})
}),
onReceive: (chunk) => {
// Start personalizing as soon as preferences are available
if (isPathComplete(['user', 'preferences'], chunk)) {
applyTheme(chunk.user.preferences.theme);
}
// Begin content rendering when title is ready
if (isPathComplete(['content', 'title'], chunk)) {
updateTitle(chunk.content.title);
}
}
});
return <div>{/* Your UI */}</div>;
};
Error Handling
function StreamComponent() {
const { error, reset } = useJsonStream({
schema,
onError: (err) => {
console.error("Stream error:", err);
}
});
if (error) {
return (
<div>
<p>Error: {error.message}</p>
<button onClick={reset}>Retry</button>
</div>
);
}
return <div>{/* Your UI */}</div>;
}
Integration with zod-stream
stream-hooks
works seamlessly with zod-stream
response modes:
import { withResponseModel } from "zod-stream";
// API Route
export async function POST(req: Request) {
const params = withResponseModel({
response_model: {
schema,
name: "Analysis"
},
mode: "TOOLS",
params: {
messages: [{ role: "user", content: "..." }],
model: "gpt-4"
}
});
const completion = await openai.chat.completions.create({
...params,
stream: true
});
return new Response(completion.body);
}
TypeScript Support
The hook provides full type inference:
const schema = z.object({
result: z.string(),
confidence: z.number()
});
// data is fully typed based on schema
const { data } = useJsonStream({
schema,
onReceive: (data) => {
// TypeScript knows the shape of data
console.log(data.result, data.confidence);
}
});
Return Values
interface UseJsonStreamReturn<T> {
data: T | null; // Current stream data
loading: boolean; // Stream status
error: Error | null; // Error state
startStream: (options: FetchOptions) => Promise<void>; // Start streaming
stopStream: () => void; // Stop streaming
reset: () => void; // Reset hook state
}
For more details on the underlying streaming capabilities, check out the zod-stream documentation.