migrating-to-workflow-sdk

작성자: vercel

Temporal, Inngest, Trigger.dev 및 AWS Step Functions 워크플로를 Workflow SDK로 마이그레이션합니다. Activities, Workers, Signals, step.run() 등을 포팅할 때 사용합니다.

npx skills add https://github.com/vercel/workflow --skill migrating-to-workflow-sdk

Migrating to the Workflow SDK

Use this skill when converting an existing orchestration system to the Workflow SDK.

Intake

  1. Identify the source system:
    • Temporal
    • Inngest
    • Trigger.dev
    • AWS Step Functions
  2. Identify the target runtime:
    • Managed hosting -> keep examples focused on start(), getRun(), hooks/webhooks, and route handlers.
    • Self-hosted -> also read references/runtime-targets.md and explicitly say the workflow/step code can stay the same, but deployment still needs a World implementation and startup bootstrap.
  3. Extract the source constructs:
    • entrypoint
    • waits / timers
    • external callbacks / approvals
    • retries / failure handling
    • child workflows / fan-out
    • progress streaming
    • external side effects

Default migration rules

  • Put orchestration in "use workflow" functions.
  • Put side effects, SDK calls, DB calls, HTTP calls, and stream I/O in "use step" functions.
  • Use sleep() only in workflow context.
  • For Signals, step.waitForEvent(), and .waitForTaskToken, choose exactly one resume surface:
    • resume/internal -> createHook() + resumeHook() when the app resumes from server-side code with a deterministic business token.
    • resume/url/default -> createWebhook() when the external system needs a generated callback URL and the default 202 Accepted response is fine.
    • resume/url/manual -> createWebhook({ respondWith: 'manual' }) only when the prompt explicitly requires a custom response body, status, or headers.
    • If a callback-URL prompt does not specify response semantics, default to resume/url/default and make the assumption explicit in ## Open Questions.
  • Never pair createWebhook() with resumeHook(), and never pass token: to createWebhook().
  • Wrap start() and getRun() inside "use step" functions for child runs.
  • Use getStepMetadata().stepId as the idempotency key for external writes.
  • Use getWritable() in workflow context to obtain the stream, but interact with it (write, close) only inside "use step" functions.
  • Prefer rollback stacks for multi-step compensation.
  • Choose app-boundary syntax in this order:
    1. If the prompt explicitly asks for framework-agnostic app-boundary code, use plain Request / Response even when a framework like Hono is named.
    2. Otherwise, if the target framework is named, shape app-boundary examples to that framework.
    3. Otherwise, keep examples framework-agnostic with Request / Response. Do not default to Next.js-only route signatures unless Next.js is explicitly named.

Fast memory aid:

  • Callback URL + default ack -> createWebhook()
  • Callback URL + custom ack -> createWebhook({ respondWith: 'manual' })
  • Deterministic server-side resume -> createHook() + resumeHook()

Fast-path router

Load references/resume-routing.md when the source pauses for Signals, step.waitForEvent(), or .waitForTaskToken.

Fast defaults:

  • callback URL only -> resume/url/default
  • callback URL + explicit custom response -> resume/url/manual
  • deterministic server-side resume -> resume/internal
  • self-hosted -> add runtime/self-hosted
  • named framework -> add boundary/named-framework
  • explicit framework-agnostic request -> add boundary/framework-agnostic

Before drafting ## Migrated Code, write the selected route keys in ## Migration Plan.

Source references

  • Temporal -> references/temporal.md
  • Inngest -> references/inngest.md
  • Trigger.dev -> references/trigger-dev.md
  • AWS Step Functions -> references/aws-step-functions.md

Shared references

  • references/shared-patterns.md — reusable code templates for hooks, child workflows, idempotency, streaming, and rollback.
  • references/runtime-targets.md — Managed vs custom World guidance.
  • references/resume-routing.md — route-key selection, obligations, and exact ## Migration Plan shape.
  • references/retries.md — canonical retry mechanics: stepFn.maxRetries, RetryableError({ retryAfter }), FatalError.

Required output shape

Return the migration in this structure:

## Migration Plan
## Source -> Target Mapping
## Migrated Code
## App Boundary / Resume Endpoints
## Verification Checklist
## Open Questions

Verification checklist

Fail the draft if any of these are true:

  • ## Migration Plan omits Route keys
  • ## Migration Plan omits Why these route keys
  • ## Migration Plan lists route keys that do not match the prompt
  • ## Migration Plan lists required code obligations that do not match the selected route keys
  • Source-framework primitives remain in the migrated code
  • Side effects remain in workflow context
  • sleep() appears inside a step
  • Stream interaction (getWriter(), write(), close()) appears inside a workflow function
  • Child workflows call start() / getRun() directly from workflow context
  • External writes omit idempotency keys
  • Hooks/webhooks are missing where the source used signals, waitForEvent, or task tokens
  • A callback-URL flow uses createHook() + resumeHook() instead of createWebhook()
  • A resume/url/default or resume/url/manual migration invents a user-authored callback route or resumeWebhook() wrapper when webhook.url should be the only resume surface
  • createWebhook() is given a custom token or paired with resumeHook()

Validation note:

  • Reading webhook request data in workflow context is allowed. Only request.respondWith() is step-only.

Additional fail conditions:

  • resume/internal output omits resumeHook() in app-boundary code
  • resume/internal output omits a deterministic business token
  • resume/internal output emits createWebhook() or webhook.url
  • resume/url/default output does not pass webhook.url to the external system
  • resume/url/default output emits resumeHook(), respondWith: 'manual', or RequestWithResponse without a custom-response requirement in the prompt
  • resume/url/default output invents a user-authored callback route or resumeWebhook() wrapper when webhook.url is the intended resume surface
  • resume/url/manual output does not pass webhook.url to the external system
  • resume/url/manual output omits RequestWithResponse or await request.respondWith(...)
  • resume/url/manual output calls request.respondWith(...) outside a "use step" function
  • resume/url/manual output invents a user-authored callback route or resumeWebhook() wrapper when webhook.url is the intended resume surface
  • createWebhook() is paired with resumeHook()
  • self-hosted output omits World extends Queue, Streamer, Storage, startWorkflowWorld(), or the explicit note that the workflow and step code can stay the same while the app still needs a custom World
  • named-framework output mixes framework syntax with plain Request / Response app-boundary code without a framework-agnostic override

For concrete passing code, load:

  • references/shared-patterns.md -> ## Generated callback URL (default response)
  • references/shared-patterns.md -> ## Generated callback URL (manual response)
  • references/runtime-targets.md -> ## Self-hosted output block
  • references/aws-step-functions.md -> ## Combined recipe: callback URL on self-hosted Hono

Sample prompt

Migrate this Inngest workflow to the Workflow SDK.
It uses step.waitForEvent() with a timeout and step.realtime.publish().

Expected response shape:

## Migration Plan
## Source -> Target Mapping
## Migrated Code
## App Boundary / Resume Endpoints
## Verification Checklist
## Open Questions

Example references

Load a worked example only when the prompt needs concrete code:

  • references/shared-patterns.md -> ## Named-framework internal resume example (Hono)
  • references/shared-patterns.md -> ## Generated callback URL (default response)
  • references/shared-patterns.md -> ## Generated callback URL (manual response)
  • references/runtime-targets.md -> ## Self-hosted output block
  • references/aws-step-functions.md -> ## Combined recipe: callback URL on self-hosted Hono

Reject these counterexamples:

  • resume/url/default or resume/url/manual + user-authored callback route when webhook.url is the intended resume surface
  • createWebhook() paired with resumeHook()
  • named-framework app-boundary output mixed with plain Request / Response without a framework-agnostic override

vercel의 다른 스킬

vercel-optimize
vercel
Vercel에 배포된 프로젝트(특히 Next.js, SvelteKit, Nuxt 및 제한된 Astro 앱)의 비용 및 성능 최적화에 사용합니다. 먼저 Vercel 메트릭, 사용량, 프로젝트 구성 및 코드 스캔 결과를 수집하고, 메트릭 기반 후보만 조사합니다. 검증된 파일과 버전 인식 Vercel/프레임워크 문서를 기반으로 순위가 매겨진 권장 사항을 생성합니다. Vercel 청구액 감소, 느리거나 비용이 많이 드는 경로, 캐싱 기회, 함수 호출, 빌드 시간, 빠른 데이터 전송, 코어...
officialdevelopmentdevops
writing-guidelines
vercel
문서/산문이 작성 가이드라인을 준수하는지 검토합니다. "내 문서 검토", "작문 스타일 확인", "산문 감사", "문서 음성 및 톤 검토", "이 페이지를 작성 핸드북과 비교 확인" 요청 시 사용하세요.
officialdocumentcommunication
agent-friendly-apis
vercel
Vercel Academy의 Agent-Friendly APIs 코스를 위한 컴패니언 스킬입니다. 피드백 API를 구축하고, 구조화된 문서로 에이전트 친화적으로 만든 다음, 문서를 자동으로 생성하는 Claude Code 스킬을 만듭니다.
official
filesystem-agents
vercel
당신은 Vercel Academy의 Building Filesystem Agents 과정을 위한 지식이 풍부한 조교입니다. 학생들이 bash를 사용하여 파일 시스템을 탐색하는 에이전트를 구축하여 구조화된 데이터에 대한 질문에 답할 수 있도록 도와줍니다.
official
add-provider-package
vercel
AI SDK에 새로운 AI 제공자 패키지를 추가하기 위한 가이드입니다. AI 서비스를 SDK에 통합하기 위해 새로운 @ai-sdk/<provider> 패키지를 생성할 때 사용하세요.
official
csv
vercel
bash 도구를 사용하여 CSV 데이터를 분석하고 변환합니다.
official
ai
vercel
Python `ai` module — models, agents, hooks, middleware, MCP, structured output
official
cron-jobs
vercel
Vercel Cron Jobs 구성 및 모범 사례. vercel.json에서 예약된 작업을 추가, 편집 또는 디버깅할 때 사용합니다.
official