I built a 20 kB React hook that doesn't care which AI you use — here's how streaming actually works
title: "🔥 Building a Provider-Agnostic React Hook for AI Streaming" date: 2026-05-10 tags:
- react
- ai
- frontend
- fullstack
- react-hooks image: "https://images.unsplash.com/photo-1627398242454-45a1465c2479?w=1200&q=80" share: true featured: false description: "Learn how to create a lightweight, provider-agnostic React hook for AI streaming, allowing for seamless switching between different AI providers without rewriting the frontend."
Introduction
When building AI-powered chat applications with React, developers often rely on libraries that are tightly coupled to specific AI providers, such as OpenAI or Claude. However, this approach can lead to vendor lock-in, making it difficult to switch providers or migrate to a different platform. In this article, we'll explore how to build a provider-agnostic React hook that can stream AI chat data from any provider, without requiring significant changes to the frontend code.
The traditional approach to building AI-powered chat applications involves using a library that is specifically designed for a particular AI provider. These libraries often stream data directly from the provider's API, using a thin client on top of the provider's backend. However, this approach can be limiting, as it requires rewriting the frontend code whenever the AI provider is changed or the application is migrated to a different platform.
Main Body
So, how can we build a React hook that can stream AI chat data from any provider, without being tied to a specific backend or platform? The key insight is that streaming AI chat is fundamentally just three events: data, end, and error. By focusing on these events, we can create a hook that is agnostic to the underlying provider.
Here's an example of how we can implement this hook:
import { useState, useEffect } from 'react';
const useAiChat = (provider: any) => {
const [messages, setMessages] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const handleData = (data: any) => {
setMessages((prevMessages) => [...prevMessages, data]);
};
const handleEnd = () => {
console.log('Chat session ended');
};
const handleError = (error: any) => {
setError(error);
};
provider.on('data', handleData);
provider.on('end', handleEnd);
provider.on('error', handleError);
return () => {
provider.off('data', handleData);
provider.off('end', handleEnd);
provider.off('error', handleError);
};
}, [provider]);
return { messages, error };
};
In this example, the useAiChat hook takes a provider object as an argument, which is expected to emit data, end, and error events. The hook uses the useState and useEffect hooks to manage the chat session state and handle the events emitted by the provider.
By using this hook, we can easily switch between different AI providers, without requiring significant changes to the frontend code. For example, we can use the hook with OpenAI, Claude, or any other provider that emits the data, end, and error events.
Conclusion
In this article, we've seen how to build a provider-agnostic React hook for AI streaming, allowing for seamless switching between different AI providers without rewriting the frontend. By focusing on the fundamental events of AI chat streaming, we can create a hook that is flexible, reusable, and easy to maintain. Whether you're building a chat application with React or migrating to a different platform, this hook can help you to simplify your code and reduce vendor lock-in. So, go ahead and give it a try – your future self will thank you!