---
title: Bun S3
description: AWS S3 (and any S3-compatible bucket) via Bun's native Bun.S3Client instead of @aws-sdk/client-s3. Bun-only.
---

## Installation

This adapter has no extra peer dependencies, but it requires the Bun runtime - it's built on Bun's native `Bun.S3Client`, which Node doesn't provide. (Outside Bun it throws unless you hand it a `Bun.S3Client`-shaped `client` yourself.)

```package-install
files-sdk
```

## Usage

```ts lineNumbers
import { Files } from "files-sdk";
import { bunS3 } from "files-sdk/bun-s3";

const files = new Files({
  adapter: bunS3({
    bucket: "uploads",
    region: "us-east-1",
    // accessKeyId / secretAccessKey auto-loaded by Bun from
    // S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY (or AWS_* equivalents)
  }),
});

// Or hand it the singleton Bun.s3 client directly:
new Files({ adapter: bunS3({ client: Bun.s3 }) });
```

Three things differ from `files-sdk/s3`: `copy()` streams bytes through your process because Bun doesn't expose a server-side `CopyObject` primitive; `upload()` throws on `metadata` and `cacheControl` because `Bun.S3Client.write()` has no equivalent options; and `signedUploadUrl()` throws on `maxSize` because Bun exposes presigned URLs only - not S3 POST policy fields. Reach for `files-sdk/s3` on the same bucket when you need any of those.

## Options

<AutoTypeTable
  path="../../packages/files-sdk/src/bun-s3/index.ts"
  name="BunS3AdapterOptions"
/>

## Compatibility

| Method            | Status | Notes                                                                                                                                                                                                                                                                                                                                                                                   |
| ----------------- | :----: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upload`          |   ⚠️   | User `metadata` and `cacheControl` throw - `Bun.S3Client.write()` exposes neither field. Reach for `s3()` on the same bucket if you need them. Stream bodies are wrapped in a `Response` and handed to Bun's writer. Pause/resume via `control` is in-process only — Bun’s S3 client exposes no resumable upload id, so chunks are buffered and a token cannot resume in a new process. |
| `download`        |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `delete`          |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `list`            |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `search`          |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `head`            |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `exists`          |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `copy`            |   ⚠️   | Client-side stream copy - `Bun.S3Client` doesn't expose a server-side `CopyObject`, so the source is streamed through this process and re-uploaded. Doubled bandwidth, not atomic, and drops Content-Disposition/cache headers/user metadata/ACL (only Content-Type is preserved). Reach for `s3()` on the same bucket for server-side copy.                                            |
| `url`             |   ✅   |                                                                                                                                                                                                                                                                                                                                                                                         |
| `signedUploadUrl` |   ⚠️   | PUT URL only - Bun exposes presigned URLs, not S3 POST policy fields, so `maxSize` throws (no `content-length-range` policy). Enforce upload caps at your application gateway instead.                                                                                                                                                                                                  |
