In the world of automation and agentic systems, clarity is power. Building robust, scalable processes requires understanding the fundamental components you're working with. At .do, we've built our platform around two core concepts: Actions and Workflows. While they work together seamlessly, they serve distinct purposes.
Understanding the difference is key to mastering agentic workflow automation. When should you encapsulate logic in an action.do, and when should you orchestrate it within a workflow.do?
This guide will break down the distinction, helping you architect your automations with confidence.
Think of an action.do as the single, indivisible unit of work in your system. It's the "verb" of your automation. Each action is designed to perform one specific task reliably and repeatably.
The key here is the word atomic. An atomic action is designed to either complete successfully or fail entirely, preventing inconsistent or partial states. It’s a self-contained, powerful building block.
An action.do is like a LEGO brick: It has a specific shape and purpose. You can use it by itself, but its true power is realized when you combine it with other bricks to build something bigger.
Let’s look at a practical example of an action that sends a welcome email.
This sendWelcomeEmail action does one thing and does it well. It has clearly defined inputs (to, name) and a handler that contains the specific logic to execute the task. It's simple, testable, and, most importantly, reusable.
If actions are the bricks, a workflow.do is the architectural blueprint. A workflow is a sequence of one or more actions, orchestrated to achieve a larger business process. It defines the flow of control, manages data as it passes between actions, and handles the logic that connects the individual tasks.
A workflow.do is like a recipe: It lists the ingredients (actions) and provides step-by-step instructions on how to combine them to create a finished dish.
Let's imagine a "New User Onboarding" workflow. This process is much more than just sending a single email. It might look something like this:
This entire sequence is the workflow.do. It doesn't perform the tasks itself; it directs the action.do building blocks, telling them when to run and what data to use.
The real magic of business-as-code happens when you combine actions and workflows. You don't choose one over the other; you use them in concert.
By defining your business's core capabilities as modular action.do instances, you create a library of powerful, pre-built components. Then, you can use workflow.do to assemble these components in endless combinations to automate virtually any process, no matter how complex. This approach makes your automations easier to build, manage, and scale.
Ready to simplify complexity and build your first agentic workflow? Start by defining your first atomic action. You’ll be amazed at how simple powerful automation can be.
Q: What is an 'atomic action' in the context of .do?
A: An atomic action is the smallest, indivisible unit of work in a workflow. It represents a single, well-defined task, like 'send an email' or 'create a user record', ensuring that it either completes successfully or fails entirely, without partial states.
Q: How is an action.do different from a full workflow.do?
A: An action.do represents a single task. A workflow.do is a collection of one or more actions orchestrated to achieve a larger business process. Actions are the building blocks; workflows are the blueprints that connect them.
Q: Can I reuse actions across different workflows?
A: Absolutely. Actions are designed to be modular and reusable. You can define an action once, like 'generate-report', and call it from any number of different workflows, promoting DRY (Don't Repeat Yourself) principles in your automations.
Q: What kind of logic can I put inside an action's handler?
A: The handler can contain any Node.js/TypeScript logic. This includes making API calls to third-party services, performing data transformations, interacting with databases, or executing any custom business logic required to complete the task.
import { action } from '@do-sdk/core';
export const sendWelcomeEmail = action({
name: 'send-welcome-email',
description: 'Sends a welcome email to a new user.',
inputs: {
to: { type: 'string', required: true },
name: { type: 'string', required: true }
},
handler: async ({ inputs, context }) => {
const { to, name } = inputs;
// Email sending logic (e.g., via an external API) goes here
console.log(`Sending welcome email to ${name} at ${to}`);
return { success: true, messageId: 'xyz-123' };
},
});