In the world of software development and automation, we preach the DRY principle: Don't Repeat Yourself. Yet, how often do we find ourselves writing slightly different variations of the same core tasks? Sending a welcome email, creating a user in a database, generating a monthly report—these are the mundane, repetitive tasks that underpin complex business processes. Each time we build a new automation or workflow, we risk rebuilding these same wheels, introducing inconsistency and wasting valuable development time.
What if we could treat these fundamental business tasks like functions in a well-architected codebase? What if each task was a single, reusable, and dependable building block? This is the core idea behind atomic actions, a powerful concept that transforms chaotic scripts into clear, manageable, and agile business-as-code.
An atomic action is the smallest, indivisible unit of work within a workflow. Think of it as a specialized tool in your toolbox, designed to do one thing and do it perfectly. The "atomic" nature is key: the action either completes successfully or it fails entirely, leaving no messy, partial states behind.
This is the foundation of reliable workflow automation. Instead of a monolithic script that tries to do everything, you compose a sequence of these hardened, independent actions.
Each action is self-contained, with clearly defined inputs and predictable outputs. This simplicity is its superpower.
Managing these actions is where a framework like action.do shines. It provides a structured way to define, manage, and execute these atomic units. Instead of loose scripts, you create a formal definition for each action that is self-documenting and machine-readable.
Consider this example of defining a send-welcome-email action using action.do:
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., using an API like SendGrid or Resend)
console.log(`Sending welcome email to ${name} at ${to}`);
// A real implementation would return a real message ID
return { success: true, messageId: 'xyz-123' };
},
});
Let's break down why this is so powerful:
This is where you truly stop rebuilding the wheel. Once you’ve defined send-welcome-email, you have a canonical, "source-of-truth" action for that task.
Need to send a welcome email in your user sign-up workflow? Call send-welcome-email.
Need to send it when an admin manually creates an account? Call send-welcome-email.
Need an AI agent to onboard a new customer? Give it the send-welcome-email tool.
This library of actions becomes a strategic asset.
It's important to distinguish between an action and a workflow.
An action.do is a single brick—one task. A workflow.do is the blueprint that arranges multiple bricks to build something bigger, like a house.
Your User Onboarding workflow might look like this:
This compositional approach is especially critical for building modern agentic workflows. AI agents are powerful decision-makers, but they need a reliable set of tools to interact with the world. Your library of atomic actions becomes the agent's tool belt, allowing it to reliably perform tasks to achieve its goals.
By focusing on creating a robust library of simple, atomic, and powerful actions, you lay the groundwork for building any complex automation or agentic system you can imagine. You're not just automating tasks; you're building a more agile, resilient, and efficient business.
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.