Skip to main content

JavaScript/TypeScript SDK

The official JavaScript/TypeScript SDK for Rexec works in both Node.js and browser environments.

Installation

npm install @pipeopshq/rexec
For Node.js environments, you’ll also need the ws package:
npm install ws

Quick Start

import { RexecClient } from '@pipeopshq/rexec';

const client = new RexecClient({
  baseURL: 'https://your-rexec-instance.com',
  token: 'your-api-token'
});

// Create a container
const container = await client.containers.create({
  image: 'ubuntu:24.04',
  name: 'my-sandbox'
});

console.log(`Created container: ${container.id}`);

// Connect to terminal
const terminal = await client.terminal.connect(container.id);

terminal.onData((data) => {
  console.log('Output:', data);
});

terminal.write('echo "Hello from Rexec!"\n');

// Clean up
await client.containers.delete(container.id);

Client Initialization

Basic Configuration

import { RexecClient } from '@pipeopshq/rexec';

const client = new RexecClient({
  baseURL: 'https://your-rexec-instance.com',
  token: 'your-api-token'
});
The RexecClient class is defined at /home/daytona/workspace/source/sdk/js/src/index.ts:283.

Custom Fetch Implementation

const client = new RexecClient({
  baseURL: 'https://your-rexec-instance.com',
  token: 'your-api-token',
  fetch: customFetch // Use a custom fetch implementation
});
See the RexecConfig interface at /home/daytona/workspace/source/sdk/js/src/index.ts:8.

Container Operations

The Containers service provides methods for managing sandboxed environments.

List Containers

const containers = await client.containers.list();

for (const container of containers) {
  console.log(`${container.name}: ${container.status}`);
}
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:151.

Get Container

const container = await client.containers.get(containerId);
console.log(`Container ${container.name} is ${container.status}`);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:158.

Create Container

const container = await client.containers.create({
  image: 'ubuntu:24.04',
  name: 'my-container',
  environment: {
    MY_VAR: 'value',
    DEBUG: 'true'
  },
  labels: {
    project: 'demo'
  }
});

console.log(`Created: ${container.id}`);
The CreateContainerRequest type is defined at /home/daytona/workspace/source/sdk/js/src/index.ts:28.

Start Container

await client.containers.start(containerId);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:179.

Stop Container

await client.containers.stop(containerId);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:186.

Delete Container

await client.containers.delete(containerId);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:172.

File Operations

Manage files and directories within containers.

List Files

const files = await client.files.list(containerId, '/home');

for (const file of files) {
  const icon = file.is_dir ? '📁' : '📄';
  console.log(`${icon} ${file.name}`);
}
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:200.

Download File

const data = await client.files.download(containerId, '/home/file.txt');
const text = new TextDecoder().decode(data);
console.log('File contents:', text);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:208.

Create Directory

await client.files.mkdir(containerId, '/home/newdir');
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:217.

Terminal Operations

Connect to containers via WebSocket for real-time terminal access.

Connect to Terminal

const terminal = await client.terminal.connect(containerId, {
  cols: 120,
  rows: 40
});
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:231.

Handle Terminal Data

terminal.onData((data) => {
  console.log(data.toString());
});

terminal.onClose(() => {
  console.log('Terminal closed');
});

terminal.onError((error) => {
  console.error('Terminal error:', error);
});
The Terminal class is defined at /home/daytona/workspace/source/sdk/js/src/index.ts:68.

Write to Terminal

terminal.write('ls -la\n');

// Or send binary data
const encoder = new TextEncoder();
terminal.write(encoder.encode('echo hello\n'));
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:93.

Resize Terminal

terminal.resize(150, 50);
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:123.

Close Terminal

terminal.close();
Implementation at /home/daytona/workspace/source/sdk/js/src/index.ts:130.

Advanced Examples

Run a Script

async function runScript(
  client: RexecClient,
  containerId: string,
  script: string
): Promise<string> {
  const terminal = await client.terminal.connect(containerId);
  
  return new Promise((resolve, reject) => {
    let output = '';
    
    terminal.onData((data) => {
      output += data.toString();
    });
    
    terminal.onClose(() => {
      resolve(output);
    });
    
    terminal.onError(reject);
    
    terminal.write(script + '\n');
    terminal.write('exit\n');
  });
}

const output = await runScript(
  client,
  container.id,
  'apt update && apt install -y nodejs'
);
console.log(output);

Browser Usage

<script type="module">
import { RexecClient } from 'https://unpkg.com/@pipeopshq/rexec/dist/index.mjs';

const client = new RexecClient({
  baseURL: 'https://your-rexec-instance.com',
  token: 'your-api-token'
});

// List containers
const containers = await client.containers.list();
console.log(containers);
</script>

Integration with xterm.js

import { Terminal } from 'xterm';
import { RexecClient } from '@pipeopshq/rexec';

const xterm = new Terminal();
xterm.open(document.getElementById('terminal'));

const client = new RexecClient({
  baseURL: 'https://your-rexec-instance.com',
  token: 'your-api-token'
});

const container = await client.containers.create({ image: 'ubuntu:24.04' });
const rexecTerminal = await client.terminal.connect(container.id, {
  cols: xterm.cols,
  rows: xterm.rows
});

// Connect xterm to rexec terminal
rexecTerminal.onData((data) => {
  xterm.write(data);
});

xterm.onData((data) => {
  rexecTerminal.write(data);
});

xterm.onResize(({ cols, rows }) => {
  rexecTerminal.resize(cols, rows);
});

Type Definitions

Container

interface Container {
  id: string;
  name: string;
  image: string;
  status: 'running' | 'stopped' | 'creating' | 'error';
  created_at: string;
  started_at?: string;
  labels?: Record<string, string>;
  environment?: Record<string, string>;
}
Defined at /home/daytona/workspace/source/sdk/js/src/index.ts:17.

FileInfo

interface FileInfo {
  name: string;
  path: string;
  size: number;
  mode: string;
  mod_time: string;
  is_dir: boolean;
}
Defined at /home/daytona/workspace/source/sdk/js/src/index.ts:39.

TerminalOptions

interface TerminalOptions {
  cols?: number;
  rows?: number;
}
Defined at /home/daytona/workspace/source/sdk/js/src/index.ts:48.

Error Handling

import { RexecClient, RexecError } from '@pipeopshq/rexec';

try {
  await client.containers.get('non-existent-id');
} catch (error) {
  if (error instanceof RexecError) {
    console.error(`API Error ${error.statusCode}: ${error.message}`);
  } else {
    console.error('Network error:', error);
  }
}
The RexecError class is defined at /home/daytona/workspace/source/sdk/js/src/index.ts:55.

Source Code

View the full source code on GitHub:

License

MIT License - see LICENSE for details.

Build docs developers (and LLMs) love