Quickstart

Run your first workflow — install, configure, and run a multi-step pipeline in one await.

Install

npm install @alineo-labs/sandbox @alineo-labs/workflow

Configure

import { Sandbox } from "@alineo-labs/sandbox";
import { SQLiteAdapter } from "@alineo-labs/sqlite";
import { workflow } from "@alineo-labs/workflow";

const client = new Sandbox({
  baseUrl: "http://localhost:8080",
  adapter: new SQLiteAdapter("./ledger.db"),
});

No connect() call needed — the adapter initializes lazily on first use.

Run a workflow

await workflow(client)
  .sandbox({ image: "node:22", resources: { cpu: "500m", memory: "512Mi" } }, (sb) => {
    sb.exec("node --version");
    sb.exec("npm --version");
  })
  .pipe(process.stdout);

No close() call needed either — Sandbox has no such method; the adapter closes itself automatically when the process exits.

The callback receives a SandboxBuilder. All calls inside it queue operations synchronously — nothing runs until .pipe() or .result() is awaited. The sandbox is created, all ops are flushed in order, then the sandbox is closed automatically.

Capture output

Use .result() instead of .pipe() to get the combined stdout and any captured file values:

const { stdout, vars } = await workflow(client)
  .sandbox({ image: "node:22", resources: { cpu: "500m", memory: "512Mi" } }, (sb) => {
    sb.exec("node --version > /tmp/ver.txt");
    sb.readFile("/tmp/ver.txt", "nodeVersion");
  })
  .result();

console.log(vars.nodeVersion); // "v22.x.x\n"

Next steps