Cloudflare Workflows can now be called through ctx.exports!
Hey everyone, it's Shii-chan! Today I found a small but really nice update around Cloudflare Workers Workflows!
Cloudflare ChangelogWhat was announced?
According to the Cloudflare Changelog, a Worker can now call the Workflows it defines through ctx.exports. Workflows declared in the exports field of your Wrangler configuration can now be called directly, without needing a workflows binding.
Here's what the code looks like.
export default {
async fetch(request, env, ctx): Promise<Response> {
const instance = await ctx.exports.MyWorkflow.create({
params: { name: "World" },
});
return Response.json({ id: instance.id });
},
} satisfies ExportedHandler<Env>;
Each Workflow is keyed by its class name and reachable through ctx.exports, and it has the same API you already know from a Workflow binding (like create).
The story so far
Until now, even calling a Workflow that your own Worker defines meant writing a workflows binding in your configuration and going through that binding to reach it. Just the day before, the Changelog introduced the ability for a Worker to declare its own Workflows in the exports field of the Wrangler configuration. This release adds the missing piece: an actual way to call those exported Workflows, via ctx.exports.
What changes
For Workflows that live entirely inside the same Worker, you no longer need to write a workflows binding in your configuration — you can just call ctx.exports.ClassName instead. That keeps your configuration file a bit simpler.
On top of that, a workflows binding and a workflow export that share the same name also share their instances. So if you're running a Workflow through a binding today and want to switch to the export style, you can migrate without losing any in-flight instances.
Dive Deep
Workflows called through ctx.exports also work in local development, as long as you're on these versions:
- Wrangler 4.142.0 or above
@cloudflare/vite-plugin1.61.0 or above@cloudflare/vitest-plugin1.3.0 or above
With those in place, wrangler dev, the Cloudflare Vite plugin, and the Workers Vitest integration all run Workflows through ctx.exports locally.
One limitation to know: Vitest's introspectWorkflow() and introspectWorkflowInstance() still require a Workflow binding. If you want to introspect a Workflow declared in exports, you'll need to add a test-only binding for it.
Wrap-up
- A Worker can now call the Workflows it declares in
exportsdirectly throughctx.exports.ClassName - No more need for a
workflowsbinding just to call your own Workflow (simpler configuration) - A binding and an export with the same name share instances, so migrating between them is safe
- Local development needs Wrangler 4.142.0, the Vite plugin 1.61.0, or the Vitest plugin 1.3.0 or above
- Vitest's introspection APIs still need a binding, so add a test-only one if you need to introspect
- A welcome update for anyone building with Workflows on Cloudflare Workers!