---
title: Filesystem
description: TypeScript SDK - Filesystem API reference
---

Read and write files inside a running sandbox over the same host-guest channel as command execution: no SSH, no network. Obtain a handle with `sandbox.fs()`. See [Filesystem](/sandboxes/filesystem) for usage examples. For bulk transfers, consider a [bind-mounted volume](/sandboxes/volumes) instead.

<div className="msb-glance">

  <p className="msb-gl"><span className="msb-dot instance"></span>SandboxFsOps · read / write<span className="msb-ct">5</span></p>
  <a className="msb-row" href="#fs-read"><span className="msb-rn">fs.read()</span><span className="msb-rg">read a file as bytes</span></a>
  <a className="msb-row" href="#fs-readtostring"><span className="msb-rn">fs.readToString()</span><span className="msb-rg">read a file as UTF-8</span></a>
  <a className="msb-row" href="#fs-write"><span className="msb-rn">fs.write()</span><span className="msb-rg">write a whole file</span></a>
  <a className="msb-row" href="#fs-readstream"><span className="msb-rn">fs.readStream()</span><span className="msb-rg">stream a file in chunks</span></a>
  <a className="msb-row" href="#fs-writestream"><span className="msb-rn">fs.writeStream()</span><span className="msb-rg">stream writes to a file</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>SandboxFsOps · directories &amp; paths<span className="msb-ct">6</span></p>
  <a className="msb-row" href="#fs-list"><span className="msb-rn">fs.list()</span><span className="msb-rg">list a directory</span></a>
  <a className="msb-row" href="#fs-mkdir"><span className="msb-rn">fs.mkdir()</span><span className="msb-rg">create a directory</span></a>
  <a className="msb-row" href="#fs-removedir"><span className="msb-rn">fs.removeDir()</span><span className="msb-rg">remove a directory</span></a>
  <a className="msb-row" href="#fs-remove"><span className="msb-rn">fs.remove()</span><span className="msb-rg">remove a file</span></a>
  <a className="msb-row" href="#fs-stat"><span className="msb-rn">fs.stat()</span><span className="msb-rg">file metadata</span></a>
  <a className="msb-row" href="#fs-exists"><span className="msb-rn">fs.exists()</span><span className="msb-rg">check a path exists</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>SandboxFsOps · move &amp; copy<span className="msb-ct">4</span></p>
  <a className="msb-row" href="#fs-copy"><span className="msb-rn">fs.copy()</span><span className="msb-rg">copy within the guest</span></a>
  <a className="msb-row" href="#fs-rename"><span className="msb-rn">fs.rename()</span><span className="msb-rg">rename / move</span></a>
  <a className="msb-row" href="#fs-copyfromhost"><span className="msb-rn">fs.copyFromHost()</span><span className="msb-rg">host into guest</span></a>
  <a className="msb-row" href="#fs-copytohost"><span className="msb-rn">fs.copyToHost()</span><span className="msb-rg">guest out to host</span></a>

  <p className="msb-gl"><span className="msb-dot type"></span>Types</p>
  <div className="msb-chiprow">
    <a className="msb-typepill" href="#fsentry">FsEntry</a>
    <a className="msb-typepill" href="#fsmetadata">FsMetadata</a>
    <a className="msb-typepill" href="#fsentrykind">FsEntryKind</a>
    <a className="msb-typepill" href="#fsreadstream">FsReadStream</a>
    <a className="msb-typepill" href="#fswritesink">FsWriteSink</a>
  </div>

</div>

<p className="msb-label" id="typical-flow">Typical flow</p>

```typescript
const fs = sandbox.fs();

await fs.write("/tmp/config.json", '{"debug": true}');     // write
const content = await fs.readToString("/tmp/config.json"); // read back
console.log(content);

for (const entry of await fs.list("/tmp")) {               // list
  console.log(entry.path);
}
```

## SandboxFsOps

Filesystem handle for a running sandbox, obtained via [`sandbox.fs()`](/sdk/typescript/sandbox#sandboxfs). Every method is async and returns a `Promise`. Paths are absolute inside the guest.

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
read(path: string): Promise<Uint8Array>
```

Read the entire contents of a file as raw bytes.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest (e.g. <code>"/app/config.json"</code>).</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise&lt;Uint8Array&gt;</span></div>
    <div className="msb-param-desc">File contents as raw bytes.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
const bytes = await fs.read("/app/logo.png");
console.log(`${bytes.byteLength} bytes`);
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">readToString()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
readToString(path: string): Promise<string>
```

Read the entire contents of a file and decode it as UTF-8.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise&lt;string&gt;</span></div>
    <div className="msb-param-desc">File contents as a string.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
const text = await fs.readToString("/etc/hostname");
console.log(text.trim());
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">write()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
write(path: string, data: Uint8Array | string): Promise<void>
```

Write content to a file, creating it if it doesn't exist and overwriting if it does. Parent directories must already exist. `string` payloads are encoded as UTF-8.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>data</code><span className="msb-type">Uint8Array | string</span></div>
    <div className="msb-param-desc">File content. Strings are written as UTF-8.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.write("/tmp/config.json", '{"debug": true}');
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">readStream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
readStream(path: string): Promise<FsReadStream>
```

Open a streaming reader for a file. Data is transferred in chunks. Use this for files too large to fit in memory. The returned [`FsReadStream`](#fsreadstream) is an `AsyncIterable<Uint8Array>`, so it works with `for await...of`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsreadstream">Promise&lt;FsReadStream&gt;</a></div>
    <div className="msb-param-desc">Async stream that yields chunks of file data.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
for await (const chunk of await fs.readStream("/var/log/syslog")) {
  process.stdout.write(chunk); // chunk is a Uint8Array
}
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">writeStream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
writeStream(path: string): Promise<FsWriteSink>
```

Open a streaming writer for a file. Use this for files too large to hold in memory; pair with `await using` so the [`FsWriteSink`](#fswritesink) closes itself when the scope exits.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fswritesink">Promise&lt;FsWriteSink&gt;</a></div>
    <div className="msb-param-desc">Streaming writer.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await using sink = await fs.writeStream("/tmp/big.bin");
await sink.write(new Uint8Array(1 << 20));
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">list()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
list(path: string): Promise<FsEntry[]>
```

List the entries in a directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsentry">Promise&lt;FsEntry[]&gt;</a></div>
    <div className="msb-param-desc">Directory entries.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
for (const entry of await fs.list("/app")) {
  console.log(`${entry.kind}\t${entry.path}`);
}
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">mkdir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
mkdir(path: string): Promise<void>
```

Create a directory. Parent directories must already exist.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute directory path.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.mkdir("/app/data");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">removeDir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
removeDir(path: string): Promise<void>
```

Remove a directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute directory path.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.removeDir("/app/data");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
remove(path: string): Promise<void>
```

Remove a file.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute file path.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.remove("/tmp/config.json");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
stat(path: string): Promise<FsMetadata>
```

Get detailed metadata for a file or directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">Promise&lt;FsMetadata&gt;</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
const meta = await fs.stat("/app/config.json");
console.log(`${meta.size} bytes, mode ${meta.mode.toString(8)}`);
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">exists()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
exists(path: string): Promise<boolean>
```

Check whether a path exists inside the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Promise&lt;boolean&gt;</span></div>
    <div className="msb-param-desc"><code>true</code> if the path exists.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
if (await fs.exists("/app/config.json")) {
  console.log("config present");
}
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
copy(from: string, to: string): Promise<void>
```

Copy a file within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Source path.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Destination path.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.copy("/app/config.json", "/app/config.bak.json");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">rename()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
rename(from: string, to: string): Promise<void>
```

Rename or move a file or directory within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Current path.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">New path.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.rename("/tmp/draft.txt", "/tmp/final.txt");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copyFromHost()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
copyFromHost(hostPath: string, guestPath: string): Promise<void>
```

Copy a file from the host machine into the sandbox. For transferring many files, consider a [bind-mounted volume](/sandboxes/volumes) instead.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>hostPath</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Path on the host filesystem.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guestPath</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Destination path inside the sandbox.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.copyFromHost("./seed.db", "/app/data/seed.db");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copyToHost()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```typescript
copyToHost(guestPath: string, hostPath: string): Promise<void>
```

Copy a file from the sandbox to the host machine.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>guestPath</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Path inside the sandbox.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>hostPath</code><span className="msb-type">string</span></div>
    <div className="msb-param-desc">Destination path on the host.</div>
  </div>
</div>

<Accordion title="Example">

```typescript
await fs.copyToHost("/app/out/report.pdf", "./report.pdf");
```

</Accordion>

---

## Types

### FsEntry

<div className="msb-tags"><span className="msb-tag is-type">interface</span></div>

<p className="msb-backref">Returned by <a href="#fs-list">list()</a></p>

Metadata for a single directory entry.

| Field | Type | Description |
|-------|------|-------------|
| path | `string` | Entry path |
| kind | [`FsEntryKind`](#fsentrykind) | Type of entry |
| size | `number` | File size in bytes |
| mode | `number` | Unix permission bits |
| modified | `Date \| null` | Last modified timestamp, or `null` if unavailable |

### FsMetadata

<div className="msb-tags"><span className="msb-tag is-type">interface</span></div>

<p className="msb-backref">Returned by <a href="#fs-stat">stat()</a></p>

Detailed file metadata.

| Field | Type | Description |
|-------|------|-------------|
| kind | [`FsEntryKind`](#fsentrykind) | Type of entry |
| size | `number` | File size in bytes |
| mode | `number` | Unix permission bits |
| readonly | `boolean` | Whether the file is read-only |
| modified | `Date \| null` | Last modified timestamp, or `null` if unavailable |
| created | `Date \| null` | Creation timestamp, or `null` if unavailable |

### FsEntryKind

<div className="msb-tags"><span className="msb-tag is-type">type</span></div>

<p className="msb-backref">Used by <a href="#fsentry">FsEntry.kind</a> · <a href="#fsmetadata">FsMetadata.kind</a></p>

```typescript
type FsEntryKind = "file" | "directory" | "symlink" | "other";
```

| Value | Description |
|-------|-------------|
| `"file"` | Regular file |
| `"directory"` | Directory |
| `"symlink"` | Symbolic link |
| `"other"` | Other entry type |

### FsReadStream

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-readstream">readStream()</a></p>

Async stream for reading a file in chunks. Implements `AsyncIterable<Uint8Array>` and `AsyncDisposable`, so it works with `for await...of` and `await using`.

| Method | Returns | Description |
|--------|---------|-------------|
| `recv()` | `Promise<Uint8Array \| null>` | Receive the next chunk. Returns `null` when the file has been fully read. |
| `collect()` | `Promise<Uint8Array>` | Drain the stream into a single buffer |
| `[Symbol.asyncIterator]()` | `AsyncIterator<Uint8Array>` | Iterate chunks with `for await...of` |
| `[Symbol.asyncDispose]()` | `Promise<void>` | Stop reading; runs on `await using` scope exit |

### FsWriteSink

<div className="msb-tags"><span className="msb-tag is-type">class</span></div>

<p className="msb-backref">Returned by <a href="#fs-writestream">writeStream()</a></p>

Streaming writer for a file. Implements `AsyncDisposable`, so it can be paired with `await using`.

| Method | Parameters | Returns | Description |
|--------|-----------|---------|-------------|
| `write(data)` | `Uint8Array \| string` | `Promise<void>` | Append a chunk. Strings are encoded as UTF-8. |
| `close()` | - | `Promise<void>` | Flush and close. Idempotent. |
| `[Symbol.asyncDispose]()` | - | `Promise<void>` | Calls `close()` on `await using` scope exit |
