Artifacts
Advanced streaming interfaces for AI applications. Create structured, type-safe artifacts that stream real-time updates from AI tools to React components with progress tracking and error handling.
npm install @ai-sdk-tools/artifacts
What it does
🌊 Streaming
Stream real-time updates from AI tools to React components with smooth, responsive interfaces.
📊 Progress
Track progress and show loading states as AI tools process requests and generate responses.
🔒 Type Safety
Full TypeScript support with schema validation using Zod for type-safe data structures.
⚡ Performance
Optimized rendering with selective updates and efficient state management.
🛠️ Error Handling
Built-in error handling with retry mechanisms and graceful fallbacks.
🎨 Customizable
Highly customizable with support for custom UI components and styling.
Getting Started
1. Install the package
npm install @ai-sdk-tools/artifacts
2. Create an artifact
import { artifact } from '@ai-sdk-tools/artifacts' import { z } from 'zod' const burnRateArtifact = artifact('burn-rate', z.object({ monthlyBurn: z.number(), runway: z.number(), title: z.string(), stage: z.enum(['loading', 'processing', 'complete']).default('loading'), }))
3. Use in your component
import { useArtifact } from '@ai-sdk-tools/artifacts/client' function BurnRateChart() { const { data, status, error, progress } = useArtifact(burnRateArtifact) if (status === 'error') return <div>Error: {error}</div> if (!data) return <div>Loading...</div> return ( <div> <h2>{data.title}</h2> <p>Monthly Burn: ${data.monthlyBurn.toLocaleString()}</p> <p>Runway: {data.runway} months</p> {progress && <div>Progress: {Math.round(progress * 100)}%</div>} </div> ) }
Features
Schema Validation
Define data structures with Zod schemas for type safety and validation:
const userProfileArtifact = artifact('user-profile', z.object({ name: z.string(), email: z.string().email(), avatar: z.string().url().optional(), preferences: z.object({ theme: z.enum(['light', 'dark']), notifications: z.boolean(), }), }))
Progress Tracking
Track progress and show loading states:
function ProgressBar() { const { progress, status, isActive } = useArtifact(processingArtifact) return ( <div> {isActive && ( <div className="w-full bg-gray-200 rounded-full h-2.5"> <div className="bg-blue-600 h-2.5 rounded-full" style={{ width: `${(progress || 0) * 100}%` }} /> </div> )} <p>Status: {status}</p> </div> ) }
Error Handling
Built-in error handling with retry mechanisms:
const resilientArtifact = artifact('resilient-data', z.object({ data: z.string(), status: z.enum(['idle', 'loading', 'complete', 'error']).default('idle') })) function ResilientComponent() { const { data, status, error } = useArtifact(resilientArtifact, { onError: (error) => { console.error('Artifact error:', error) // Custom error handling }, onComplete: (data) => { console.log('Success!', data) } }) return <div>{status === 'error' ? error : data?.data}</div> }
API Reference
artifact(id, schema)
Create a new artifact definition with schema validation:
import { artifact } from '@ai-sdk-tools/artifacts' import { z } from 'zod' const myArtifact = artifact( 'unique-id', // Unique artifact identifier z.object({ // Zod schema for type safety title: z.string(), data: z.array(z.number()).default([]), status: z.enum(['idle', 'loading', 'complete']).default('idle') }) )
useArtifact(artifact, callbacks?)
Hook for consuming a specific streaming artifact:
import { useArtifact } from '@ai-sdk-tools/artifacts/client' const { data, // Current artifact payload (typed) status, // 'idle' | 'loading' | 'streaming' | 'complete' | 'error' progress, // Progress value (0-1) error, // Error message if failed isActive, // Whether artifact is currently processing hasData, // Whether artifact has any data } = useArtifact(myArtifact, { onUpdate: (data, prevData) => console.log('Updated:', data), onComplete: (data) => console.log('Done!', data), onError: (error) => console.error('Failed:', error), onProgress: (progress) => console.log(`${progress * 100}%`), })
useArtifacts(options?)
Hook for listening to all artifacts across all types. Perfect for switch cases:
import { useArtifacts } from '@ai-sdk-tools/artifacts/client' const { byType, // All artifacts grouped by type latest, // Latest version of each artifact type artifacts, // All artifacts in chronological order current, // Most recent artifact across all types } = useArtifacts({ onData: (artifactType, data) => { console.log(`New ${artifactType} artifact:`, data) } }) // Perfect for rendering different artifact types return ( <div> {Object.entries(latest).map(([type, artifact]) => { switch (type) { case 'burn-rate': return <BurnRateComponent key={type} data={artifact} /> case 'financial-report': return <ReportComponent key={type} data={artifact} /> default: return <GenericComponent key={type} type={type} data={artifact} /> } })} </div> ) // Perfect for Canvas-style switching on current artifact function Canvas() { const { current } = useArtifacts() switch (current?.type) { case 'burn-rate-canvas': return <BurnRateCanvas /> case 'revenue-canvas': return <RevenueCanvas /> default: return <DefaultCanvas /> } }