Back to Rivet

Vercel Workflows (Beta)

website/src/content/docs/integrations/vercel-workflows.mdx

2.3.74.7 KB
Original Source
<Info> This integration is in beta. APIs may change between releases. </Info>

@rivet-dev/vercel-world implements the Vercel World API with native Rivet Actors.

View the complete example →

Quickstart

<Steps> <Step title="Create a project">

Set up a Vercel Workflows project for your framework on Node.js 22 or newer. The Workflows getting-started guides cover Next.js, Astro, Express, Fastify, Hono, Nitro, Nuxt, SvelteKit, TanStack Start, and Vite.

</Step> <Step title="Install the World">
sh
npm install workflow @rivet-dev/vercel-world
</Step> <Step title="Write a workflow">

Create workflows/order.ts:

<CodeSnippet file="examples/vercel-workflow/workflows/order.ts" title="workflows/order.ts" /> </Step> <Step title="Serve Workflow and Rivet together">

The World starts Rivet lazily in the Workflows process. You do not need a second server or a framework instrumentation hook.

<Tabs> <Tab title="Next.js">

Create app/api/orders/[id]/route.ts:

ts
import { start } from "workflow/api";
import { processOrder } from "@/workflows/order";

export async function POST(
	_request: Request,
	{ params }: { params: Promise<{ id: string }> },
) {
	const { id } = await params;
	const run = await start(processOrder, [id]);
	return Response.json({ runId: run.runId });
}
</Tab> <Tab title="Hono">

Hono has no build system of its own, so this server mounts the generated flow and step handlers itself. See HTTP routes.

Create src/server.ts:

<CodeSnippet file="examples/vercel-workflow/src/server.ts" title="src/server.ts" /> </Tab> </Tabs>

Create .env with the variables under Configuration, then build and run:

sh
npm run build
npm run dev
</Step> <Step title="Validate the workflow">

Start a run:

sh
curl -X POST http://localhost:3000/orders/42

Use Vercel's Workflow Vitest harness. The first World operation starts the native Rivet registry and Engine in the test process:

sh
npm test
</Step> </Steps>

Configuration

Select the World and configure its Rivet connection in the application process:

<CodeSnippet file="examples/vercel-workflow/.env.example" title=".env" />
VariableRequiredPurpose
WORKFLOW_TARGET_WORLDYesLoads @rivet-dev/vercel-world through Vercel Workflows
WORKFLOW_RUNTIME_URLYesExternally reachable base URL of the Workflows HTTP server
WORKFLOW_QUEUE_NAMESPACENoShared queue namespace used by Workflows and crash-safe initial dispatch
RIVET_ENDPOINTRemote onlyRivet Engine endpoint
RIVET_NAMESPACERemote onlyNamespace containing the World actors
RIVET_POOLRemote onlyPool that hosts the native World registry
RIVET_TOKENCloud onlyToken sent to Rivet
RIVET_WORKFLOW_SECRETRecommended when publicShared bearer secret for World-to-runtime delivery

Local development starts the native Rivet Engine automatically. For production, configure the remote Rivet connection. Run the combined server at WORKFLOW_RUNTIME_URL; its World client and native registry use the same Rivet endpoint, namespace, and pool.

HTTP routes

workflow build generates the flow and step handlers under .well-known/workflow/v1. WORKFLOW_RUNTIME_URL must resolve to the service hosting those routes. Do not point it at the Rivet Engine. If RIVET_WORKFLOW_SECRET is set, delivery carries that value as a bearer token and rejects requests without it.

Durability

The World stores runs, event logs, queues, streams, hook tokens, and recovery alarms in Rivet Actors.

Recovery is local to each run; startup does not scan all actors. Queue an initial workflow with the default namespace or WORKFLOW_QUEUE_NAMESPACE. The current Vercel Workflows does not include a per-call start({ namespace }) value in the run_created event, so that per-call override cannot be reconstructed after a crash and is not supported by this World.

Application code continues to use "use workflow", "use step", workflow/api, hooks, sleeps, and streams exactly as documented by Vercel.

Testing

<CodeSnippet file="examples/vercel-workflow/vitest.integration.config.ts" title="vitest.integration.config.ts" /> <CodeSnippet file="examples/vercel-workflow/workflows/order.integration.test.ts" title="workflows/order.integration.test.ts" />

waitForSleep observes the durable sleep, wakeUp resumes that exact correlation, and the assertions wait for the final persisted result.

See the Vercel Workflows documentation for the SDK itself.