Afina

Download app

AppleWindows
EN

RPA modules — Node.js code inside your flows

Write your own Node.js modules with npm dependencies and call them from RPA flows through the executeModule block. Signed execution, isolated runtime, full reusability — the bridge between no-code automation and real engineering.

RPA modules — Node.js code inside your flows
Node.js • npm • executeModule

When clicks aren't enough, drop into code

Most RPA flows live happily on the visual canvas. The hard 10% — custom API calls, niche libraries, complex data transforms — wants real code. Afina modules are full Node.js packages with npm dependencies, an Ed25519 signature for execution safety, and a clean form-based UI in the parent flow.

Write Node.js code, ship npm-style

Each module is a folder with index.js, package.json and any npm dependencies you need. Edit files in your editor of choice — VS Code, Cursor, JetBrains — Afina watches and re-signs on demand.

Call modules from RPA flows

A new executeModule block accepts the module hash + a form payload. Module function receives the args, talks to the browser through Afina's helpers, returns a value back to the flow. Native interop with the rest of the scripts-and-automation stack.

Full npm ecosystem

Bring your favourite packages — axios, cheerio, ethers, sharp, anything. Afina installs dependencies in the module folder; the runtime allowlist limits node API surface so a misbehaving module can't kill your machine. Ideal companion to the local API.

Ed25519-signed execution

Every module has an Ed25519 signature over an md5 manifest of its files. The executor refuses to run an unsigned or stale module — protecting you from accidental corruption and supply-chain swaps. Combined with the MCP server, AI agents can author modules safely too.

FAQs

A script is a graph of blocks on the visual canvas. A module is a Node.js function — pure code — that you wrap with a form schema and call from inside a script via the executeModule block. Scripts give you orchestration; modules give you imperative logic when blocks aren't enough.

Call create_module via API, MCP or UI — Afina scaffolds a folder with index.js, utils.js, package.json and settings.json. Edit index.js in your editor, add npm dependencies, then call resign_module so the executor accepts the new files. The new module shows up in the executeModule block picker.

To stop the executor from running tampered or swapped code. Each save updates an Ed25519 signature over an md5 manifest of every file in the module folder. If the signature doesn't match the manifest, the executor refuses to start — surfacing a clear modules.error.signature_invalid.

Almost anything. Afina runs npm install in the module folder, so your package.json's dependencies live there in isolation. The runtime's allowedFunctions list controls which Node built-ins are exposed; you can broaden or narrow it per module.

Yes — through Afina's module helpers. The module receives a context that lets it call into the same primitives flows use: navigate, click, eval, set/get account variables, hit the local API. It runs in the same task as the parent flow.

Yes. The MCP server ships create_module/update_module/resign_module tools, and the LLM uses host filesystem tools (Read/Edit/Write) to edit module files under moduleDirAbs. The signing step is what guarantees what the LLM ships is what runs.

Custom Node.js inside your antidetect browser

Write a module, sign it, drop it into a flow — your code, signed and isolated, running on a real browser.

RPA modules — Node.js code inside your flows | Afina