GET STARTED / QUICK START

Your first workflow.

From an input to a result, in two nodes. This example doubles a number and shows the three building blocks in action.

01 Install the package

terminalShell
npm install @newvexa/workify

Use the scoped name @newvexa/workify. The unscoped npm package workify belongs to a different publisher and is not this library.

ESM imports are shown below. CommonJS applications can use:

app.cjsJavaScript
const { Engine, Workflow, ifNode, switchNode } = require("@newvexa/workify");

02 Build a reusable graph

Save this as workflow.ts. Every node has a unique ID, a name, a type, and an asynchronous execute handler. The first node receives input.initial; the next reads its ordered incoming deliveries.

workflow.tsTypeScript
import { Engine, Workflow } from "@newvexa/workify";

export function createWorkflowEngine() {
  const workflow = new Workflow({ id: "demo", name: "Double a number" });

  workflow.addNode({
    id: "start",
    name: "Receive input",
    type: "trigger",
    async execute(input) {
      return { outputs: { main: input.initial } };
    },
  });

  workflow.addNode({
    id: "double",
    name: "Double the value",
    type: "action",
    async execute(input, context) {
      context.signal.throwIfAborted();
      const value = input.incoming[0]?.value;
      if (typeof value !== "number") throw new Error("Expected a number");
      return { outputs: { main: value * 2 } };
    },
  });

  workflow.addLink({
    id: "start-double",
    name: "Input to calculation",
    source: { nodeId: "start", port: "main" },
    target: { nodeId: "double", port: "main" },
  });

  return new Engine(workflow, { concurrency: 4, historyLimit: 500 });
}

A link explicitly connects the source’s main output port to the target’s main input port. The factory returns an engine without starting a run on import.

03 Run your workflow

run.tsTypeScript
import { createWorkflowEngine } from "./workflow.js";

const engine = createWorkflowEngine();
const result = await engine.run(21);

console.log(result.status);                       // "succeeded"
console.log(result.results.double?.outputs.main); // 42

For a standalone ESM project, install TypeScript and add "type": "module" to the application’s package.json. Then compile and run:

terminalShell
npx tsc workflow.ts run.ts --target ES2022 --module NodeNext --moduleResolution NodeNext --outDir build
node build/run.js

Prefer a zero-build demo?

An installed Node.js project can run the included JavaScript example directly:

terminalShell
node ./node_modules/@newvexa/workify/examples/run-quick-start.mjs
# Expected output: succeeded, then 42

The factory and entry point are included example files, not main package exports.

Observe the execution

observe.tsTypeScript
const stopState = engine.subscribe(() => {
  console.log(engine.getSnapshot().status);
});

const stopEvents = engine.onEvent((event) => {
  if (event.type === "node.changed") {
    console.log(event.nodeId, event.state.status);
  }
});

try {
  await engine.run(21);
  const previous = engine.getHistory().at(-2);
  console.log(previous?.snapshot.status);
} finally {
  stopState();
  stopEvents();
}

Both subscription methods return a cleanup function. Snapshots contain status and error metadata; read business output from result.results, not from snapshots.

What comes next?

Create one engine per independent view or request. Construction captures and validates the graph; subsequent builder changes do not alter that engine. Handle invalid initial inputs and overlapping runs with try/catch, and inspect result.status for execution failures.

Documentation for @newvexa/workify 0.1.3Read the full source guide