Automa: Building Browser Automation Without Code Using Vue and WebExtensions
Hook
Over 21,000 developers have starred a browser automation tool that requires zero lines of code to scrape websites, fill forms, and generate screenshots—yet it can compile those visual workflows into standalone Chrome extensions.
Context
Browser automation has traditionally been the domain of developers wielding Selenium, Puppeteer, or Playwright. While these tools offer immense power and flexibility, they require programming knowledge, development environment setup, and ongoing maintenance. For non-technical users or developers handling simple repetitive tasks, the overhead is unjustifiable—you shouldn't need a Node.js project with dependencies just to auto-fill a form every morning or scrape product prices weekly.
Automa emerged to bridge this gap by bringing visual programming to browser automation. Built as a WebExtensions-compatible browser extension using Vue.js, it allows users to create automation workflows by connecting functional blocks in a graph editor. Think of it as Scratch or Node-RED for your browser—drag blocks for clicking elements, extracting data, taking screenshots, or executing JavaScript, then wire them together to define execution flow. The project has cultivated a marketplace where users share pre-built workflows, and it even includes Automa CEB (Chrome Extension Builder), which packages workflows as distributable extensions. This transforms browser automation from a developer-only activity into something accessible to analysts, marketers, QA testers, and power users.
Technical Insight
Automa's architecture separates three primary concerns: the workflow editor UI (Vue components), the execution engine that interprets workflows, and the browser automation layer that interfaces with WebExtensions APIs. The workflow editor uses a graph-based UI library to render the node canvas where users create workflows. Each block represents an atomic operation—DOM manipulation, data extraction, control flow, storage operations, or external integrations.
Under the hood, workflows are serialized as JSON structures defining nodes and their connections. When a workflow executes, the engine traverses this graph, evaluating each block in sequence (or in parallel for branches) and maintaining a shared state object that blocks can read from and write to. Here's a simplified example of what a workflow JSON structure looks like:
{
"drawflow": {
"Home": {
"data": {
"1": {
"id": 1,
"name": "trigger",
"data": { "type": "manual" },
"outputs": { "output_1": { "connections": [{ "node": "2", "output": "input_1" }] } }
},
"2": {
"id": 2,
"name": "new-tab",
"data": { "url": "https://example.com", "active": true },
"outputs": { "output_1": { "connections": [{ "node": "3", "output": "input_1" }] } }
},
"3": {
"id": 3,
"name": "element-exists",
"data": { "selector": ".product-price", "timeout": 5000 },
"outputs": {
"output_1": { "connections": [{ "node": "4", "output": "input_1" }] },
"fallback": { "connections": [{ "node": "5", "output": "input_1" }] }
}
}
}
}
}
}
The execution engine injects content scripts into web pages when blocks need to interact with the DOM. Blocks like element-click, forms, or get-text send messages from the background script to the content script, which then performs the actual page interaction and returns results. This message-passing architecture respects browser security boundaries while enabling powerful automation.
One clever design choice is the variable system. Blocks can reference variables using mustache syntax ({{variableName}}), and the engine performs string interpolation before execution. This allows workflows to be dynamic—you can extract data in one block and use it as input for subsequent blocks:
// Pseudo-code representing how a block might process variables
function processBlockData(blockData, workflowState) {
const processed = {};
for (const [key, value] of Object.entries(blockData)) {
if (typeof value === 'string') {
// Replace {{variableName}} with actual values from state
processed[key] = value.replace(/\{\{(.+?)\}\}/g, (match, varName) => {
return workflowState.variables[varName] || match;
});
} else {
processed[key] = value;
}
}
return processed;
}
The Automa Chrome Extension Builder (CEB) takes this further. It packages a workflow along with a minimal runtime into a standalone extension that can be distributed via the Chrome Web Store or loaded unpacked. The generated extension includes only the execution engine and the specific blocks used in the workflow, keeping the bundle size reasonable. This is particularly useful for teams that want to distribute automation to non-technical users without requiring them to install Automa itself.
Automa also implements a scheduling system using Chrome's alarms API, allowing workflows to run at specified intervals or times. Combined with blocks for web scraping and data export (to Google Sheets, CSV, or webhooks), this creates a lightweight alternative to traditional scraping infrastructure for simple monitoring tasks. The extension can run while the browser is open, making it suitable for periodic checks rather than high-frequency data collection.
The project's Vue.js foundation makes the UI highly responsive and modular. Each block type is a Vue component with its own configuration panel, validation logic, and execution handler. This component-based architecture makes it straightforward for contributors to add new block types—several dozen community-contributed blocks exist for niche use cases like interacting with specific APIs or performing custom data transformations.
Gotcha
Automa's browser extension architecture imposes meaningful constraints. Extensions can't access the local filesystem directly (beyond downloads), can't make arbitrary system calls, and have limited persistent storage (browser.storage has quotas). If your automation needs to process local files, interact with desktop applications, or store gigabytes of scraped data, you'll hit walls quickly. The tool is fundamentally constrained by WebExtensions security boundaries, which is by design but limits use cases.
The visual block-based approach, while accessible, becomes unwieldy for complex conditional logic or loops over large datasets. A workflow with dozens of conditional branches and nested loops is technically possible but difficult to visualize and maintain. You'll find yourself wishing for proper function definitions, classes, or modules. For workflows beyond moderate complexity, traditional scripting with Playwright or Puppeteer offers better maintainability—code with version control, testing, and IDE support beats a visual graph for complex logic. Additionally, the AGPL license requires careful consideration. If you're building a commercial product that incorporates Automa workflows, you may need the commercial license to avoid AGPL's copyleft provisions, adding cost and complexity compared to permissively licensed alternatives.
Verdict
Use if: You need browser automation for repetitive tasks (form filling, monitoring, basic scraping) and want an accessible tool for non-developers or quick prototyping. The marketplace and visual editor excel for teams with mixed technical abilities, and the Chrome Extension Builder is excellent for distributing simple automations. It's ideal for personal productivity, small team workflows, or educational contexts where learning visual programming before text-based coding makes sense. Skip if: You're building complex automation with extensive conditional logic (use Puppeteer/Playwright instead), need programmatic control for testing frameworks or CI/CD integration, require local file system access or system-level automation beyond the browser, or are developing commercial products under licenses incompatible with AGPL without budget for commercial licensing. Also skip if you're automating at scale—this is a personal/small-team tool, not production scraping infrastructure.