The Immortal Function: Inside vercel-labs/workflow-splitter
How compiler directives and durable execution are solving the brittle agent problem for serverless architectures.
- Vercel's workflow-splitter utilizes compiler directives to bring durable execution natively into TypeScript.
- The Splitter pattern isolates individual tasks within a larger process, preventing a single failure from destroying the entire workflow state.
- By reading its own source code from disk, the application turns business logic into a live, observable dashboard via Server-Sent Events.
- Unlike heavy SDK-driven alternatives, this syntax-first approach integrates directly into the serverless paradigm to solve the brittle nature of stateless AI agents.
The Brittle Agent Problem
Serverless architectures and AI agents share a fatal flaw. They are fundamentally stateless and brittle. If a multi-step process fails halfway through, the entire state is often lost. Consider an e-commerce order with three items. If the inventory check for one item fails, you should not drop the entire order. Yet in a standard serverless function, a transient network timeout or a crash destroys the entire process memory.
If you have a complex agent running through a twenty-step process and the fifth step fails because of a network hiccup, you shouldn’t have to restart from scratch.
This is the problem Vercel aims to solve with its Workflow Development Kit (WDK) and the accompanying workflow-splitter repository. It demonstrates how to move durable execution out of heavy third-party SDKs and directly into native TypeScript syntax.
The Compiler as the Orchestrator
Instead of wrapping code in complex SDK boilerplate, developers use specific compiler directives. The magic lies in two strings: "use workflow" and "use step". This tells the underlying infrastructure to snapshot the state automatically.
import { workflow } from '@vercel/workflow';
export const orderSplitter = workflow('order-splitter', async (payload) => {
'use workflow';
const results = [];
for (const item of payload.items) {
// This step is durable and will retry automatically on failure
const result = await processLineItem(item);
results.push(result);
}
return results;
});
async function processLineItem(item) {
'use step';
// Atomic unit of work
return await checkInventory(item);
}
Standard loops can now sleep, retry, and resume exactly where they left off. It is the React-ification of backend background jobs, making functions effectively immortal.
Anatomy of the Splitter
The repository provides a technical breakdown of this pattern in the workflows directory. It separates the orchestrator from the atomic unit of work. The orchestrator manages the high-level loop and aggregates results, while the step represents a retriable unit.
The code handles errors with nuance. A FatalError, like insufficient stock, instantly halts the specific step and reports failure to the orchestrator. Transient errors, such as network timeouts, trigger automatic retries. The global state remains intact regardless of individual step failures.
Code as Live Documentation
The most unique feature of the repository is its Code Workbench. The Next.js application physically reads its own source code from the disk. It then maps the execution state via Server-Sent Events (SSE) and highlights the exact line of code currently executing in the UI.
This turns business logic into a live observable dashboard. Users can watch an order move through lines of code in real-time, completely bypassing traditional log parsing.
The Durable Execution Landscape
Durable execution is not a new concept, but integrating it natively into the Next.js and TypeScript compiler is a significant shift. This syntax-first approach contrasts sharply with the infrastructure-first approaches of established players.
| Feature | Vercel WDK | Temporal | Inngest | Trigger.dev |
|---|---|---|---|---|
| Mental Model | Compiler Directives | Heavy SDK | Event-Driven | Background Jobs |
| State Management | Native TS syntax | Deterministic constraints | Event payloads | Database polling |
| Primary Target | Serverless / AI Agents | Enterprise Microservices | Serverless integrations | API integrations |
| Setup Complexity | Zero-config Next.js | Requires dedicated worker infrastructure | Drop-in SDK | Drop-in SDK |
By solving the partial success problem at the compiler level, workflow-splitter demonstrates a future where developers can build resilient, long-running processes without managing complex queues or worker fleets.