Hey, I'm Ricardo. I've been building Flow Weaver, a TypeScript workflow compiler. I've been working on it solo for nearly two years as a side project, and I'm finally sharing it.
Every workflow tool I've come across has asked me to leave my code behind. Use their editor, their format, their runtime. I never actually used them. I'd see the demo, think about what I'd lose, and close the tab.
The thing is, I don't think developers hate visual workflows. I think they hate what they have to give up to get them. Your types, your linter, your version control, your ability to just read the code and understand what's happening.
What if your code was the workflow, and the visual was just a view on top?
The code is the workflow
That's Flow Weaver. You write TypeScript functions, add one annotation, and the compiler turns them into workflow nodes. The visual representation is generated from your code, not the other way around.
Step 1: Write your node functions
These are plain TypeScript functions. The only thing special about them is the annotation. The @expression shorthand handles execute/onSuccess/onFailure automatically, so you just write the transform.
/** @flowWeaver nodeType @expression */
function greet(name: string): { greeting: string } {
return { greeting: `Hello, ${name}!` };
}
/** @flowWeaver nodeType @expression */
function shout(text: string): { result: string } {
return { result: text.toUpperCase() + '!!!' };
}
You can call these directly, test them with vitest, import them anywhere. They're just functions. The greet function translates to a node (a box in the graph) type with the following ports (connection points for the node):
| Port | Direction | Type | What it is |
|---|---|---|---|
execute |
in | boolean | Control signal that starts the node |
name |
in | string | The parameter you defined |
onSuccess |
out | boolean | You set this to true when the node succeeds. Expression nodes set it automatically: true if the function returns without throwing |
onFailure |
out | boolean | You set this to true when the node fails. Expression nodes set it automatically: true if the function throws |
greeting |
out | string | The return property you defined |
Step 2: Wire them into a workflow
The workflow annotation connects node instances together. @connect wires ports between nodes. @path is a shortcut so you don't have to write the step connections one by one. @path Start -> g -> s -> Exit is equivalent to connecting Start.onSuccess -> g.execute, g.onSuccess -> s.execute, s.onSuccess -> Exit.onSuccess manually.
/**
* @flowWeaver workflow
* @node g greet
* @node s shout
* @path Start -> g -> s -> Exit
* @connect Start.name -> g.name
* @connect g.greeting -> s.text
* @connect s.result -> Exit.message
*/
export function helloWorld(
execute: boolean,
params: { name: string }
): { onSuccess: boolean; onFailure: boolean; message: string } {
throw new Error('This body is replaced by the compiler. Run: npx flow-weaver compile <file>');
}
Start and Exit are virtual nodes. Start receives the workflow inputs, Exit collects the outputs. Everything lives in one .ts file.
Step 3: See what you built
npx flow-weaver diagram hello.ts --format ascii
You can also generate SVG for documentation, Mermaid for GitHub, or open an interactive HTML version in your browser.
Step 4: Validate
The compiler checks your workflow graph before generating anything. Port types, missing connections, dead-end branches, all caught at compile time.
npx flow-weaver validate hello.ts
✓ 1 file valid in 248ms
And when something is wrong, it tells you exactly what and where:
✗ [line 11] Unknown Input Port: Port 'wrong_port' doesn't exist on node Exit.
⚠ How to fix: Check the port name in the @connect annotation.
These are structured diagnostics with error codes, source locations, and fix suggestions. They're also machine-readable, which means your AI assistant can fix issues automatically.
Step 5: Compile
npx flow-weaver compile hello.ts
Compiling Workflows
✓ hello.ts 278ms
1 file compiled (ESM) in 278ms
The compiler generates the execution logic inside your workflow function, between @flow-weaver-body-start and @flow-weaver-body-end markers. Your node functions are never touched. The compiled output is standalone TypeScript. No imports from Flow Weaver. You could remove the package and the code keeps running.
Step 6: Run
npx flow-weaver run hello.ts --params '{"name":"World"}'
✓ Workflow "helloWorld" completed in 1ms
Result
{
"onSuccess": true,
"onFailure": false,
"message": "HELLO, WORLD!!!!"
}
Or just tell your AI assistant
Everything above, your AI assistant can do through conversation, you don't have to know the syntax by heart, Flow Weaver was designed to work smoothly with AI. You can ask your assistant to use the CLI directly. It gives you direct expertise through the fw context and fw docs command. Or, if you prefer, use the available MCP tools that work with Claude Code, Codex, Copilot, Cursor, Windsurf, and any MCP-compatible editor.
npx flow-weaver mcp-setup --tool claude
Personally I use the CLI directly, so it is always up-to-date with the available version, up to you.
Then you talk to it:
The first thing you'll want to do is ask your AI to load the Flow Weaver context:
"Load the Flow Weaver context core"
The AI calls fw context core and gets the full annotation syntax, node patterns, CLI commands, and a tutorial. From that point on it knows how to build workflows without guessing. There are other presets to choose based on the context you want to give it:
| Preset | What's included | When to use |
|---|---|---|
core |
concepts, annotation syntax, tutorial | Getting started |
authoring |
core + advanced annotations, built-in nodes, scaffolding, node conversion, patterns | Building real workflows |
ops |
CLI reference, compilation, deployment, debugging, error codes | Deploying and debugging |
full |
everything (16 topics) | When you want the AI to know it all |
You can then ask about how it works, and what it can do for you. It will have the context and will be able to pull up documentation and try things out on your behalf.
Then, when you are ready to use it:
"Build a support agent that classifies customer messages and routes to LLM reply or human escalation"
The AI scaffolds the workflow, adds nodes, wires connections, validates, and compiles. When the compiler finds issues, the AI reads the structured diagnostics and fixes them in a loop until the workflow is valid.
If you still don't understand the inner details and want to dig deeper, just visit the source code at Flow Weaver's GitHub.
Routing
The expression nodes above are great for simple transforms. When you need branching, you use the full node signature. The runtime calls your function when the node receives an execute signal. You return which path fires next:
/**
* @flowWeaver nodeType
* @label Validate Input
* @input data - Data to validate
* @output validated - Validated data
* @output errors - Validation errors
*/
function validate(execute: boolean, data: any) {
if (!execute) return { onSuccess: false, onFailure: false, validated: {}, errors: [] };
if (!data || !data.name || data.name.length < 3) {
return { onSuccess: false, onFailure: true, validated: {}, errors: ['Name too short'] };
}
return { onSuccess: true, onFailure: false, validated: data, errors: [] };
}
No routing engine, no config file, just a return value from a function you control.
Agent workflows
The hello world is intentionally simple. For real use cases, Flow Weaver ships with templates for LLM agents, RAG pipelines, conversational memory, human approval gates, and more.
npx flow-weaver create workflow ai-agent my-agent.ts
Each template generates a complete working workflow with mock providers so you can compile and run immediately without any API keys.
I'll do a deeper walkthrough of the agent workflow patterns in a future post. For now, run npx flow-weaver templates to see what's available.
Packs
Flow Weaver is extensible through npm packages called packs. They add deploy targets, node types, CLI commands, and MCP tools.
npx flow-weaver market search # see what's available
npx flow-weaver market install <pack>
Deploy
The compiled output is standalone TypeScript, so it runs anywhere TypeScript runs. For specific platforms, install a deploy pack and export:
Serverless functions
Workflows can be serverless functions on your provider.
npx flow-weaver export agent.ts -t inngest -o deploy/
npx flow-weaver export agent.ts -t vercel -o deploy/
npx flow-weaver export agent.ts -t lambda -o deploy/
npx flow-weaver export agent.ts -t cloudflare -o deploy/
CI/CD pipelines (experimental)
Workflows can also define CI/CD pipelines
npx flow-weaver export pipeline.ts -t gitlab-ci -o deploy/
npx flow-weaver export pipeline.ts -t github-actions -o deploy/
Version control that makes sense
When someone changes a workflow, the PR diff looks like this:
- @path Start -> g -> s -> Exit
+ @path Start -> g -> validate -> s -> Exit
+ @connect g.greeting -> validate.input
+ @connect validate.output -> s.text
That's a real diff you can review. And for deeper analysis, the semantic diff engine compares workflow versions at the graph level:
npx flow-weaver diff hello-old.ts hello.ts
═══════════════════════════════════════════════════════════════
WORKFLOW DIFF - Impact: BREAKING
═══════════════════════════════════════════════════════════════
SUMMARY
───────────────────────────────────────────────────────────
Node Types: +1 added, -0 removed, ~1 modified
Instances: +1 added, -0 removed, ~0 modified
Connections: +4 added, -2 removed
INSTANCES
───────────────────────────────────────────────────────────
+ v
CONNECTIONS
───────────────────────────────────────────────────────────
+ g.greeting → v.text
+ v.validated → s.text
+ g.onSuccess → v.execute
+ v.onSuccess → s.execute
- g.greeting → s.text
- g.onSuccess → s.execute
It classifies the overall impact as critical, breaking, minor, or cosmetic. So you know not just what changed, but whether it matters.
There is a visual editor
I still believe in the visual side, that's what started all of this. I built a Studio where you can see the graph and edit it on a canvas. It's still experimental, but core editing with the canvas, terminal, and diagnostics is live. Edit code and the graph updates. Edit the graph and the code updates.
But you don't need it. The CLI and your text editor work fine on their own. The visual is there when it helps you reason about what you're building, not as something you're forced to use. That's the whole point.
Works inside OpenClaw too
If you use OpenClaw, Flow Weaver runs as a native plugin. Tell your assistant what you want automated, and it builds, validates, and compiles the workflow for you. The agent uses AI for individual steps like classification or summarization, but the routing between steps is compiled and deterministic. No skipped steps, no wrong routing, same result every run.
openclaw plugins install @synergenius/flow-weaver-openclaw
The plugin is on ClawHub and npm.
Where things stand
Flow Weaver is in beta and real world usage will make it stronger. Even if you are skeptical, just give it a try. I'd really appreciate it, and negative feedback is just as welcome as positive.
Breaking changes may still happen during the beta. If you run into issues, the Discord is the best place to reach out. Every message gets read and responded to.
If you've been looking for a way to build workflows without giving up your code, try it. Two commands, first workflow running in under two minutes:
npm install @synergenius/flow-weaver
npx flow-weaver init hello
Be one of the first people to use it.



Top comments (0)