R2Bucket
Creates and manages Cloudflare R2 Buckets for object storage with S3 compatibility.
Minimal Example
Section titled “Minimal Example”Create a basic R2 bucket with default settings:
import { R2Bucket } from "alchemy/cloudflare";
const bucket = await R2Bucket("my-bucket", { name: "my-bucket",});Bind to a Worker
Section titled “Bind to a Worker”import { Worker, R2Bucket } from "alchemy/cloudflare";
const bucket = await R2Bucket("my-bucket", { name: "my-bucket",});
await Worker("my-worker", { name: "my-worker", script: "console.log('Hello, world!')", bindings: { BUCKET: bucket, },});With Location Hint
Section titled “With Location Hint”Create a bucket with location hint for optimal performance:
import { R2Bucket } from "alchemy/cloudflare";
const euBucket = await R2Bucket("eu-bucket", { name: "eu-bucket", locationHint: "eu", jurisdiction: "eu",});With Public Access
Section titled “With Public Access”Create a development bucket with public access enabled:
import { R2Bucket } from "alchemy/cloudflare";
const publicBucket = await R2Bucket("public-assets", { name: "public-assets", allowPublicAccess: true,});console.log(publicBucket.domain); // [random-id].r2.devThis enables the r2.dev domain for the bucket. This URL is rate-limited and not recommended for production use.
With CORS
Section titled “With CORS”Create a bucket with CORS rules:
import { R2Bucket } from "alchemy/cloudflare";
const corsBucket = await R2Bucket("cors-bucket", { name: "cors-bucket", cors: [ { allowed: { origins: ["https://example.com"], methods: ["GET", "POST", "PUT", "DELETE", "HEAD"], headers: ["*"], }, }, ],});With Auto-Emptying
Section titled “With Auto-Emptying”Create a bucket that will be automatically emptied when deleted:
import { R2Bucket } from "alchemy/cloudflare";
const tempBucket = await R2Bucket("temp-storage", { name: "temp-storage", empty: true, // All objects will be deleted when this resource is destroyed});With Lifecycle Rules
Section titled “With Lifecycle Rules”Configure automatic transitions like aborting multipart uploads, deleting objects after an age or date, or moving objects to Infrequent Access.
import { R2Bucket } from "alchemy/cloudflare";
const bucket = await R2Bucket("logs", { name: "logs", lifecycle: [ // Abort incomplete multipart uploads after 7 days { id: "abort-mpu-7d", conditions: { prefix: "" }, // empty means apply to all objects/uploads enabled: true, abortMultipartUploadsTransition: { condition: { type: "Age", maxAge: 7 * 24 * 60 * 60 }, }, }, // Delete objects after 30 days { id: "delete-30d", conditions: { prefix: "archive/" }, deleteObjectsTransition: { condition: { type: "Age", maxAge: 30 * 24 * 60 * 60 }, }, }, // Transition storage class to InfrequentAccess after 60 days { id: "ia-60d", conditions: { prefix: "cold/" }, storageClassTransitions: [ { condition: { type: "Age", maxAge: 60 * 24 * 60 * 60 }, storageClass: "InfrequentAccess", }, ], }, ],});- conditions.prefix: Scope rule to keys beginning with a prefix. Use "" for all keys.
- enabled: Defaults to
truewhen omitted. - Age condition fields: lifecycle uses
maxAge(seconds). - Date condition fields: use ISO strings like
"2025-01-01T00:00:00Z".
With Object Lock Rules
Section titled “With Object Lock Rules”Apply retention locks to objects by age, until a fixed date, or indefinitely.
import { R2Bucket } from "alchemy/cloudflare";
const bucket = await R2Bucket("legal-holds", { name: "legal-holds", lock: [ // Lock all objects for 7 days { id: "retain-7d", prefix: "", enabled: true, condition: { type: "Age", maxAgeSeconds: 7 * 24 * 60 * 60 }, }, // Indefinite lock for the legal prefix { id: "legal-indef", prefix: "legal/", condition: { type: "Indefinite" }, }, // Retain until a specific date { id: "retain-until-2025", prefix: "exports/", condition: { type: "Date", date: "2025-01-01T00:00:00Z" }, }, ],});- prefix: Scope the lock rule to objects starting with the prefix. Omit or set to "" for all keys.
- enabled: Defaults to
truewhen omitted. - Age condition fields: lock uses
maxAgeSeconds(seconds).
Object Operations
Section titled “Object Operations”Use the returned R2Bucket instance to work with objects directly from your scripts.
import { R2Bucket } from "alchemy/cloudflare";
const bucket = await R2Bucket("my-bucket", { name: "my-bucket",});Retrieve metadata about an object.
const head = await bucket.head("example.txt");if (head) { console.log(head.etag, head.size);}Retrieve an object from the bucket.
const obj = await bucket.get("example.txt");const text = await obj?.text();Upload an object to the bucket.
const putInfo = await bucket.put("example.txt", "Hello, R2!\n");delete
Section titled “delete”Delete an object from the bucket.
await bucket.delete("example.txt");List objects in the bucket.
const list = await bucket.list();console.log(list.objects.length);