Skip to main content

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

PropTypeDescription
sandboxIdstringSandbox ID
theme'dark' | 'light'Color theme
fontSizenumberFont size in pixels
onCommand(cmd: string) => voidCommand callback
readOnlybooleanDisable 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

PropTypeDescription
sandboxIdstringSandbox ID
initialPathstringStarting directory
onFileSelect(path: string) => voidSelection callback
onFileOpen(path: string, content: string) => voidOpen callback
showHiddenbooleanShow 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

PropTypeDescription
sandboxIdstringSandbox ID
pathstringFile path
languagestringSyntax highlighting
themestringEditor theme
onChange(content: string) => voidChange callback
readOnlybooleanDisable 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

PropTypeDescription
deploymentstringDeployment API slug
placeholderstringInput placeholder
showToolCallsbooleanShow tool execution
showFileEditsbooleanShow file changes
showThinkingbooleanShow agent thinking
onComplete(result) => voidCompletion 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

PropTypeDescription
sandboxIdstringSandbox ID
portnumberServer port
refreshOnChangebooleanAuto-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>
  );
}