In the world of software development and workflow automation, a silent, insidious enemy lurks: repetition. You write a script to send a a notification. Then you copy, paste, and tweak it for another workflow. Before you know it, you have a dozen slightly different versions of the same core logic. When it's time to update your notification provider or fix a bug, you're faced with a nightmare of tracking down and changing every single instance. This violates the cardinal rule of efficient coding: Don't Repeat Yourself (DRY).
What if you could build your automations like LEGOs? Define a standard, reliable block once, and then use it everywhere you need it.
This is the core philosophy behind action.do. By encapsulating tasks into atomic actions, you can create a library of reusable, powerful building blocks for all your agentic workflows. Let's explore how this "define once, use everywhere" approach can revolutionize the way you build, maintain, and scale your automations.
Before we can reuse something, we need to define it properly. In the context of .do, the fundamental unit of work is the atomic action.
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 leaving things in a messy, partial state.
Think of it as a contract. It promises to do one thing, do it well, and report back clearly on its success or failure. This predictable, self-contained nature is precisely what makes it the perfect candidate for reuse. It's Simple. Atomic. Powerful.
The power of reusability begins with a clear definition. With action.do, you define your business logic as code, creating a clear, version-controlled source of truth for each task.
Let's look at a classic example: sending a welcome email to a new user. Instead of scripting this within a larger onboarding workflow, we define it as its own atomic action.
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;
// Your robust email sending logic lives here.
// Connect to your email provider, use templates, etc.
console.log(`Sending welcome email to ${name} at ${to}`);
// Return a structured result.
return { success: true, messageId: 'xyz-123' };
},
});
Let's break down why this is so powerful:
We have now defined "sending a welcome email" once. This single piece of code is our universal tool for this job.
Now that our send-welcome-email action is defined, we can call it from anywhere. It's no longer just a piece of a script; it's a capability of our system.
Consider these scenarios:
New User Signup Workflow (onboarding.workflow.do):
Admin Panel "Resend Welcome Email" Button:
Newsletter Subscription (subscribe.workflow.do):
In all three cases, the core logic for sending the email is identical, centralized, and maintained in one place. If you decide to switch from SendGrid to Postmark, you update the handler in the send-welcome-email action once. Instantly, all three workflows—and any others that use this action—are updated without any further intervention.
Embracing this model for your agentic workflows and task automation yields significant advantages:
This approach truly embodies the principle of business-as-code. Your core business tasks are no longer trapped in monolithic applications or scattered scripts; they are modular, version-controlled, and reusable assets. An action.do is the building block; a workflow.do is the blueprint that orchestrates them into a powerful automated process.
Ready to stop repeating yourself and start building scalable, maintainable, and powerful automations? Get started with action.do and turn your complex processes into simple, repeatable tasks.