惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
News and Events Feed by Topic
D
DataBreaches.Net
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recorded Future
Recorded Future
Y
Y Combinator Blog
C
Check Point Blog
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence
小众软件
小众软件
F
Full Disclosure
S
SegmentFault 最新的问题
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
Martin Fowler
Martin Fowler
P
Proofpoint News Feed
博客园 - 司徒正美
量子位
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
T
Tenable Blog
P
Privacy International News Feed
T
The Exploit Database - CXSecurity.com
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
Google Developers Blog
P
Proofpoint News Feed
T
Threatpost
Know Your Adversary
Know Your Adversary
aimingoo的专栏
aimingoo的专栏
Latest news
Latest news
Security Latest
Security Latest
Cyberwarzone
Cyberwarzone
A
About on SuperTechFans
P
Palo Alto Networks Blog
Stack Overflow Blog
Stack Overflow Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Hacker News
The Hacker News
A
Arctic Wolf
AWS News Blog
AWS News Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
NISL@THU
NISL@THU
Last Week in AI
Last Week in AI
Hacker News - Newest:
Hacker News - Newest: "LLM"
Spread Privacy
Spread Privacy
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Application and Cybersecurity Blog
Application and Cybersecurity Blog
I
InfoQ
J
Java Code Geeks
H
Help Net Security

Workflow SDK Documentation

Patterns for Defining Tools Human-in-the-Loop Building Durable AI Agents Queueing User Messages Resumable Streams Sleep, Suspense, and Scheduling Streaming Updates from Tools API Reference Workflow Globals Changelog Resilient run start Cookbook Building a World Deploying Astro Express Fastify Hono Getting Started NestJS Next.js Nitro Nuxt Python SvelteKit Vite corrupted-event-log fetch-in-workflow hook-conflict Errors node-js-module-in-workflow serialization-failed start-invalid-workflow-function step-not-registered timeout-in-workflow webhook-invalid-respond-with-value webhook-response-not-sent workflow-not-registered Errors & Retrying Hooks & Webhooks Idempotency Foundations Serialization Starting Workflows Streaming Versioning Workflows and Steps How the Directives Work Encryption Event Sourcing Framework Integrations Understanding Directives Migration Guides Migrating from AWS Step Functions Migrating from Inngest Migrating from Temporal Observability Testing Server-Based Testing createHook createWebhook defineHook FatalError fetch getStepMetadata getWorkflowMetadata getWritable workflow RetryableError sleep @workflow/vitest DurableAgent @workflow/ai WorkflowChatTransport getHookByToken getRun getWorld workflow/api resumeHook resumeWebhook Chat Session Modeling runtime-decryption-failed Upgrading Workflows abort-signal-timeout-in-workflow Cancellation How Cancellation Works Internal Serializable AbortController and AbortSignal Eager Processing of Steps & Incremental Event Replay Agent Cancellation Sequential & Parallel Execution Workflow Composition Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK Migrating from trigger.dev Secure Credential Handling Local World | Workflow SDK Postgres World | Workflow SDK Vercel World | Workflow SDK
TanStack Start
2026-05-04 · via Workflow SDK Documentation

Set up your first durable workflow in a TanStack Start application.

This guide will walk through setting up your first workflow in a TanStack Start app. Along the way, you'll learn more about the concepts that are fundamental to using the Workflow SDK in your own projects.


Start by creating a new TanStack Start project:

npx @tanstack/cli create my-workflow-app

Enter the newly made directory:

Install workflow

Configure TanStack Start

TanStack Start runs on Vite, so the Workflow SDK is wired in via the same workflow/vite plugin. Add workflow() to the existing plugins array in your Vite config — list it first so the "use workflow" and "use step" transforms run before any other plugin processes the file.

import { defineConfig } from "vite";
import { workflow } from "workflow/vite";
// ...

export default defineConfig({
  plugins: [
    workflow(), 
    // ...the existing tanstackStart(), nitro(), and any other plugins
  ],
});

Create a new file for our first workflow:

import { sleep } from "workflow";

export async function handleUserSignup(email: string) {
  "use workflow"; 

  const user = await createUser(email);
  await sendWelcomeEmail(user);

  await sleep("5s"); // Pause for 5s - doesn't consume any resources
  await sendOnboardingEmail(user);

  return { userId: user.id, status: "onboarded" };
}

We'll fill in those functions next, but let's take a look at this code:

  • We define a workflow function with the directive "use workflow". Think of the workflow function as the orchestrator of individual steps.
  • The Workflow SDK's sleep function allows us to suspend execution of the workflow without using up any resources. A sleep can be a few seconds, hours, days, or even months long.

Let's now define those missing functions.

import { FatalError } from "workflow"

// Our workflow function defined earlier

async function createUser(email: string) {
  "use step"; 

  console.log(`Creating user with email: ${email}`);

  // Full Node.js access - database calls, APIs, etc.
  return { id: crypto.randomUUID(), email };
}

async function sendWelcomeEmail(user: { id: string; email: string; }) {
  "use step"; 

  console.log(`Sending welcome email to user: ${user.id}`);

  if (Math.random() < 0.3) {
  // By default, steps will be retried for unhandled errors
   throw new Error("Retryable!");
  }
}

async function sendOnboardingEmail(user: { id: string; email: string}) {
  "use step"; 

  if (!user.email.includes("@")) {
    // To skip retrying, throw a FatalError instead
    throw new FatalError("Invalid Email");
  }

  console.log(`Sending onboarding email to user: ${user.id}`);
}

Taking a look at this code:

  • Business logic lives inside steps. When a step is invoked inside a workflow, it gets enqueued to run on a separate request while the workflow is suspended, just like sleep.
  • If a step throws an error, like in sendWelcomeEmail, the step will automatically be retried until it succeeds (or hits the step's max retry count).
  • Steps can throw a FatalError if an error is intentional and should not be retried.

We'll dive deeper into workflows, steps, and other ways to suspend or handle events in Foundations.

To invoke your new workflow, add a server handler at src/routes/api/signup.ts:

import { createFileRoute } from "@tanstack/react-router";
import { json } from "@tanstack/react-start";
import { start } from "workflow/api";
import { handleUserSignup } from "../../workflows/user-signup";

export const Route = createFileRoute("/api/signup")({
  server: {
    handlers: {
      POST: async ({ request }) => {
        const { email } = await request.json();
        // Executes asynchronously and doesn't block your app
        await start(handleUserSignup, [email]);
        return json({ message: "User signup workflow started" });
      },
    },
  },
});

This route handler creates a POST request endpoint at /api/signup that will trigger your workflow.

Workflows can be triggered from API routes or any server-side code.

To start your development server, run the following command in your terminal in the TanStack Start root directory:

Once your development server is running, you can trigger your workflow by running this command in the terminal:

curl -X POST --json '{"email":"hello@example.com"}' http://localhost:3000/api/signup

Check the dev server logs to see your workflow execute as well as the steps that are being processed.

Additionally, you can use the Workflow SDK CLI or Web UI to inspect your workflow runs and steps in detail.

# Open the observability Web UI on http://localhost:3456
npx workflow web
# or if you prefer a terminal interface, use the CLI inspect command
npx workflow inspect runs

Workflow SDK Web UI


Workflow SDK apps currently work best when deployed to Vercel and needs no special configuration.

Enable Fluid compute before deploying. Workflow is designed to take advantage of Fluid compute for efficient suspension and resumption. Without Fluid compute enabled, each workflow resume incurs a separate function cold start, which can result in significantly higher costs.

Check the Deploying section to learn how your workflows can be deployed elsewhere.