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.dev
This 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
true
when 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
true
when omitted. - Age condition fields: lock uses
maxAgeSeconds
(seconds).