Skip to main content

Overview

The Sandbox SDK provides file operations that let you write and read both text and binary files within your sandboxes. This enables you to:
  • Create and execute scripts dynamically
  • Store and retrieve data
  • Work with configuration files
  • Handle binary assets like images
File Size Limit: Individual file operations are limited to 10 MB. For larger files, consider splitting them into chunks or using alternative approaches.

Prerequisites

Before working with files, ensure you have:
  • Installed the Sandbox SDK (see Quickstart)
  • Created a sandbox instance
  • Basic familiarity with async/await in JavaScript/TypeScript

Writing Text Files

Use sandbox.files.write() to create or overwrite files with text content.

Basic Syntax

const result = await sandbox.files.write(path, content);

Example: Writing a JavaScript File

const script = `
const fs = require('fs');

console.log('Hello from dynamically written script!');
console.log('Node version:', process.version);

// Create some data
const data = {
    timestamp: new Date().toISOString(),
    message: 'Generated by script',
    random: Math.random()
};

// Write JSON output
fs.writeFileSync('/tmp/output.json', JSON.stringify(data, null, 2));
console.log('Wrote output to /tmp/output.json');
`;

const result = await sandbox.files.write("/tmp/script.js", script);
console.log(`Wrote ${result.bytesWritten} bytes to ${result.path}`);
The response includes bytesWritten and path to confirm the operation succeeded.

Response Object

{
  bytesWritten: number;  // Number of bytes written
  path: string;          // Absolute path of the file
}

Reading Text Files

Use sandbox.files.read() to retrieve file contents as a string.

Basic Syntax

const content = await sandbox.files.read(path);

Example: Reading and Parsing JSON

// Read the file
const content = await sandbox.files.read("/tmp/output.json");
console.log("File contents:", content);

// Parse JSON data
const data = JSON.parse(content);
console.log(`Timestamp: ${data.timestamp}`);
console.log(`Message: ${data.message}`);
console.log(`Random: ${data.random}`);
By default, read() returns text content as a string. For binary files, specify the encoding option (see below).

Working with Binary Files

The SDK supports binary file operations using Uint8Array for writing and the encoding: "binary" option for reading.

Writing Binary Data

// Create a 1x1 red pixel PNG image
const pngData = new Uint8Array([
    0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
    0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
    0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53,
    0xde, 0x00, 0x00, 0x00, 0x0c, 0x49, 0x44, 0x41,
    0x54, 0x08, 0xd7, 0x63, 0xf8, 0xcf, 0xc0, 0x00,
    0x00, 0x03, 0x01, 0x01, 0x00, 0x18, 0xdd, 0x8d,
    0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
    0x44, 0xae, 0x42, 0x60, 0x82,
]);

const result = await sandbox.files.write("/tmp/image.png", pngData);
console.log(`Wrote ${result.bytesWritten} bytes`);

Reading Binary Data

const imageData = await sandbox.files.read("/tmp/image.png", {
    encoding: "binary"
});

console.log(`Read ${(imageData as ArrayBuffer).byteLength} bytes`);
Use the file command in the sandbox to verify binary file types:
const check = await sandbox.exec("file /tmp/image.png");
console.log(check.stdout); // "PNG image data, 1 x 1, 8-bit/color RGB"

Complete Workflow Example

Here’s a complete example that demonstrates writing a script, executing it, and reading the generated output:
import { Sandbox } from "@simplesandbox/sdk";

async function fileOperationsDemo() {
    const client = Sandbox();
    
    try {
        // Create a sandbox
        const sandbox = await client.sandboxes.create({
            image: "node:lts-alpine",
            timeoutMs: 60000,
        });
        console.log(`Created sandbox: ${sandbox.id}`);

        // 1. Write a JavaScript script
        const script = `
const fs = require('fs');

const data = {
    timestamp: new Date().toISOString(),
    message: 'Generated by script',
    random: Math.random()
};

fs.writeFileSync('/tmp/output.json', JSON.stringify(data, null, 2));
console.log('Script executed successfully!');
`;

        await sandbox.files.write("/tmp/script.js", script);
        console.log("Wrote script file");

        // 2. Execute the script
        const execResult = await sandbox.exec("node /tmp/script.js");
        console.log(`Exit code: ${execResult.exitCode}`);
        console.log(`Output: ${execResult.stdout}`);

        // 3. Read the generated output
        const output = await sandbox.files.read("/tmp/output.json");
        const data = JSON.parse(output);
        
        console.log("Generated data:");
        console.log(`  Timestamp: ${data.timestamp}`);
        console.log(`  Message: ${data.message}`);
        console.log(`  Random: ${data.random}`);

        // Cleanup
        await sandbox.kill();
        console.log("Sandbox destroyed");
        
    } catch (error) {
        console.error("Error:", error);
        throw error;
    }
}

fileOperationsDemo();
This example demonstrates the complete cycle: write → execute → read → verify.

Working with Relative Paths

File operations support relative paths with sandbox.cwd():
sandbox.cwd("/app/project");

// Relative paths resolve to /app/project
const config = await sandbox.files.read("config.json");
await sandbox.files.write("output.txt", "result data");

// Override cwd for single operation
const logs = await sandbox.files.read("error.log", { cwd: "/var/log" });
Relative paths resolve to:
  1. The cwd option if provided
  2. The persistent sandbox.cwd() if set
  3. The sandbox default directory (usually /)

Best Practices

Choose Path Style: Use absolute paths (starting with /) for clarity, or set a working directory with sandbox.cwd() and use relative paths for cleaner code.
Choose the Right Encoding: Use default (text) encoding for strings and JSON. Use encoding: "binary" for images, PDFs, and other binary formats.
Verify Operations: Use shell commands like ls, cat, or file to verify file operations succeeded as expected.
Path Security: Be cautious with user-provided file paths. Validate and sanitize paths to prevent directory traversal attacks.

Error Handling

Wrap file operations in try-catch blocks to handle errors gracefully:
try {
    const content = await sandbox.files.read("/tmp/config.json");
    const config = JSON.parse(content);
} catch (error) {
    if (error instanceof Error) {
        console.error("Failed to read config:", error.message);
    }
    // Fallback to defaults
    const config = { /* default config */ };
}
Common errors include file not found, permission denied, or exceeding the 10 MB size limit.

Next Steps