A small R2 example you can adapt quickly
This example uses one private bucket and one route, which is still the cleanest default shape for many real apps.
A good first R2 example teaches both the binding and the delivery boundary: the worker decides what the browser gets.
- Config focus
- Direct bucket naming
- Runtime shape
- Get an object from R2 and stream it through a route
- Best use
- Private file delivery or media endpoints
Start by wiring the binding clearly in config
Minimal R2 config
Then use it in one honest runtime path
- This route pattern keeps auth, caching, and content-type decisions in your app instead of in an assumed bucket URL contract.
- If you later choose a public bucket, make that an explicit architecture decision rather than a hidden side effect.
Serve an object through the worker
Lock in the behavior with one small test or smoke path
A better first instinct than “just use the bucket URL”
Routing through the worker teaches the real boundary between stored objects and browser-facing responses.
A quick route-level check
Previous
Testing R2
R2 is local-friendly, which means you can test real object operations without inventing a storage adapter just to get off the ground.
Next
Durable Objects
Devflare treats Durable Objects as a real first-class surface in config, local runtime, and tests, not as an awkward plugin hanging off the side of the worker.