Skip to main content
Bun provides a fast, native S3 client that works with AWS S3, Cloudflare R2, DigitalOcean Spaces, MinIO, and any other S3-compatible storage service. The API is designed to feel like Bun’s local filesystem API — S3File extends Blob, so methods like .text(), .json(), .stream(), and .arrayBuffer() work the same way they do on local files.

Setup

Bun.s3 — global client using environment variables

Bun.s3 (also importable as s3 from "bun") reads credentials from environment variables automatically: S3_* variables take precedence over AWS_* fallbacks.

S3Client — explicit credentials


Reading files

Partial reads with slice()

Use byte ranges to avoid downloading an entire large file:
Internally this uses the HTTP Range header.

Writing files

For large files, writer() automatically uses S3 multipart upload. You don’t need to configure this explicitly — it happens whenever you stream data in chunks.

Using Bun.write with S3 files

S3File is a Blob, so you can pass it to Bun.write just like a local BunFile:

Presigned URLs

Presigned URLs grant time-limited access to a specific S3 object without exposing your credentials. Generating them is synchronous — no network request needed.

ACL options


Redirecting clients to S3

Wrap an S3File in a Response to issue a 302 redirect directly to the presigned URL — no need to proxy the file through your server:

File metadata and existence checks


Deleting files


Listing objects


S3-compatible services

Point endpoint to any S3-compatible service:

s3:// protocol

Use the s3:// protocol in Bun.file() and fetch() for a more ergonomic API:
Pass S3 credentials inline:

Error codes

Errors from the S3 service itself are instances of S3Error (an Error with name === "S3Error").