bodhi-sdk-react-integration
Integrate React+Vite web apps with bodhi-js-sdk for local LLM integration. Use when user asks to: "integrate bodhi", "add bodhi sdk", "connect to bodhi", "setup bodhi provider", "bodhi react integration", "deploy bodhi to github pages", or troubleshoot bodhi-js-sdk connection/auth issues.
Best use case
bodhi-sdk-react-integration is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Integrate React+Vite web apps with bodhi-js-sdk for local LLM integration. Use when user asks to: "integrate bodhi", "add bodhi sdk", "connect to bodhi", "setup bodhi provider", "bodhi react integration", "deploy bodhi to github pages", or troubleshoot bodhi-js-sdk connection/auth issues.
Integrate React+Vite web apps with bodhi-js-sdk for local LLM integration. Use when user asks to: "integrate bodhi", "add bodhi sdk", "connect to bodhi", "setup bodhi provider", "bodhi react integration", "deploy bodhi to github pages", or troubleshoot bodhi-js-sdk connection/auth issues.
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "bodhi-sdk-react-integration" skill to help with this workflow task. Context: Integrate React+Vite web apps with bodhi-js-sdk for local LLM integration. Use when user asks to: "integrate bodhi", "add bodhi sdk", "connect to bodhi", "setup bodhi provider", "bodhi react integration", "deploy bodhi to github pages", or troubleshoot bodhi-js-sdk connection/auth issues.
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/bodhi-sdk-react-integration/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How bodhi-sdk-react-integration Compares
| Feature / Agent | bodhi-sdk-react-integration | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Integrate React+Vite web apps with bodhi-js-sdk for local LLM integration. Use when user asks to: "integrate bodhi", "add bodhi sdk", "connect to bodhi", "setup bodhi provider", "bodhi react integration", "deploy bodhi to github pages", or troubleshoot bodhi-js-sdk connection/auth issues.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Bodhi JS SDK React Integration
Guide for integrating React+Vite applications with bodhi-js-sdk to enable local LLM chat capabilities through the Bodhi Browser ecosystem.
## When to Use This Skill
- User wants to integrate a React app with bodhi-js-sdk
- User needs to add chat/LLM capabilities to their React+Vite app
- User is deploying a bodhi-integrated app to GitHub Pages
- User is troubleshooting SDK connection, authentication, or streaming issues
## Quick Integration Checklist
1. **Install**: `npm install @bodhiapp/bodhi-js-react`
2. **Register**: Create OAuth client at https://developer.getbodhi.app
3. **Wrap App**: Add `<BodhiProvider authClientId={...}>` around your app
4. **Use Hook**: Access `useBodhi()` for client, auth state, and actions
5. **Build UI**: Create chat interface with streaming support
## Core Concepts
### Package Architecture
- `@bodhiapp/bodhi-js-react` - Preset package for web apps (auto-creates WebUIClient)
- `@bodhiapp/bodhi-js-react-ext` - Preset package for Chrome extensions (auto-creates ExtUIClient)
- Both include React bindings + OpenAI-compatible API
### Connection Modes
- **Extension mode**: Via Bodhi Browser extension (preferred)
- **Direct mode**: Direct HTTP to local server (fallback)
- SDK auto-detects and switches modes automatically
### Authentication
- OAuth 2.0 + PKCE flow
- Two auth servers:
- **Dev**: `https://main-id.getbodhi.app/realms/bodhi` (allows localhost)
- **Prod**: `https://id.getbodhi.app/realms/bodhi` (requires real domain)
## Basic Integration Steps
### Step 1: Install Package
```bash
npm install @bodhiapp/bodhi-js-react
```
### Step 2: Wrap App with BodhiProvider
```tsx
// App.tsx
import { BodhiProvider } from '@bodhiapp/bodhi-js-react';
import Chat from './Chat';
const CLIENT_ID = 'your-client-id-from-developer.getbodhi.app';
function App() {
return (
<BodhiProvider authClientId={CLIENT_ID}>
<div className="app">
<h1>My Bodhi Chat App</h1>
<Chat />
</div>
</BodhiProvider>
);
}
export default App;
```
### Step 3: Create Chat Component
```tsx
// Chat.tsx
import { useState, useEffect } from 'react';
import { useBodhi } from '@bodhiapp/bodhi-js-react';
function Chat() {
const { client, isOverallReady, isAuthenticated, login, showSetup } = useBodhi();
const [prompt, setPrompt] = useState('');
const [response, setResponse] = useState('');
const [loading, setLoading] = useState(false);
const [models, setModels] = useState<string[]>([]);
const [selectedModel, setSelectedModel] = useState('');
// Load models on mount
useEffect(() => {
if (isOverallReady && isAuthenticated) {
loadModels();
}
}, [isOverallReady, isAuthenticated]);
const loadModels = async () => {
const modelList: string[] = [];
for await (const model of client.models.list()) {
modelList.push(model.id);
}
setModels(modelList);
if (modelList.length > 0) setSelectedModel(modelList[0]);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!prompt.trim() || !selectedModel) return;
setLoading(true);
setResponse('');
try {
const stream = client.chat.completions.create({
model: selectedModel,
messages: [{ role: 'user', content: prompt }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices?.[0]?.delta?.content || '';
setResponse(prev => prev + content);
}
} catch (err) {
setResponse(`Error: ${err instanceof Error ? err.message : String(err)}`);
} finally {
setLoading(false);
}
};
if (!isOverallReady) {
return <button onClick={showSetup}>Open Setup</button>;
}
if (!isAuthenticated) {
return <button onClick={login}>Login</button>;
}
return (
<div>
<select value={selectedModel} onChange={e => setSelectedModel(e.target.value)}>
{models.map(model => (
<option key={model} value={model}>
{model}
</option>
))}
</select>
<form onSubmit={handleSubmit}>
<input value={prompt} onChange={e => setPrompt(e.target.value)} />
<button type="submit" disabled={loading}>
{loading ? 'Generating...' : 'Send'}
</button>
</form>
{response && <div>{response}</div>}
</div>
);
}
export default Chat;
```
## Key APIs and Hooks
### useBodhi() Hook
```tsx
const {
client, // SDK client instance (OpenAI-compatible API)
isOverallReady, // Both client AND server ready (most common check)
isAuthenticated, // User has valid OAuth token
login, // Initiate OAuth login flow
logout, // Logout and clear tokens
showSetup, // Open setup wizard modal
// Additional properties
isReady, // Client initialized (extension or direct URL)
isServerReady, // Server status is 'ready'
isInitializing, // client.init() in progress
isExtension, // Using extension mode
isDirect, // Using direct HTTP mode
canLogin, // isReady && !isAuthLoading
isAuthLoading, // Auth operation in progress
} = useBodhi();
```
### Client Methods (OpenAI-Compatible)
```tsx
// List models (AsyncGenerator)
for await (const model of client.models.list()) {
console.log(model.id);
}
// Streaming chat
const stream = client.chat.completions.create({
model: 'gemma-3n-e4b-it',
messages: [{ role: 'user', content: 'Hello!' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices?.[0]?.delta?.content || '';
// Append to response
}
// Non-streaming chat
const response = await client.chat.completions.create({
model: 'gemma-3n-e4b-it',
messages: [{ role: 'user', content: 'Hello!' }],
stream: false,
});
```
## Advanced Configuration
### Custom Client Config
```tsx
<BodhiProvider
authClientId={CLIENT_ID}
clientConfig={{
redirectUri: 'https://myapp.com/callback',
basePath: '/app',
logLevel: 'debug',
}}
>
<App />
</BodhiProvider>
```
### basePath for Sub-paths or GitHub Pages
When your app runs on a sub-path (e.g., GitHub Pages at `/repo-name/`):
```tsx
// Vite config
export default defineConfig({
base: '/repo-name/',
});
// BodhiProvider
<BodhiProvider authClientId={CLIENT_ID} basePath="/repo-name" callbackPath="/repo-name/callback">
<App />
</BodhiProvider>;
```
## Common Patterns
### Conditional Rendering
```tsx
function App() {
const { isOverallReady, isAuthenticated, showSetup, login } = useBodhi();
if (!isOverallReady) {
return <button onClick={showSetup}>Setup Required</button>;
}
if (!isAuthenticated) {
return <button onClick={login}>Login Required</button>;
}
return <ChatInterface />;
}
```
### Model Loading with Caching
```tsx
const loadModels = async () => {
const cached = localStorage.getItem('bodhi_models');
if (cached) {
const { models: cachedModels, expiry } = JSON.parse(cached);
if (Date.now() < expiry) {
setModels(cachedModels);
return;
}
}
const modelList: string[] = [];
for await (const model of client.models.list()) {
modelList.push(model.id);
}
setModels(modelList);
localStorage.setItem(
'bodhi_models',
JSON.stringify({
models: modelList,
expiry: Date.now() + 3600000, // 1 hour
})
);
};
```
### Error Handling
```tsx
try {
const stream = client.chat.completions.create({ ... });
for await (const chunk of stream) {
// Process chunk
}
} catch (err) {
if (err instanceof Error) {
console.error('Chat error:', err.message);
setError(err.message);
}
}
```
## Detailed Guides
For comprehensive information on specific topics, see the supporting documentation:
- **[Quick Start Guide](./quick-start.md)** - Complete 5-minute integration walkthrough
- **[OAuth Setup](./oauth-setup.md)** - Dev vs prod environments, client registration
- **[GitHub Pages Deployment](./github-pages.md)** - basePath config, 404 hack, workflows
- **[Troubleshooting](./troubleshooting.md)** - Common issues and solutions
- **[Code Examples](./code-examples.md)** - Copy-paste snippets for common patterns
## SDK Documentation Reference
The bodhi-js-sdk repository contains comprehensive documentation:
- `bodhi-js-sdk/docs/quick-start.md` - Official quick start
- `bodhi-js-sdk/docs/react-integration.md` - Deep dive into React integration
- `bodhi-js-sdk/docs/authentication.md` - OAuth flow details
- `bodhi-js-sdk/docs/streaming.md` - Streaming patterns
- `bodhi-js-sdk/docs/api-reference.md` - Complete API documentation
## Implementation Approach
When user asks to integrate bodhi-js-sdk:
1. **Check existing setup**: Look for package.json, existing React components
2. **Install package**: Run `npm install @bodhiapp/bodhi-js-react`
3. **Add BodhiProvider**: Wrap root component with provider
4. **Create/update components**: Add useBodhi() hook to components
5. **Test connection**: Verify extension detection or direct mode
6. **Add OAuth**: Guide user to register at developer.getbodhi.app
7. **Implement chat**: Create streaming chat interface
8. **Handle errors**: Add proper error boundaries and user feedback
When troubleshooting:
1. **Check connection status**: Use `isOverallReady`, `isReady`, `isServerReady`
2. **Verify auth state**: Check `isAuthenticated`, `auth` object
3. **Inspect logs**: Look for `[Bodhi/Web]` prefixed logs in console
4. **Review config**: Verify authClientId, redirectUri, basePath
5. **Test backend**: Ensure local server at http://localhost:1135
6. **Check extension**: Verify Bodhi Browser extension installed
## Testing Integration
After integration, verify:
1. **Extension detection**: Check console for `[Bodhi/Web] Extension detected`
2. **Server connection**: Verify `[Bodhi/Web] Server ready`
3. **Setup flow**: Click "Open Setup" to test modal
4. **Authentication**: Click "Login" to test OAuth flow
5. **Model loading**: Verify models populate in dropdown
6. **Streaming**: Send message and verify real-time response streaming
7. **Error handling**: Test with server offline to verify error states
## Common Integration Tasks
When user requests:
- **"Add bodhi to my React app"** → Follow basic integration steps
- **"Setup OAuth for bodhi"** → Guide to oauth-setup.md, developer.getbodhi.app
- **"Deploy to GitHub Pages"** → Reference github-pages.md for basePath and 404 hack
- **"Chat not working"** → Check troubleshooting.md for connection/auth issues
- **"Models not loading"** → Verify server, check models endpoint, review async iteration
- **"Streaming broken"** → Verify stream:true, check AsyncGenerator pattern
## Key Files to Reference
When implementing integration:
- `bodhi-js-sdk/docs/quick-start.md` - Primary integration guide
- `bodhi-js-sdk/docs/react-integration.md` - React-specific patterns
- `bodhi-js-sdk/docs/` - Comprehensive documentation and examples
## Notes
- Focus on React+Vite projects only
- Always use `@bodhiapp/bodhi-js-react` preset package (simplest)
- Auto-callback handling is enabled by default (`handleCallback={true}`)
- OAuth callback happens automatically without custom routes
- Default backend: http://localhost:1135
- Extension mode is preferred over direct mode
- AsyncGenerator pattern for streaming (OpenAI-compatible)Related Skills
react-native-design
Master React Native styling, navigation, and Reanimated animations for cross-platform mobile development. Use when building React Native apps, implementing navigation patterns, or creating performant animations.
react-useeffect
React useEffect best practices from official docs. Use when writing/reviewing useEffect, useState for derived values, data fetching, or state synchronization. Teaches when NOT to use Effect and better alternatives.
react-dev
This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned. Covers type-safe patterns for React 18-19 including generic components, proper event typing, and routing integration (TanStack Router, React Router).
stripe-integration
Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.
react-state-management
Master modern React state management with Redux Toolkit, Zustand, Jotai, and React Query. Use when setting up global state, managing server state, or choosing between state management solutions.
react-native-architecture
Build production React Native apps with Expo, navigation, native modules, offline sync, and cross-platform patterns. Use when developing mobile apps, implementing native integrations, or architecting React Native projects.
react-modernization
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
react-flow-node-ts
Create React Flow node components with TypeScript types, handles, and Zustand integration. Use when building custom nodes for React Flow canvas, creating visual workflow editors, or implementing node-based UI components.
react-flow-architect
Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or optimize ReactFlow applications for: (1) Interactive process graphs with expand/collapse navigation, (2) Hierarchical tree structures with drag & drop, (3) Performance-optimized large datasets with incremental rendering, (4) Auto-layout integration with Dagre, (5) Complex state management for nodes and edges, or any advanced ReactFlow visualization requirements.
paypal-integration
Integrate PayPal payment processing with support for express checkout, subscriptions, and refund management. Use when implementing PayPal payments, processing online transactions, or building e-commerce checkout flows.
payment-integration
Integrate Stripe, PayPal, and payment processors. Handles checkout flows, subscriptions, webhooks, and PCI compliance. Use PROACTIVELY when implementing payments, billing, or subscription features.
hubspot-integration
Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects. Covers Node.js and Python SDKs. Use when: hubspot, hubspot api, hubspot crm, hubspot integration, contacts api.