> ## Documentation Index
> Fetch the complete documentation index at: https://docs.superserve.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Read and write files

> Upload and download files to and from a sandbox's filesystem.

Use `sandbox.files` to move data in and out of a sandbox. The SDK handles data-plane routing and authentication transparently.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  await sandbox.files.write("/app/config.json", '{"key": "value"}')

  const text = await sandbox.files.readText("/app/config.json")
  console.log(text)
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  sandbox.files.write("/app/config.json", '{"key": "value"}')

  text = sandbox.files.read_text("/app/config.json")
  print(text)
  ```
</CodeGroup>

<Note>
  Using `AsyncSandbox`? The same `files` methods are there, awaitable.
</Note>

## Write binary content

`write()` accepts strings or raw bytes. Parent directories are created automatically.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  import { readFileSync } from "node:fs"

  const buffer = readFileSync("./local-image.png")
  await sandbox.files.write("/app/image.png", buffer)

  await sandbox.files.write("/app/data.bin", new Uint8Array([1, 2, 3, 4]))
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  with open("local-image.png", "rb") as f:
      sandbox.files.write("/app/image.png", f.read())

  sandbox.files.write("/app/data.bin", bytes([1, 2, 3, 4]))
  ```
</CodeGroup>

## Read as bytes or text

* `read()` returns raw bytes (`Uint8Array` in TypeScript, `bytes` in Python)
* `readText()` / `read_text()` returns a UTF-8-decoded string

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  const bytes: Uint8Array = await sandbox.files.read("/app/image.png")

  const text: string = await sandbox.files.readText("/app/config.json")
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  data: bytes = sandbox.files.read("/app/image.png")

  text: str = sandbox.files.read_text("/app/config.json")
  ```
</CodeGroup>

## Download a directory as a zip

`downloadDir()` / `download_dir()` exports a whole directory as a ZIP archive —
useful for pulling out logs, build artifacts, or results in one call. It returns
the raw zip bytes; large directories can exceed the default 30s timeout, so pass
a longer `timeoutMs` / `timeout` when needed.

<CodeGroup>
  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  import { writeFileSync } from "node:fs"

  const zip = await sandbox.files.downloadDir("/app/results", {
    timeoutMs: 120_000,
  })
  writeFileSync("results.zip", zip)
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"vitesse-dark"}}
  zip_bytes = sandbox.files.download_dir("/app/results", timeout=120)
  with open("results.zip", "wb") as f:
      f.write(zip_bytes)
  ```
</CodeGroup>

## Path rules

Paths passed to `files.*` methods must:

* **Start with `/`** - only absolute paths are accepted
* **Contain no `..` segments** - no traversal

Parent directories are created automatically on write - you don't need to `mkdir -p` first.

## Errors

See the [files reference](/sdk-reference/files#errors) and the full [error hierarchy](/errors).
