TL;DR
This is the quick and dirty way to get started – but be sure to read the full guide below.Getting Started: Step-by-step
How this tutorial works: We’ll use Claude Code throughout - Output is designed to work with Claude Code natively - we’ll ask things in plain English, and Claude Code builds it. Along the way, we show the CLI commands running under the hood—so you understand both approaches, or you can just use the CLI directly if you prefer.
Prerequisites
Before starting, you’ll need:- Node.js 20+ — Download here
- Docker Desktop — Download here we’ll need for running some of dependencies (PostgreSQL, Redis, Temporal)
- VS Code with Claude Code — Install extension. You can use the CLI directly if you prefer or Claude Code outside of VS Code as well - your choice, but AI assisted is how we recommend you use Output.
- Anthropic API key — Get one here
Create Your Project
Open your terminal and run:
The CLI creates the project, configures your
.env, and installs dependencies. Here’s what you get:
Start Development Services
Navigate into your project and start the dev environment:Open VS Code with Claude Code
Open a new terminal and launch VS Code:Run the Example Workflow
Tell Claude Code:“Run the blog_evaluator workflow with the test scenario”Under the hood, Claude Code runs:
Explore Execution via UI
For execution, Output uses Temporal.io - a battle-tested workflow engine. You can use the Temporal UI at http://localhost:8080 to inspect your workflow runs. This is likely your first experience with Temporal. The UI can feel overwhelming at first - there’s a lot of information. Don’t worry about understanding everything now. The key thing to know: Temporal records every workflow execution, and this UI lets you inspect them. You’ll see your workflow run listed. Click into it to see:- Input: The question you asked
- Output: The LLM’s answer
- Event History: Every step that executed, with timing
Explore Execution Traces
Output traces every operation - not just LLM calls, but HTTP requests, step executions, and timing data. This happens automatically with zero configuration. The quickest way to inspect a run isoutput workflow debug with the workflow ID from the previous step:
--format json to get the full untruncated trace, including complete LLM inputs and outputs.
Traces are also saved as JSON files in your project’s logs/runs/ directory — you can open them directly or share them with teammates:
Understand the Code
Let’s look at what makes up a workflow. Theblog_evaluator example demonstrates the key patterns:
options.activityOptions.retry configures automatic retries at the workflow level. (No I/O here—this matters later when we cover rewinding and replaying workflows.)
steps.ts — The actual work. API calls, database queries—anything that talks to the outside world (aka I/O) goes here. If a step fails, Output retries it automatically.
evaluators.ts — The quality assessment layer. Evaluators wrap LLM calls and return structured results with confidence scores. Use them when you need to assess or score content rather than transform it. The EvaluationNumberResult provides a standardized way to return numeric evaluations with confidence levels.
signal_noise@v1.prompt — The LLM prompt. Settings at the top (provider, model), then the actual prompt with variables like {{ title }} and {{ content }}. There’s a powerful templating language under the hood (Liquid.js) that we’ll cover in detail later.
Building Something Real: Web Summarization
The example workflow is a good “Hello World”, but let’s build something real: a workflow that scrapes a webpage and summarizes its content. Tell Claude Code:“Delete the simple workflow and create a new workflow called ‘summarize_url’ that scrapes a webpage in markdown format and summarizes its content. At the end we want a structured output with the title, summary, and full page (markdown) content. For the scraping we’ll need an API client for Jina (https://jina.ai/) reader”Under the hood, Claude Code:
workflow.ts
steps.ts
src/clients/jina.ts
summarize@v1.prompt
scenarios/test_url.json
src/clients/jina.ts, separate from the workflow. It wraps @outputai/http which gives you automatic tracing and retries. When you need to integrate with other APIs (Stripe, Slack, your own backend), create similar clients in src/clients/.
Now run it:
“Run the summarize_url workflow with the test scenario”Under the hood:
scrapeUrl followed by summarizeContent. Each step shows its input and output. You can also inspect the detailed trace in the logs/runs/summarize_url/ folder.
Adding Parallel Steps
Let’s make this more interesting. Tell Claude Code:“Add a generateFaq step that creates 5 FAQs from the content. Run it in parallel with the summarization step.”Here’s what changes:
workflow.ts
steps.ts (add to existing)
generate_faq@v1.prompt
summarizeContent and generateFaq running at the same time—parallel execution with just Promise.all. That’s the power of steps: each is independently retryable, traceable, and can run concurrently when the workflow allows it.
Next Steps
You’ve built your first real Output workflow. Here’s where to go next:CLI Reference
CLI Reference. All commands in depth—run, start, status, terminate, and more.
Workflows
Workflows. Control flow, child workflows, scenarios, and advanced patterns.
Claude Code
Claude Code. How Output’s Claude Code plugin plans, builds, and debugs workflows for you.