In the world of software development and workflow automation, we often talk about building complex systems. But the secret to managing complexity isn't about building bigger, more monolithic tools. It's about breaking things down. The most robust, scalable, and understandable systems are built from the smallest, most reliable parts.
Enter the atomic action. This concept is the cornerstone of modern automation and the fundamental building block of the .do platform. It's the simple, powerful idea behind action.do.
So, what is an atomic action?
An atomic action is the smallest, indivisible unit of work in a workflow. It performs a single, specific task, like 'send an email' or 'update a database record', ensuring that operations are reliable, testable, and easy to debug.
Think of it like a LEGO brick. A single brick is simple, predictable, and serves one purpose. By itself, it's just a block. But when you combine it with other bricks, you can build anything you can imagine.
In an agentic workflow, an action.do is that single, executable step. It's focused, it does one thing, and it does it well. This "single responsibility principle" is what makes it so powerful.
The best way to understand an action.do is to see one. Let's define a simple action to send a welcome email to a new user. This is a classic task in any onboarding workflow.
import { action } from '@do-sdk/core';
// Define an action to send a welcome email
const sendWelcomeEmail = action.create({
id: 'send-welcome-email',
description: 'Sends a welcome email to a new user.',
execute: async ({ email, name }) => {
// Your email sending logic via an external API
console.log(`Sending welcome email to ${name} at ${email}...`);
return { success: true, messageId: 'xyz-123' };
}
});
// Execute the action
const result = await sendWelcomeEmail.execute({
email: 'jane.doe@example.com',
name: 'Jane Doe'
});
Let's break this down:
Once defined, this sendWelcomeEmail action is a reusable piece of business logic. It's a self-contained unit of task execution.
It's crucial to understand the relationship between an action.do and a workflow.do.
If sendWelcomeEmail is an action, a full "New User Onboarding" workflow.do might look like this:
You build powerful workflows by composing a series of simple, atomic actions. This makes the entire process transparent, easier to debug (if step 3 fails, you know exactly where the problem is), and more flexible to change.
The design of action.do is intentional, guided by principles that ensure robust workflow automation.
Actions are stateless. They don't remember anything about past executions. They receive input, perform their task, and produce output. That's it. This makes them incredibly predictable and reusable. State management (like knowing which user you're currently processing) is handled by the orchestrating workflow, not the individual action.
The true power of the .do platform is that it's designed for you to create your own custom actions. You are not limited to a pre-built library. You can encapsulate your unique business logic, integrate with any third-party API, and make your core operations available as code. This is the essence of "business as code."
Because each action is a self-contained unit, you can mix and match them to create new workflows without rewriting any code. Have an action that generates-invoice-pdf? You can use it in your "Monthly Subscriptions" workflow and your "One-Time Purchase" workflow.
By defining your business capabilities as a series of atomic actions, you're not just automating a process; you're creating a library of executable services. These simple, powerful blocks can be chained together to deliver valuable Services-as-Software, executed by human agents, scheduled jobs, or autonomous AI agents.
The next time you face a complex automation challenge, don't think big. Think small. Think atomic. What is the smallest, most fundamental step you can define? Start there, and you'll have found your first action.do.