Workers API
Workers let you run code at the edge. When you bind an R2 bucket to a Worker, you can read and write objects directly using the Workers API.
A bucket stores your objects in R2. To create a new R2 bucket:
-
Log in to your Cloudflare account:
Terminal window npx wrangler login -
Create a bucket named
my-bucket:Terminal window npx wrangler r2 bucket create my-bucketIf prompted, select the account you want to create the bucket in.
-
Verify the bucket was created:
Terminal window npx wrangler r2 bucket list
-
In the Cloudflare Dashboard, go to R2 object storage.
Go to Overview -
Select Create bucket.
-
Enter a name for your bucket.
-
Select a location for your bucket and a default storage class.
-
Select Create bucket.
-
Create a new Worker project:
Terminal window npm create cloudflare@latest -- r2-workerTerminal window yarn create cloudflare r2-workerTerminal window pnpm create cloudflare@latest r2-workerWhen prompted, select Hello World example and JavaScript (or TypeScript) as your template.
-
Move into the project directory:
Terminal window cd r2-worker -
Add an R2 binding to your Wrangler configuration file. Replace
my-bucketwith your bucket name:{"r2_buckets": [{"binding": "MY_BUCKET","bucket_name": "my-bucket"}]}[[r2_buckets]]binding = "MY_BUCKET"bucket_name = "my-bucket" -
(Optional) If you are using TypeScript, regenerate types:
Terminal window npx wrangler types
Use the binding to interact with your bucket. This example stores and retrieves objects based on the URL path:
export default { async fetch(request, env) { // Get the object key from the URL path // For example: /images/cat.png → images/cat.png const url = new URL(request.url); const key = url.pathname.slice(1);
// PUT: Store the request body in R2 if (request.method === "PUT") { await env.MY_BUCKET.put(key, request.body); return new Response(`Put ${key} successfully!`); }
// GET: Retrieve the object from R2 const object = await env.MY_BUCKET.get(key); if (object === null) { return new Response("Object not found", { status: 404 }); } return new Response(object.body); },};export default { async fetch(request, env): Promise<Response> { // Get the object key from the URL path // For example: /images/cat.png → images/cat.png const url = new URL(request.url); const key = url.pathname.slice(1);
// PUT: Store the request body in R2 if (request.method === "PUT") { await env.MY_BUCKET.put(key, request.body); return new Response(`Put ${key} successfully!`); }
// GET: Retrieve the object from R2 const object = await env.MY_BUCKET.get(key); if (object === null) { return new Response("Object not found", { status: 404 }); } return new Response(object.body); },} satisfies ExportedHandler<Env>;-
Test your Worker locally:
Terminal window npx wrangler dev -
Once the dev server is running, test storing and retrieving objects:
Terminal window # Store an objectcurl -X PUT http://localhost:8787/my-file.txt -d 'Hello, R2!'# Retrieve the objectcurl http://localhost:8787/my-file.txt -
Deploy to production:
Terminal window npx wrangler deploy -
After deploying, Wrangler outputs your Worker's URL (for example,
https://r2-worker.<YOUR_SUBDOMAIN>.workers.dev). Test storing and retrieving objects:Terminal window # Store an objectcurl -X PUT https://r2-worker.<YOUR_SUBDOMAIN>.workers.dev/my-file.txt -d 'Hello, R2!'# Retrieve the objectcurl https://r2-worker.<YOUR_SUBDOMAIN>.workers.dev/my-file.txt
Refer to the Workers R2 API documentation for the complete API reference.
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Directory
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- © 2026 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark
-