---
title: "Hello Workflow"
description: "Learn Vercel Workflow by deploying a visual workflow builder. Run your first durable workflow and see how APIs return instantly while background work continues."
canonical_url: "https://vercel.com/academy/visual-workflow-builder-on-vercel/hello-workflow"
md_url: "https://vercel.com/academy/visual-workflow-builder-on-vercel/hello-workflow.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-03-11T12:10:18.440Z"
content_type: "lesson"
course: "visual-workflow-builder-on-vercel"
course_title: "Build Visual Workflow Plugins on Vercel"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Hello Workflow

# Deploy and Run Your First Workflow

You can read docs about durable execution all day, but it won't click until you see it happen. This lesson gets you to that moment in 15 minutes.

## Outcome

Deploy the workflow builder, run Hello Workflow, and see the API return instantly while work continues in the background.

## Fast Track

1. Click Deploy to provision Neon + create your repo
2. Clone, link, pull env, run `pnpm dev`
3. Click Run on Hello Workflow, check Network tab for instant response

## Deploy the Visual Workflow Builder

One click provisions the starter app, Neon database, environment variables, and your own repo.

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-description=Visual%20Workflow%20Builder%20Starter\&demo-title=Visual%20Workflow%20Builder%20on%20Vercel\&project-name=visual-workflow-builder-on-vercel\&repository-name=workflow-builder-starter\&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fworkflow-builder-starter\&products=%5B%7B%22type%22%3A%22integration%22%2C%22protocol%22%3A%22storage%22%2C%22productSlug%22%3A%22neon%22%2C%22integrationSlug%22%3A%22neon%22%7D%5D\&skippable-integrations=0)

After deploy completes, you'll have:

- A live workflow builder at your Vercel URL
- A GitHub repo with the starter source
- A Neon Postgres database connected and ready

\*\*Note: Neon\*\*

[Neon](https://neon.tech/) is serverless Postgres. The deploy button provisions a database and wires up `DATABASE_URL` automatically. You won't need to touch database config in this course.

## Set Up Local Development

Clone your repo so you can build plugins locally.

**1. Install Vercel CLI** (if you don't have it):

```bash
npm i -g vercel
```

**2. Clone your repo:**

```bash
git clone https://github.com/YOUR_USERNAME/workflow-builder-starter
cd workflow-builder-starter
pnpm install
```

**3. Link to your Vercel project:**

```bash
vercel link
```

Select your project when prompted.

**4. Pull environment variables:**

```bash
vercel env pull .env.local
```

This pulls `DATABASE_URL` and any other project env vars from Vercel into `.env.local` (the standard Next.js local env file).

\*\*Warning: Common Mistake: Database Connection Errors\*\*

If you see `ECONNREFUSED` or connection errors, verify `.env.local` contains `DATABASE_URL` — open it and check. The value should start with `postgres://` or `postgresql://`.

**5. Push database schema:**

The starter uses [Drizzle ORM](https://orm.drizzle.team/) for database access. This command creates the tables your app needs:

```bash
pnpm db:push
```

**6. Start the dev server:**

```bash
pnpm dev
```

Open <http://localhost:3000>.

## Hands-on Exercise

1. You'll see the seeded **Hello Workflow** on the canvas
2. Click **Run** in the toolbar
3. Open DevTools Network tab

\*\*Reflection:\*\* Before you click Run: How long do you expect the API response to take? Will the workflow be finished when the response arrives, or still running? What HTTP status code do you expect?

\*\*Note: React Flow\*\*

The canvas is built with [React Flow](https://reactflow.dev/). You won't need to modify it for this course — just know that nodes and edges you see become the workflow definition that gets executed.

## Try It

Open Network tab and run the workflow. You should see:

```
POST /api/workflow/abc123/execute 200 142ms
```

Response:

```json
{ "executionId": "exec_xyz", "status": "running" }
```

Terminal shows the workflow completing *after* the response:

```
[Workflow Log] 👋 Hello from Vercel Workflow!
```

The API returned in \~100-200ms. The workflow finished a moment later. That's the pattern.

\*\*Note: Mental Model: Keep Your API Fast\*\*

The API returned instantly, but the workflow is still running. That's the core pattern — routes return immediately, heavy work runs via `"use workflow"` in the background.

## Solution

The key insight is **fire-and-forget**: calling `start()` schedules durable execution without blocking. Your route handler doesn't `await` the workflow — it kicks it off and moves on.

This is a deliberate tradeoff. Blocking until completion would tie up your function for the entire workflow duration — seconds, minutes, even hours for complex flows. Instead, `start()` returns a handle instantly, and the workflow engine takes over. You get sub-200ms API responses regardless of how long the actual work takes.

The consequence: your API can't return the workflow's result directly. You'll need to poll, use webhooks, or check execution status later. That's the deal — fast APIs in exchange for async result handling.

## What's Happening

The API doesn't wait for the workflow to finish. It starts the workflow and returns immediately.

```
POST /api/workflow/{id}/execute
├── Create execution record
├── start(executeWorkflow, [...])  ← kicks off background work
└── Return { executionId, status: "running" }  ← instant

Background (continues after response):
├── Run each step
└── Update execution record when done
```

The `start()` function from `@vercel/workflow` schedules durable execution without blocking. The workflow runs with retries, step isolation, and logging built in.

\*\*Note: Vercel Workflow\*\*

[Vercel Workflow](https://vercel.com/docs/workflow) is the durable execution engine. Tag a function with `"use workflow"`, tag async calls with `"use step"`, and you get retries, observability, and crash recovery. Steps run on [Vercel Functions](https://vercel.com/docs/functions) with [Fluid Compute](https://vercel.com/docs/fluid-compute) for efficient execution. See the [Workflows and Steps](https://useworkflow.dev/docs/foundations/workflows-and-steps) guide for how these directives work under the hood.

```typescript title="app/api/workflow/[workflowId]/execute/route.ts"
// Don't await - just start it
executeWorkflowBackground(
  execution.id,
  workflowId,
  workflow.nodes,
  workflow.edges,
  input
);

// Return immediately
return NextResponse.json({
  executionId: execution.id,
  status: "running",
});
```

```yaml
quiz:
  question: "Why does the API return { status: 'running' } before the workflow finishes?"
  choices:
    - id: "async-await"
      text: "The code forgot to await the workflow"
    - id: "background"
      text: "Workflows run in the background so APIs stay fast"
    - id: "timeout"
      text: "The workflow timed out"
    - id: "error"
      text: "There was an error starting the workflow"
  correctAnswerId: "background"
  feedback: "{\n    correct: \"Exactly. The API returns instantly while the workflow continues in the background. That's the core pattern — routes stay fast, heavy work runs durably via \\\"use workflow\\\".\",\n    incorrect: \"This is intentional, not an error. The whole point is that APIs return instantly while workflows run in the background.\"\n  }"
```

## Commit

```bash
git add -A
git commit -m "chore: configure local dev environment for workflow builder"
```

## Done

- [ ] Deploy button created your repo and provisioned Neon
- [ ] Cloned and running locally
- [ ] Ran a workflow
- [ ] API returned in under 200ms
- [ ] Saw "👋 Hello from Vercel Workflow!" in server logs
- [ ] Committed local setup

## What's Next

You've seen workflows run in the background. But what if a workflow needs to wait for something external — a webhook, a user action, a payment confirmation? Lesson 2 shows how workflows pause and resume.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
