By the end of this guide you will have a fully typed Cloudflare Workflow — a step that adds two numbers — running locally with the Vite dev server. The workflow will be auto-discovered by the Sideffect Vite plugin, which means noDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/eersnington/sideffect/llms.txt
Use this file to discover all available pages before exploring further.
wrangler.jsonc changes are needed: the binding ADD_NUMBERS will appear on your env object and be ready to call from your Worker’s fetch handler.
Create
src/workflows/add-numbers.ts and define the addNumbers step. Step.make takes a human-readable name and a definition object with a payload schema, a result schema, and a run function.import { Schema, Step, Workflow } from "sideffect";
export const addNumbers = Step.make("add numbers", {
payload: Schema.Struct({ left: Schema.Number, right: Schema.Number }),
result: Schema.Number,
run: ({ left, right }) => left + right,
});
The schemas serve a dual purpose: they document the contract of the step and they validate payloads at the boundaries of workflow execution. The
run function may return a plain value, a Promise, or an Effect.In the same file, construct a
Workflow with a name and a payload schema, then call .toLayer() to wire steps together into the workflow body.import { Schema, Step, Workflow } from "sideffect";
export const addNumbers = Step.make("add numbers", {
payload: Schema.Struct({ left: Schema.Number, right: Schema.Number }),
result: Schema.Number,
run: ({ left, right }) => left + right,
});
export const addNumbersLayer = Workflow.make({
name: "add-numbers",
payload: Schema.Struct({ left: Schema.Number, right: Schema.Number }),
}).toLayer(async ({ payload }, step) => {
const sum = await step.do(addNumbers, payload);
return { sum };
});
step.do executes a step inside Cloudflare’s durable step runtime — providing automatic retries, checkpointing, and replay safety. The result is fully typed based on the result schema you provided.The workflow
name drives the auto-generated binding name. Sideffect converts "add-numbers" to ADD_NUMBERS as the Wrangler binding and to AddNumbers as the WorkflowEntrypoint class name. No configuration is required.Add the Sideffect plugin to your Vite config by wrapping the Cloudflare plugin with
withCloudflareWorkflows. Point workflowPaths at the directory containing your workflow files.import { cloudflare } from "@cloudflare/vite-plugin";
import { defineConfig } from "vite";
import { withCloudflareWorkflows } from "sideffect/vite";
export default defineConfig({
plugins: [
...withCloudflareWorkflows(cloudflare, {
workflowPaths: ["src/workflows"],
}),
],
});
At dev and build time, Sideffect statically analyses the files in
src/workflows, discovers every exported workflow layer, and injects the matching workflows binding block into the build output. Your wrangler.jsonc requires no workflows field.src/workflows is the default scan path used when workflowPaths is omitted. Customise it — or supply multiple paths — by passing a workflowPaths array as shown above.Workflow bindings appear on
env like any other Cloudflare binding. Trigger the add-numbers workflow from your Worker’s fetch handler using env.ADD_NUMBERS.create:export default {
async fetch(_req: Request, env: Env): Promise<Response> {
const instance = await env.ADD_NUMBERS.create({
params: { left: 2, right: 3 },
});
return Response.json({ id: instance.id });
},
};
env.ADD_NUMBERS is typed from the generated Env types that the Vite plugin produces — no manual declare statements needed.Start the local development server. Sideffect’s Vite plugin runs its workflow discovery step before Wrangler boots, so your workflow is registered and reachable immediately.
What’s Next
Now that you have a working workflow, explore the rest of the documentation to learn about step context, rollback handlers,step.sleep, step.waitForEvent, and the manual Wrangler adapter for projects without Vite.