Workflows Overview
Workflows let you define and orchestrate complex sequences of tasks as typed steps connected by data flows. Each step has clearly defined inputs and outputs validated by Zod schemas.
A workflow manages execution order, dependencies, branching, parallelism, and error handling — enabling you to build robust, reusable processes. Steps can be nested or cloned to compose larger workflows.
You create workflows by:
- Defining steps with
createStep
, specifying input/output schemas and business logic. - Composing steps with
createWorkflow
to define the execution flow. - Running workflows to execute the entire sequence, with built-in support for suspension, resumption, and streaming results.
This structure provides full type safety and runtime validation, ensuring data integrity across the entire workflow.
Getting Started
To use workflows, first import the necessary functions from the workflows module:
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
Create Step
Steps are the building blocks of workflows. Create a step using createStep
:
const cityCoordinatesStep = createStep({
id: "city-step",
description: "Gets coordinates for city",
inputSchema: z.object({
city: z.string()
}),
outputSchema: z.object({
city_name: z.string(),
city_latitude: z.number(),
city_longitude: z.number()
}),
execute: async ({ inputData }) => {
const { city } = inputData;
const geocodingResponse = await fetch(`https://geocoding-api.open-meteo.com/v1/search?name=${city}`);
const geocodingData = await geocodingResponse.json();
const { name, latitude, longitude } = geocodingData.results[0];
return {
city_name: name,
city_latitude: latitude,
city_longitude: longitude
};
}
});
See createStep for more information.
Create Workflow
Create a workflow using createWorkflow
. End a workflow using .commit()
.
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const cityCoordinatesStep = createStep({...});
export const testWorkflow = createWorkflow({
id: "test-workflow",
description: 'Test workflow',
inputSchema: z.object({
city: z.string()
}),
outputSchema: z.object({
outcome: z.string()
})
})
.then(cityCoordinatesStep)
.commit();
Composing Steps
Workflow steps can be composed and executed sequentially using .then()
.
import { createWorkflow, createStep } from "@mastra/core/workflows";
import { z } from "zod";
const cityCoordinatesStep = createStep({...});
const cityWeatherStep = createStep({...});
export const testWorkflow = createWorkflow({
id: "test-workflow",
description: 'Test workflow',
inputSchema: z.object({
city: z.string()
}),
outputSchema: z.object({
outcome: z.string()
})
})
.then(cityCoordinatesStep)
.then(cityWeatherStep)
.commit();
Steps can be composed using a number of different methods. See Control Flow for more information.
Register Workflow
Register a workflow using workflows
in the main Mastra instance:
import { Mastra } from "@mastra/core/mastra";
import { PinoLogger } from "@mastra/loggers";
import { LibSQLStore } from "@mastra/libsql";
import { testWorkflow } from "./workflows/test-workflow";
export const mastra = new Mastra({
workflows: { testWorkflow },
storage: new LibSQLStore({
// stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db
url: ":memory:"
}),
logger: new PinoLogger({
name: "Mastra",
level: "info"
})
});
Run Workflow
There are two ways to run and test workflows.
Mastra Playground
With the Mastra Dev Server running you can run the workflow from the Mastra Playground by visiting http://localhost:4111/workflows  in your browser.
Command line
Create a run instance of any Mastra workflow using createRun
and start
:
import { mastra } from "./mastra";
const run = mastra.getWorkflow("testWorkflow").createRun();
const result = await run.start({
inputData: {
city: "London"
}
});
console.log(JSON.stringify(result, null, 2));
To trigger this workflow, run the following:
npx tsx src/test-workflow.ts
Stream Workflow
Similar to the run method shown above, workflows can also be streamed:
import { mastra } from "./mastra";
const run = mastra.getWorkflow("testWorkflow").createRun();
const result = await run.stream({
inputData: {
city: "London"
}
});
for await (const chunk of result.stream) {
console.log(chunk);
}
Watch Workflow
A workflow can also be watched, allowing you to inspect each event that is emitted.
import { mastra } from "./mastra";
const run = mastra.getWorkflow("testWorkflow").createRun();
run.watch((event) => {
console.log(event);
});
const result = await run.start({
inputData: {
city: "London"
}
});
See watch for more information.
More Resources
- The Workflow Guide in the Guides section is a tutorial that covers the main concepts.
- Parallel Steps workflow example
- Conditional Branching workflow example
- Inngest workflow example
- Suspend and Resume workflow example