vercel-labs/workflow-publish-subscribe: Pub/Sub That Refuses to Be a Black Box
A durable workflow demo that turns message delivery into a visible, resumable sequence, then maps execution back onto the code so you can see exactly what happened and where.
- This repo turns Pub/Sub into an experience you can watch in real time, not a backend you have to infer from logs.
- Its core trick is a closed loop between durable workflow steps, SSE event streaming, and source-code line mapping.
- The demo argues that observability should be part of the product surface, not a separate debugging tool.
- Compared with queues and orchestrators, it makes the code itself the workflow boundary and the debugging surface.
The backend that shows its work
Most Pub/Sub demos stop at delivery. This one does something more interesting: it publishes a message, streams the workflow state back to the browser, and highlights the exact source lines that are executing. The result feels less like a queue demo and more like a backend with a built-in stage light.
That matters because backend systems are usually legible only after the fact. Here, the app is legible while it runs. The workflow does not just complete. It explains itself.
Why Pub/Sub is usually a black box
Traditional queues are good at one thing: moving work from A to B. The trouble starts when you need to know what happened inside that trip. Did a subscriber fail before the commit? Did a retry duplicate work? Which event is stuck, and why?
| Model | Where state lives | Retries | Observability | Developer writes | Operational overhead | Best fit |
|---|---|---|---|---|---|---|
| Traditional Pub/Sub | Mostly outside the app, in queue infrastructure | Usually added around the queue, often with dead-letter handling | Logs, metrics, and ad hoc tracing | Handlers plus retry glue | Medium to high | Simple async delivery at scale |
| Temporal | In the workflow engine | Built into durable execution | Strong execution history and tooling | Workflow code with engine semantics | High | Complex long-running orchestration |
| AWS Step Functions | In AWS state machine definitions | Native state transitions and retries | Visual graph plus cloud telemetry | JSON or visual state machine | Medium | Cloud-native orchestration on AWS |
| Inngest | In the platform and event graph | Managed by the event system | Good event visibility and replay | Function handlers and event triggers | Low to medium | Event-driven serverless apps |
| vercel-labs/workflow-publish-subscribe | Inside the workflow code itself | Checkpointed by durable steps | SSE stream plus source-line highlighting | JavaScript workflow with "use workflow" and "use step" | Low | Legible durable Pub/Sub demos and teaching |
The interesting part is not that this repo replaces every queue pattern. It does not. The interesting part is that it collapses delivery, retries, and traceability into one readable flow. The backend is not hidden behind an ops console. It is embedded in the code path itself.
Workflow Development Kit brings durability, reliability, and observability to async JavaScript so you can build apps and AI agents that suspend, resume, and maintain state with ease.
What the workflow actually does
At the center of the repo is publishSubscribeFlow. It reads like ordinary async JavaScript, but the directives change the game. "use workflow" marks the function as durable, and "use step" turns important phases into checkpoints that can resume after interruption.
export async function publishSubscribeFlow(input: PublishSubscribeInput) {
"use workflow";
const subscription = await registerSubscription(input);
const targets = await filterSubscribers(subscription.topic, input.payload);
const delivered = await deliverToSubscribers(targets, input.payload);
return summarizeDelivery(delivered);
}
async function deliverToSubscribers(subscribers, payload) {
"use step";
// durable delivery work happens here
}
That structure matters because the workflow is not a single fragile function call. It is a sequence of durable phases. If delivery fails halfway through, completed steps stay completed. The next run resumes from the last checkpoint instead of replaying the whole story.
The trick: code that streams its own execution
The most distinctive move in the repo is not the workflow runtime. It is the feedback loop. The app reads its own workflow file, builds a line map, then uses Server-Sent Events to stream execution events into the browser so the current phase can be highlighted against the source.
That makes the UI more than a viewer. It becomes a guided reading surface for the backend. You are not just watching subscribers get processed. You are watching the exact lines that process them light up in context.
const workflowSource = readFileSync('workflows/publish-subscribe.ts', 'utf8');
const lineMap = buildWorkflowLineMap(workflowSource);
const run = await start(publishSubscribeFlow, input);
const readable = await run.getReadable();
// SSE route forwards workflow events to the browser
for await (const chunk of readable) {
controller.enqueue(encodeSSE(chunk));
}
That is why this demo feels educational instead of decorative. It does not merely visualize state. It binds state back to source. The browser becomes a live annotation layer for the code itself.
Why this is different from queues and orchestrators
The comparison is subtle. Traditional queues optimize for transport. Orchestrators optimize for control flow. This repo optimizes for legibility. The workflow is still durable, but the product goal is to make durability understandable to a human looking at the screen.
| System | Core idea | Main strength | Main trade-off |
|---|---|---|---|
| Queue-based Pub/Sub | Push messages through a reliable pipe | Simple, scalable transport | Execution is harder to observe and reconstruct |
| Temporal | External durable engine runs the workflow | Powerful histories and retries | More infrastructure and a heavier conceptual model |
| AWS Step Functions | Managed state machine orchestration | Clear cloud-native transitions | Workflow logic is split between code and service |
| Inngest | Event-driven durable functions | Fast path to serverless reliability | Still a platform layer between code and runtime |
| This repo | Workflow code is the boundary and the debugger | Code, state, and tracing stay tightly coupled | Best suited to demos, teaching, and developer experience exploration |
The point is not to pick a universal winner. The point is to notice the design bet. This repo treats observability as part of the workflow contract. That is a different promise from most queue systems, and a cleaner promise than many orchestration stacks make to developers.
Running async jobs have been one of the common issues when using serverless paradigms as jobs reference persistent state and serverless is stateless. Instead of cloning competitors, Vercel invented an entirely new approach around building long-running tasks.
What Vercel is really testing here
This repo is a small demo with a larger thesis: durable JavaScript on serverless infrastructure should not feel like a compromise. The app suggests a future where reliability, replay, and observability are not bolted on after deployment. They are the way the code runs.
That is also why the project feels a little provocative. It makes a backend pattern behave like a teaching tool. For teams building event-driven systems, that is more than a nice demo. It is a different mental model for how software should explain itself.





