@fronx/use-claude-code
v0.1.3
Published
Library for integrating Claude Code CLI into applications
Downloads
431
Readme
@fronx/use-claude-code
A reusable library for integrating Claude Code CLI conversations into applications.
Features
- Server-side: Spawn and manage Claude CLI processes, handle conversation lifecycle, stream responses via SSE
- Client-side: Parse SSE streams, manage connection state, handle reconnection with exponential backoff
- React:
useClaudeConversationhook for easy integration
Installation
npm install @fronx/use-claude-codePublishing
# 1. Make changes, then build
npm run build
# 2. Bump version in package.json (patch/minor/major)
npm version patch
# 3. Publish (requires npm login as fronx + fingerprint 2FA)
npm publish --access publicUsage
Server (Node.js)
import { ClaudeManager } from '@fronx/use-claude-code/server';
const manager = new ClaudeManager({
sessionDir: './data/sessions',
});
// Start a conversation
const conversation = manager.start('user-123', {
systemPrompt: 'You are a helpful assistant.',
cwd: process.cwd(),
initialMessage: 'Hello!',
});
// Subscribe to SSE events
conversation.subscribe(res);
// Send additional messages
conversation.send('How does this work?');
// Stop generation (SIGINT)
conversation.stop();
// Clear conversation
manager.clear('user-123');Client (Browser)
import { ClaudeConnection } from '@fronx/use-claude-code/client';
const connection = new ClaudeConnection({
baseUrl: '/api/claude',
conversationId: 'user-123',
});
connection.on('stateChange', () => {
console.log('Messages:', connection.messages);
console.log('Streaming:', connection.streamingSegments);
});
connection.on('result', () => {
console.log('Response complete');
});
// Check status and connect
await connection.connect();
// Start a new conversation
await connection.start('Hello!');
// Send a message
await connection.send('How does this work?');
// Stop generation
await connection.stop();
// Clear session
await connection.clear();React
import { useClaudeConversation } from '@fronx/use-claude-code/react';
function Chat({ projectId }) {
const {
messages,
status,
isStreaming,
streamingSegments,
hasPersistedSession,
start,
send,
stop,
clear,
resume,
} = useClaudeConversation({
baseUrl: '/api/claude',
conversationId: projectId,
onResult: () => console.log('Response complete'),
});
return (
<div>
{/* Completed messages */}
{messages.map(msg => (
<div key={msg.id} className={msg.role}>
{msg.content}
</div>
))}
{/* Streaming content */}
{streamingSegments.map((seg, i) =>
seg.type === 'text' ? (
<div key={i}>{seg.content}</div>
) : (
<div key={i}>Running: {seg.name} {seg.param}</div>
)
)}
{/* Resume link for persisted sessions */}
{status === 'disconnected' && hasPersistedSession && (
<button onClick={resume}>Resume Previous Session</button>
)}
{/* Controls */}
<input type="text" id="message" />
<button onClick={() => send(document.getElementById('message').value)}>
Send
</button>
{isStreaming && <button onClick={stop}>Stop</button>}
</div>
);
}API Reference
Server
ClaudeManager
Main class for managing Claude conversations.
interface ClaudeManagerConfig {
sessionDir: string; // Where to persist sessions
claudePath?: string; // Path to claude CLI (default: 'claude')
defaultAllowedTools?: string[]; // Default tools to allow
autoPrewarm?: boolean; // Auto-prewarm after clear (default: false)
}
interface StartOptions {
systemPrompt: string | { file: string };
cwd: string;
allowedTools?: string[];
initialMessage?: string;
}Methods:
start(id, options)- Start a new conversationget(id)- Get an active conversationresume(id, options)- Resume from persisted sessionstop(id)- Stop current response (SIGINT)clear(id)- Kill process and delete sessionprewarm(id, options)- Spawn without sending messagegetStatus(id)- Get conversation statushasPersistedSession(id)- Check for saved session
Client
ClaudeConnection
Event-emitter based connection manager.
interface ClaudeConnectionConfig {
baseUrl: string;
conversationId: string;
reconnect?: {
maxRetries?: number; // Default: 10
baseDelay?: number; // Default: 1000ms
maxDelay?: number; // Default: 30000ms
};
}Properties (read-only):
status- 'checking' | 'disconnected' | 'connecting' | 'connected' | 'reconnecting'messages- Array of completed messagesisStreaming- Whether currently streamingstreamingSegments- Current streaming content (text and tools)hasPersistedSession- Whether a saved session existslastError- Most recent error
Methods:
connect()- Check status and connectdisconnect()- Close connectionstart(message?)- Start new conversationsend(message)- Send messagestop()- Stop generationclear()- Clear sessionresume()- Resume saved sessionprewarm()- Prewarm for faster response
Events:
stateChange- Any state property changedmessage- New message addedstreaming- Streaming segments updatedtool- Tool invocationresult- Response completeerror- Error occurred
React
useClaudeConversation
interface UseClaudeConversationOptions {
baseUrl: string;
conversationId: string;
autoConnect?: boolean; // Default: true
reconnect?: ReconnectConfig;
onResult?: () => void; // Called when response completes
}Returns all ClaudeConnection properties and methods as React state.
HTTP API
The package expects these server endpoints:
| Endpoint | Method | Purpose |
| -------------- | ------ | ------------------------- |
| /:id/status | GET | Check conversation status |
| /:id/start | POST | Start new conversation |
| /:id/connect | GET | SSE stream for updates |
| /:id/message | POST | Send message |
| /:id/stop | POST | Stop generation |
| /:id/clear | POST | Clear session |
| /:id/resume | POST | Resume saved session |
| /:id/prewarm | POST | Prewarm conversation |
Architecture
Streaming
When Claude runs tools, the streaming behavior differs from simple responses:
assistantevents stream the full response contentresultevents may only contain the final portion after tool execution
The state machine accumulates streaming content correctly. Always use streamingSegments for display, not just the result event.
Session Persistence
Sessions are saved to disk after each message, enabling:
- Resume after page reload
- Resume after server restart
- Multi-device continuation
Prewarming
Call prewarm() before the user is likely to start a conversation. This spawns Claude without sending a message, making the first response faster.
License
MIT
