Try your first bindings by growing the same worker one route at a time
Take the same starter worker, split it into routes and helpers, then add one binding-backed route at a time so can stay small.
Keep one worker shape throughout: a tiny , a tree for leaf handlers, and one shared helper module that can read or write the active request context through when that keeps the code cleaner.
- Best for
- Growing the first worker without turning into one crowded file
- Base shape
- Tiny plus and shared helpers
- Habit to keep
- after binding changes
Keep the same worker, but split it into routes and helpers
The additive move after the first worker is not a different app. It is the same worker with one tiny fetch entry, one route tree, and one shared request helper.
Once the first worker responds and maybe already has one small test, the next step is to keep tiny. Let it do request-wide setup, then let own the individual URLs.
That shape also lets helper modules read the active request path, route params, request body, or request id through and without turning every function signature into plumbing.
Durable Object
Add one counter route that forwards to one object class and keeps state there.
R2 bucket
Add one route that stores and reads one named file without bloating the global fetch file.
Browser Rendering
Add one route that opens a page and returns its title so the browser binding stays obvious.
- 1
Keep for request-wide setup only.
- 2
Add so the route tree is explicit in config.
- 3
Move URL-specific work into files.
- 4
Put shared request helpers in and let them read active request context from when that keeps route files cleaner.
- 5
Add one binding-backed route at a time instead of rebuilding the worker from scratch.
This is still the same worker
You are not swapping architectures here. You are just letting stay small while routes and helpers take the extra responsibility.
Keep the same worker, but let routes and helpers do the growing
The fetch file stays tiny. Routes own URLs, and one helper module reads and writes the active request context through Devflare runtime when you need it.
Add one Durable Object-backed route
Keep the same route-based worker and add one counter route, one transport file, and one object class.
Use the same , the same request helper, and the same route tree. The new work lives in one route file that talks to one Durable Object namespace through a custom method.
That keeps the route honest: the HTTP path stays in , the stateful method stays in , and restores the returned value object cleanly on the worker side.
Why this is a good first Durable Object
It proves binding lookup, object identity, route-to-object flow, and persisted state without turning the whole worker into object-specific plumbing.
Same worker, now add a counter route, transport, and one Durable Object
The familiar fetch file and helper stay in place. You add the binding config, one transport file, the counter route, and the object class that exposes a custom `increment()` method.
Add one R2-backed route
Keep the same worker shape and let one route file own the bucket round-trip.
Here the route path becomes the obvious home for the binding: owns both the and flow for one named object.
The shared helper still provides request-wide context, route params, and request reads through runtime helpers, while the route file keeps the bucket usage visible and local to the URL that needs it.
Why this is a good first R2 route
It proves route params, the bucket binding, and a clean read/write boundary without teaching a giant upload architecture before the first success.
Same worker, now add one file route and one bucket binding
The global fetch file stays tiny. The new work lives in one route file under `src/routes/files/[name].ts`, while the helper module still reads the active request through runtime helpers.
Add one browser-backed route
Keep the same worker shape and let one route prove the browser binding.
Browser Rendering gets simpler when it looks like the other examples: the shared fetch file stays untouched, and one route file owns the browser work.
Install before you try this route, and remember that Devflare currently supports exactly one browser binding in config.
Keep the first browser path skinny
One title read is enough to prove the binding. Save screenshots, PDFs, and longer browser workflows for the next pass once the launch path is already trustworthy.
Same worker, now add one browser-backed route
The route tree grows by one file, and the helper still gives that route access to request-scoped context without bloating `src/fetch.ts`.
Open the next page when the first quick win works
Once one tiny example works locally, jump to the dedicated binding guides for the bigger caveats, testing patterns, and architecture choices.
Bindings
Durable Objects guide
Read the fuller guidance on stateful objects, migrations, previews, and local testing.
Bindings
R2 guide
Open the R2 page for delivery boundaries, testing patterns, and storage choices.
Bindings
Browser Rendering guide
Open the browser guide when you need the single-binding caveat, dev-server details, or heavier browser workflows.
Previous
Your first route tree
The first route-tree step should only change project shape: config, request-wide middleware, one route, and one worker-level test.
Next
Deploy and Preview
Take the same starter worker, ship one named preview, then remove that preview scope cleanly.