# NoFlo: flow-based programming for JavaScript, from npm install to a running graph

> NoFlo is a JavaScript library for wiring black-box components into dataflow graphs on Node.js and in the browser. It is a coordination layer, not a framework, and the ecosystem around it carries most of the tooling.

**noflo/noflo** — Flow-based programming for JavaScript

- Repository: https://github.com/noflo/noflo
- Website: https://noflojs.org/
- Stars: 3,552 · Forks: 264
- Language: JavaScript
- License: not declared
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/noflo-noflo

## The problem NoFlo solves: programs as networks, not call stacks

Most JavaScript code is organized by call order. A function calls another function, and the shape of the program lives in the source of whoever calls whom. NoFlo organizes code by connection instead. The README quotes the flow-based programming definition: applications are networks of black box processes that exchange data across predefined connections by message passing, and those connections are specified externally to the processes. The practical consequence is that a component does not know what feeds it or what consumes its output. It reads from its input ports and writes to its output ports, and the graph decides the rest.

The intended audience is developers who already think in pipelines. The README draws the parallel to the Unix philosophy of small programs joined by text streams, and to Alan Kay's description of objects as cells that only communicate by messages. If you have written a shell pipeline and wished the stages were typed and inspectable, that is the target use case. The README also names concrete deployments it knows of: web servers, build tools, event coordination inside GUI applications, robot control, and Internet-connected art installations. Those are all cases where the wiring changes more often than the units of work do.

## How a NoFlo graph actually moves data

The library depends on fbp for the language and on fbp-graph for the graph model, so a NoFlo program is a graph object plus a set of component implementations. Components are addressed by name through a component loader, which is what lets the same graph run under Node.js or in a browser bundle. The package's exports field splits the entry point: an import resolves to src/lib/NoFlo.js and a require resolves to lib/NoFlo.js, with types at lib/NoFlo.d.ts. That split matters because the build pipeline is not symmetric.

The build scripts reveal the awkward part. prebuild:node rewrites import.meta.dirname to __dirname and rewrites a dynamic import into Promise.resolve().then(() => require(cPath)) in src/lib/loader/NodeJs.js, then postbuild:node rewrites them back. In other words the Node loader source is edited in place to produce a CommonJS-compatible build and restored afterwards. If you build from a dirty working tree or interrupt the build, you can leave the loader in the rewritten state. That is a real failure mode, and it is visible in package.json rather than documented as a caveat.

Data flow itself is message passing over named ports. A component declares inputs and outputs, the graph connects an output port of one node to an input port of another, and the runtime delivers packets along those edges. Nothing in the graph model requires the two ends to share memory or call each other directly, which is why the same graph can be serialized, inspected, and reconnected.

## Installing NoFlo and running a first graph

The README gives the npm path first. Install the library as a dependency of your project:

```bash
$ npm install noflo --save
```

The package declares engines.node as ">= 6", so any reasonably recent Node.js satisfies it. After install you have the library and two binaries, noflo and noflo-cache-preheat, both listed in the bin field.

Installing from Git is a separate procedure. The README says to check out the repository, install dependencies, then build and link:

```bash
$ npm run build
$ npm link
```

npm run build runs the tsc build:node script, and because of the prebuild and postbuild replacements described above, it expects to run against the checked-out source. If you are building from Git, run it on a clean tree.

For the browser, the README does not give a plain command. It says you can make a browser build with webpack, that webpack builds need the component loader configured statically with noflo-component-loader, and that projects using Grunt can use the grunt-noflo-browser plugin instead. Those are separate repositories, so the configuration itself lives there, not in this README.

The repository ships runnable examples under examples/: helloworld, http, linecount, and spreadsheet. The README does not walk through any of them, so the honest first step after install is to open examples/helloworld and read the graph and component files together, then run the development suite to confirm the install:

```bash
$ npm run build
$ npm test
```

The README states that NoFlo has an extensive test suite and gives exactly those two commands for running it.

## Where NoFlo is the wrong tool

The README is unusually direct about scope: NoFlo is not a web framework or a UI toolkit. It coordinates data flow inside a JavaScript application, and it can be used for whatever JavaScript can be used for, which is a very wide and not very useful boundary. If you want routing, templating, a component tree, or a reactive store, NoFlo does not provide them and the ecosystem does not pretend it does.

The second limitation is tooling gravity. NoFlo itself is described as just a library for implementing flow-based programs. The visual IDE, the Node.js CLI, the browser template, the assembly design approach, the spec-based testing tool, and the retroactive debugger are all separate projects. That is a deliberate architecture, but it means the library alone gives you a graph model and a runtime, and you assemble the rest. A team expecting a single install to deliver a development environment will be disappointed by the gap between the library and app.noflojs.org.

The third limitation is release cadence. The most recent release recorded for this repository is 1.3.0 from 2020-11-23, while package.json on master declares version 1.5.2. The last push to the repository was on 2026-07-05. So the published release line and the source tree have diverged, and anyone pinning to the npm release is not running what master contains. The README does not document rollback or a supported-version policy, so treat the release list as informational rather than as a compatibility guarantee.

## NoFlo against a node-and-edge editor such as Rete.js

Rete.js appears in the search data around this project, and the comparison is instructive because the two sit at different layers. Rete.js is a framework for building visual node editors: it gives you the editor, the socket rendering, and the plugin structure, and you supply the processing semantics. NoFlo is the opposite arrangement. It gives you the runtime semantics, components, ports, connections, and packet delivery, and the visual environment is a separate application built on the fbp protocol.

That difference decides the project. If the deliverable is a diagramming tool where users arrange nodes and you control what execution means, a node-editor framework fits better, because NoFlo will not draw anything for you. If the deliverable is a running dataflow system and the graph is a configuration artifact you may also want to edit visually, NoFlo's split makes sense: the runtime is a library you can embed, and the editor is optional. The cost of that split is the integration work of connecting the two, which is exactly what the fbp protocol and the NoFlo Development Environment exist to do.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and its last push was on 2026-07-05. The published release list, however, stops at 1.3.0 in 2020-11-23, so the gap between releases and commits is roughly six years. That combination is worth reading carefully: the code is being touched, but the npm release line has not moved in a long time. Anyone who needs a versioned artifact with a changelog entry should check CHANGELOG.md and confirm which version corresponds to what they intend to run.

Upgrade cost is dominated by the dependencies rather than by NoFlo's own API surface. The runtime depends on fbp, fbp-graph, fbp-manifest, debug, and get-function-params. A major bump in the graph model or the FBP language parser propagates into NoFlo, and because the build rewrites source files in place, a TypeScript or Babel change can also break the prebuild and postbuild replacements. The devDependencies pin TypeScript 4.0.2, which is old enough that a modern toolchain may need attention before the build scripts run as written.

The licence is MIT, stated in package.json and in the README. MIT is permissive: it allows use, modification, and redistribution with the licence and copyright notice retained, and it offers no patent grant and no warranty. That is the whole of what the repository says on the subject; questions about your specific distribution obligations belong with your own counsel, not with this article.

## Conclusion

Adopt NoFlo when the shape of your program is a graph of independent processes that you want to rewire without editing the processes themselves, and you are willing to write components as JavaScript or anything that transpiles to it. Do not adopt it as a web framework, a UI toolkit, or a general state manager; the README says plainly that it is not those things. Before committing, verify two facts yourself: that the npm package version you install matches the 1.5.2 in package.json on master, and that the browser build path through noflo-component-loader or grunt-noflo-browser still works for your bundler, because the README points at those separate projects rather than documenting the configuration inline.

## FAQ

### Does NoFlo run in the browser as well as on Node.js?

Yes. The README describes NoFlo as running on both Node.js and the browser, and says you can make a browser build with webpack, configuring the component loader statically with noflo-component-loader. For Grunt projects, the grunt-noflo-browser plugin is offered as the easier route.

### Is NoFlo a web framework or a UI toolkit?

No. The README states directly that NoFlo is not a web framework or a UI toolkit, and describes it instead as a way to coordinate and reorganize data flow in any JavaScript application.

### What components ship with the NoFlo repository?

The repository has an examples directory containing helloworld, http, linecount, and spreadsheet. The README does not walk through these examples, and it points readers to the documentation site for usage.

### How do I run the NoFlo test suite?

The README gives two commands: npm run build followed by npm test. It describes the suite as extensive.

### What licence is NoFlo released under?

MIT. The licence is declared in package.json as "license": "MIT" and the README states that NoFlo is available from GitHub under the MIT license.

## Sources

- [License: MIT](https://github.com/noflo/noflo/blob/master/LICENSE)
- [noflo/noflo on GitHub](https://github.com/noflo/noflo)
- [Project website](https://noflojs.org/)
- [README](https://github.com/noflo/noflo/blob/master/README.md)
- [Releases](https://github.com/noflo/noflo/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/noflo-noflo
