ViteHub

Cloudflare

Configure @vitehub/workflow for Cloudflare Workflows, generated Wrangler bindings, and workflow entrypoint classes.

Cloudflare hosting selects the Cloudflare provider automatically. Register the integration and ViteHub emits Workflow bindings for Cloudflare builds. You can also set workflow.provider explicitly when local builds should emit Cloudflare output.

vite.config.ts
import { defineConfig } from 'vite'
import { hubWorkflow } from '@vitehub/workflow/vite'

export default defineConfig({
  plugins: [hubWorkflow()],
})

Generated output

For each discovered workflow, ViteHub generates a Cloudflare Workflow binding in wrangler.json:

{
  "workflows": [
    {
      "binding": "WORKFLOW_77656C636F6D65",
      "name": "workflow--77656c636f6d65",
      "class_name": "ViteHubWelcomeWorkflow"
    }
  ]
}

The build also emits workflow entrypoint classes that load the generated registry and call the matching defineWorkflow() handler.

Naming

Cloudflare names are derived from the discovered workflow name:

WorkflowBindingNameClass
welcomeWORKFLOW_77656C636F6D65workflow--77656c636f6d65ViteHubWelcomeWorkflow
email/welcomeWORKFLOW_656D61696C2F77656C636F6D65workflow--656d61696c2f77656c636f6d65ViteHubEmailWelcomeWorkflow

Use binding or name only when an existing deployment already has a required convention:

workflow: {
  provider: 'cloudflare',
  binding: 'WORKFLOW_WELCOME',
  name: 'workflow-welcome',
}

Handler context

Cloudflare runs receive provider: 'cloudflare' and pass the provider step object when it is available:

export default defineWorkflow<WelcomePayload>(async ({ payload, step }) => {
  await step?.do?.('send welcome email', async () => {
    console.log(payload.email)
  })
})

Keep the handler portable by checking for provider step helpers before using them.

Runtime calls

runWorkflow() starts the generated Cloudflare binding when it exists:

const run = await runWorkflow('welcome', payload)

getWorkflowRun() calls the binding get(id) and normalizes Cloudflare status metadata to queued, running, completed, failed, or unknown.

If the binding is missing, the runtime falls back to the generated registry so local and preview builds can still exercise the same application API.
Copyright © 2026