# File operations
URL: /docs/core/concepts/file-ops

Write, read, move, delete, search, list, patch, and transfer files inside the sandbox container.



`SandboxHandle` exposes file operation methods that cover reading, writing, patching, searching, and transferring files. All paths are inside the container.

## writeFile [#writefile]

Write a UTF-8 string to a path inside the container. Creates parent directories automatically.

```ts
await sb.writeFile("/workspace/src/index.ts", 'export const VERSION = "1.0.0";\n');
await sb.writeFile("/tmp/config.json", JSON.stringify({ debug: true }));
```

## readFile [#readfile]

Read a file from the container as a UTF-8 string:

```ts
const source = await sb.readFile("/workspace/src/index.ts");
console.log(source);

// Use the content in subsequent steps
const config = JSON.parse(await sb.readFile("/tmp/config.json"));
```

## moveFile [#movefile]

Move or rename a file inside the container:

```ts
await sb.exec("mkdir -p /workspace/dist");
await sb.moveFile("/workspace/src/index.ts", "/workspace/dist/index.ts");
```

## deleteFile [#deletefile]

Delete a file from the container:

```ts
await sb.deleteFile("/workspace/src/util.ts");
```

## searchFiles [#searchfiles]

Search for files matching a glob pattern. Returns an array of matching paths:

```ts
const tsFiles = await sb.searchFiles("*.ts", "/workspace/src");
console.log(tsFiles);
// ["/workspace/src/index.ts", "/workspace/src/util.ts"]
```

The second argument is the base path to search from. Defaults to `/` if omitted.

## listDirectory [#listdirectory]

List entries in a directory. Returns metadata for each entry:

```ts
const entries = await sb.listDirectory("/workspace/dist");
console.log(entries.map((e) => e.path));
// ["/workspace/dist/index.ts"]

// Control recursion depth
const all = await sb.listDirectory("/workspace", { depth: 3 });
```

## createDirectory [#createdirectory]

Create a directory (and all parents) inside the container without running `exec`:

```ts
await sb.createDirectory("/workspace/src");
await sb.createDirectory("/workspace/dist");
```

## deleteDirectory [#deletedirectory]

Delete a directory from the container:

```ts
await sb.deleteDirectory("/workspace/tmp");
```

## getFileInfo [#getfileinfo]

Return metadata for a file or directory — size, type, mode, owner, and timestamps:

```ts
const info = await sb.getFileInfo("/workspace/src/index.ts");
console.log(info.size); // bytes
console.log(info.type); // "file" | "directory" | "symlink"
console.log(info.mode); // unix permission bits
console.log(info.modified_at); // ISO timestamp
```

## replaceInFiles [#replaceinfiles]

Replace a substring in one or more files in a single API call. More efficient than `readFile` → string replace → `writeFile` for targeted edits:

```ts
await sb.replaceInFiles([
  { path: "/app/config.json", old: "localhost", new: "0.0.0.0" },
  { path: "/app/src/version.ts", old: "0.0.0", new: "1.2.3" },
]);
```

## transfer [#transfer]

Copy a file from this sandbox into another sandbox. Useful after `fork()` to move results between containers:

```ts
const fork = await sb.fork("after-build");

await fork.exec("npm run build");
await fork.transfer("/app/dist/bundle.js", sb); // copy back to original

await fork.close();
```

## Pattern: patch a file [#pattern-patch-a-file]

Use `replaceInFiles` for in-place text replacements — no `exec`/`sed` needed:

```ts
await sb.writeFile("/workspace/src/index.ts", 'export const VERSION = "0.0.0";\n');
await sb.replaceInFiles([{ path: "/workspace/src/index.ts", old: "0.0.0", new: "1.2.3" }]);
const patched = await sb.readFile("/workspace/src/index.ts");
console.log(patched.trim()); // 'export const VERSION = "1.2.3";'
```

## Pattern: write a generated script and run it [#pattern-write-a-generated-script-and-run-it]

```ts
const script = `
import sys
print(f"Python {sys.version.split()[0]}")
`.trim();

await sb.writeFile("/tmp/script.py", script);
await sb.exec("python3 /tmp/script.py").pipe(process.stdout);
```

## File ops in the workflow builder [#file-ops-in-the-workflow-builder]

`writeFile`, `readFile`, `deleteFile`, and `moveFile` are available in `SandboxBuilder` for use in `@alineo-labs/workflow` (`createDirectory`, `deleteDirectory`, `getFileInfo`, `replaceInFiles`, `searchFiles`, `listDirectory`, and `transfer` are not queueable — call them directly on a `SandboxHandle` outside the workflow builder). `readFile` takes an extra `as` argument to store the result in `vars`:

```ts
await workflow(client)
  .sandbox({ image: "node:22", resources: { cpu: "500m", memory: "256Mi" } }, (sb) => {
    sb.writeFile("/tmp/hello.txt", "hello\n");
    sb.exec("cat /tmp/hello.txt").pipe(process.stdout);
    sb.readFile("/tmp/hello.txt", "greeting"); // → vars["greeting"]
    sb.moveFile("/tmp/hello.txt", "/tmp/moved.txt");
    sb.deleteFile("/tmp/moved.txt");
  })
  .result();
```
