React components (@runtools/react) are planned but not yet built. This page describes the planned component library.
Installation
npm install @runtools/react
Provider Setup
import { RunToolsProvider } from '@runtools/react';
function App() {
return (
<RunToolsProvider apiKey={process.env.NEXT_PUBLIC_RUNTOOLS_KEY}>
<YourApp />
</RunToolsProvider>
);
}
Terminal Component
Embed a sandbox terminal:
import { Terminal } from '@runtools/react';
function MyTerminal() {
return (
<Terminal
sandboxId="sandbox-abc123"
theme="dark"
fontSize={14}
onCommand={(cmd) => console.log('Executed:', cmd)}
/>
);
}
Props
| Prop | Type | Description |
|---|
sandboxId | string | Sandbox ID |
theme | 'dark' | 'light' | Color theme |
fontSize | number | Font size in pixels |
onCommand | (cmd: string) => void | Command callback |
readOnly | boolean | Disable input |
File Browser
Embed a file browser:
import { FileBrowser } from '@runtools/react';
function MyFileBrowser() {
return (
<FileBrowser
sandboxId="sandbox-abc123"
initialPath="/workspace"
onFileSelect={(path) => console.log('Selected:', path)}
onFileOpen={(path, content) => {
// Open in editor
}}
/>
);
}
Props
| Prop | Type | Description |
|---|
sandboxId | string | Sandbox ID |
initialPath | string | Starting directory |
onFileSelect | (path: string) => void | Selection callback |
onFileOpen | (path: string, content: string) => void | Open callback |
showHidden | boolean | Show hidden files |
Code Editor
Embed a code editor connected to sandbox:
import { CodeEditor } from '@runtools/react';
function MyEditor() {
return (
<CodeEditor
sandboxId="sandbox-abc123"
path="/workspace/src/App.tsx"
language="typescript"
theme="vs-dark"
onChange={(content) => {
// Auto-saves to sandbox
}}
/>
);
}
Props
| Prop | Type | Description |
|---|
sandboxId | string | Sandbox ID |
path | string | File path |
language | string | Syntax highlighting |
theme | string | Editor theme |
onChange | (content: string) => void | Change callback |
readOnly | boolean | Disable editing |
Agent Chat
Embed an agent chat interface:
import { AgentChat } from '@runtools/react';
function MyChat() {
return (
<AgentChat
deployment="my-code-bot"
placeholder="Ask me to build something..."
showToolCalls={true}
showFileEdits={true}
onComplete={(result) => {
console.log('Agent finished:', result);
}}
/>
);
}
Props
| Prop | Type | Description |
|---|
deployment | string | Deployment API slug |
placeholder | string | Input placeholder |
showToolCalls | boolean | Show tool execution |
showFileEdits | boolean | Show file changes |
showThinking | boolean | Show agent thinking |
onComplete | (result) => void | Completion callback |
Preview Frame
Embed sandbox dev server preview:
import { PreviewFrame } from '@runtools/react';
function MyPreview() {
return (
<PreviewFrame
sandboxId="sandbox-abc123"
port={3000}
refreshOnChange={true}
/>
);
}
Props
| Prop | Type | Description |
|---|
sandboxId | string | Sandbox ID |
port | number | Server port |
refreshOnChange | boolean | Auto-refresh on file changes |
Hooks
useSandbox
import { useSandbox } from '@runtools/react';
function MySandbox() {
const { sandbox, loading, error, create, destroy } = useSandbox();
const handleCreate = async () => {
await create({ template: 'nodejs-20' });
};
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
{sandbox ? (
<div>
<p>Sandbox: {sandbox.id}</p>
<button onClick={destroy}>Destroy</button>
</div>
) : (
<button onClick={handleCreate}>Create Sandbox</button>
)}
</div>
);
}
useAgent
import { useAgent } from '@runtools/react';
function MyAgent() {
const {
run,
running,
events,
output,
pause,
resume,
cancel
} = useAgent('my-code-bot');
return (
<div>
<button onClick={() => run('Build a todo app')}>
Run Agent
</button>
{running && (
<>
<button onClick={pause}>Pause</button>
<button onClick={cancel}>Cancel</button>
</>
)}
<div>
{events.map((event, i) => (
<div key={i}>{event.type}: {JSON.stringify(event.data)}</div>
))}
</div>
{output && <div>Result: {output}</div>}
</div>
);
}
useFiles
import { useFiles } from '@runtools/react';
function MyFiles() {
const {
files,
loading,
read,
write,
remove,
refresh
} = useFiles('sandbox-abc123', '/workspace');
return (
<ul>
{files.map((file) => (
<li key={file.path} onClick={() => read(file.path)}>
{file.name}
</li>
))}
</ul>
);
}
Full Example
import {
RunToolsProvider,
Terminal,
FileBrowser,
CodeEditor,
PreviewFrame,
useSandbox
} from '@runtools/react';
function IDE() {
const { sandbox, create } = useSandbox();
const [selectedFile, setSelectedFile] = useState<string | null>(null);
useEffect(() => {
create({ template: 'nodejs-20' });
}, []);
if (!sandbox) return <div>Loading...</div>;
return (
<div className="ide-layout">
<FileBrowser
sandboxId={sandbox.id}
onFileSelect={setSelectedFile}
/>
{selectedFile && (
<CodeEditor
sandboxId={sandbox.id}
path={selectedFile}
/>
)}
<Terminal sandboxId={sandbox.id} />
<PreviewFrame
sandboxId={sandbox.id}
port={3000}
/>
</div>
);
}
export default function App() {
return (
<RunToolsProvider apiKey={process.env.NEXT_PUBLIC_RUNTOOLS_KEY}>
<IDE />
</RunToolsProvider>
);
}