How to Integrate Claude API into React Apps
October 26, 2025
The Claude API requires server-side authentication. The @anthropic-ai/sdk cannot be used directly in React client code due to security concerns. Instead, create a backend API endpoint that proxies requests to Claude.
Install the Claude SDK
Install the official Anthropic SDK in your backend project.
1.npm install @anthropic-ai/sdk
Create a Backend API Endpoint
Set up a Node.js/Express endpoint to handle Claude API requests. Store your API key in environment variables.
1.// backend/server.js2.import Anthropic from '@anthropic-ai/sdk';3.import express from 'express';4.import cors from 'cors';5.6.const app = express();7.app.use(cors()); // Enable CORS for React frontend8.app.use(express.json());9.10.const client = new Anthropic({11. apiKey: process.env.ANTHROPIC_API_KEY,12.});13.14.app.post('/api/chat', async (req, res) => {15. try {16. const { message } = req.body;17.18. const response = await client.messages.create({19. model: 'claude-sonnet-4-5-20250929',20. max_tokens: 1024,21. messages: [{ role: 'user', content: message }],22. });23.24. res.json({ response: response.content[0].text });25. } catch (error) {26. res.status(500).json({ error: error.message });27. }28.});29.30.app.listen(3001, () => console.log('Server running on port 3001'));
Install the CORS package: npm install cors. This allows your React frontend to communicate with the backend from a different origin.
Use specific model snapshots like claude-sonnet-4-5-20250929 for production to ensure consistent behavior. You can also use aliases like claude-sonnet-4-5 which automatically point to the latest version.
Call Backend from React Component
Create a React component that calls your backend endpoint to communicate with Claude.
1.import { useState } from 'react';2.3.function ChatWithClaude() {4. const [message, setMessage] = useState('');5. const [response, setResponse] = useState('');6. const [loading, setLoading] = useState(false);7.8. const sendMessage = async () => {9. setLoading(true);10. try {11. const res = await fetch('/api/chat', {12. method: 'POST',13. headers: { 'Content-Type': 'application/json' },14. body: JSON.stringify({ message }),15. });16.17. const data = await res.json();18. setResponse(data.response);19. } catch (error) {20. console.error('Error:', error);21. } finally {22. setLoading(false);23. }24. };25.26. return (27. <div>28. <input29. value={message}30. onChange={(e) => setMessage(e.target.value)}31. placeholder="Ask Claude..."32. />33. <button onClick={sendMessage} disabled={loading}>34. {loading ? 'Thinking...' : 'Send'}35. </button>36. {response && <p>{response}</p>}37. </div>38. );39.}

Enable Streaming Responses
For a ChatGPT-like streaming experience, set stream: true and handle the stream in your backend.
1.// Backend with streaming2.app.post('/api/chat-stream', async (req, res) => {3. const { message } = req.body;4.5. res.setHeader('Content-Type', 'text/event-stream');6. res.setHeader('Cache-Control', 'no-cache');7. res.setHeader('Connection', 'keep-alive');8.9. const stream = await client.messages.create({10. model: 'claude-sonnet-4-5-20250929',11. max_tokens: 1024,12. messages: [{ role: 'user', content: message }],13. stream: true,14. });15.16. for await (const event of stream) {17. if (event.type === 'content_block_delta') {18. res.write(`data: ${JSON.stringify(event.delta)}\n\n`);19. }20. }21.22. res.end();23.});

Handle API Errors
Wrap API calls in try-catch blocks and handle rate limits, invalid requests, and network errors.
1.const sendMessage = async () => {2. setLoading(true);3. setError(null);4.5. try {6. const res = await fetch('/api/chat', {7. method: 'POST',8. headers: { 'Content-Type': 'application/json' },9. body: JSON.stringify({ message }),10. });11.12. if (!res.ok) {13. throw new Error(`HTTP error! status: ${res.status}`);14. }15.16. const data = await res.json();17. setResponse(data.response);18. } catch (error) {19. setError('Failed to get response. Please try again.');20. console.error('Error:', error);21. } finally {22. setLoading(false);23. }24.};
Set Environment Variables
Never expose your API key in client code. Store it in a .env file on the server.
1.# .env2.ANTHROPIC_API_KEY=your-api-key-here
Access it in Node.js using process.env.ANTHROPIC_API_KEY.
What You Can Build Now
With Claude integrated into your React app, you can build AI-powered features like chatbots, content generators, code assistants, text summarizers, or customer support tools. The streaming support enables real-time conversational interfaces, and the backend proxy pattern keeps your API key secure while allowing full control over request validation and rate limiting.
More JavaScript Snippets
Popular Articles
I Can't Believe It's Not CSS: Styling Websites with SQL
Style websites using SQL instead of CSS. Database migrations for your styles. Because CSS is the wrong kind of declarative.

How I Built an Oreo Generator with 1.1 Sextillion Combinations
Building a web app that generates 1,140,145,285,551,550,231,122 possible Oreo flavor combinations using NestJS and TypeScript.

AI Model Names Are The Worst (tier list)
A comprehensive ranking of every major AI model name, from the elegant to the unhinged. Because apparently naming things is the hardest problem in AI.