Beta Latest Beta release on GitHub Releases · 4.1.15-beta

The Node-RED runtime, reforged in Rust.

EdgeLinkd runs your existing flows.json as a single native binary — with the full Node-RED editor built in, runtime nodes implemented in Rust, and roughly a tenth of Node-RED's memory footprint.

  • Apache-2.0
  • Rust 1.88+
  • Linux · Windows
  • x86_64 · AArch64 · ARMv7
The EdgeLinkd web editor showing a Node-RED flow with inject nodes feeding a switch and three debug outputs.
≈10%
of Node-RED's memory footprint
1
self-contained binary, editor included
6
supported target triples
v4.1.15
Node-RED release used as the behavioural reference
01Why EdgeLinkd

Keep the flows. Lose the weight.

Node-RED made flow-based programming mainstream. EdgeLinkd keeps its editor, its flow format and its message semantics — and replaces the Node.js runtime underneath with native Rust.

Node-REDEdgeLinkd
ExecutionNode.js and V8 — JIT-compiled, garbage-collectedNative Rust on Tokio — no JIT, no garbage collector
SchedulingOne JavaScript event loop for the standard runtimeTokio's multi-threaded scheduler runs independent node tasks across CPU cores
MemoryBaseline≈ 1/10 of Node-RED
JavaScriptEvery node is JavaScriptOnly inside function nodes, in an embedded QuickJS sandbox
Flow formatflows.jsonThe same flows.json — no conversion step
EditorNode-RED editorThe same editor, served by the binary itself
DeploymentInstall Node.js, then npm packagesCopy one binary; add --headless for production
Extendingnpm packagesRust crates, statically linked through #[flow_node]

The honest trade-off: third-party npm nodes do not run on EdgeLinkd, and features that do not fit an embedded budget are rejected at deploy time instead of being silently ignored.

02Capabilities

A complete flow runtime in one native process.

Design, deploy and run in the same binary. Everything except the code you write in function nodes is compiled Rust.

Drop-in flows.json

Author in the Node-RED editor and deploy the same JSON. Flows, subflows, link nodes, environment variables and JSONata expressions follow Node-RED semantics.

flowssubflowsenvJSONata
[
  { "id": "f1", "type": "tab", "label": "Sensors" },
  { "id": "n1", "type": "mqtt in", "z": "f1",
    "topic": "sensors/+", "wires": [["n2"]] },
  { "id": "n2", "type": "json", "z": "f1",
    "wires": [["n3"]] }
]

Editor included

The complete Node-RED editor ships inside the binary: palette, deploy, debug sidebar, import and export. Switch it off with --headless.

JavaScript only where you write it

Every node is native Rust. function nodes run in an embedded QuickJS sandbox with node, context, flow, global, env and RED.util.

Multi-threaded async scheduling

The standard Node-RED runtime is constrained by one JavaScript event loop. EdgeLinkd schedules one task per node across Tokio worker threads, while each node still processes its own messages in order with back-pressure along every wire.

Verified against Node-RED's own specs

Upstream mocha tests are ported to pytest and run against the Rust engine through a PyO3 module, with test titles matching upstream character for character.

Sized for embedded targets

Release builds optimise for size with LTO and stripped symbols, and node families sit behind Cargo features — so a minimal image compiles only what it uses.

x86_64aarch64armv7
[profile.release]
opt-level = "z"     # optimise for size
lto = true
codegen-units = 1
strip = true

[features]
default = ["core", "js", "jsonata", "nodes_network",
           "nodes_storage", "nodes_parser"]
03Architecture

One process, three crates, a task per node.

The edgelinkd binary hosts the runtime and the editor side by side. On deploy, flows become a graph of Tokio tasks joined by bounded channels; all I/O happens at the edges of that graph.

Design time
Node-RED editorbrowser

Served by edgelinkd; deploys straight to the engine

flows.jsonfile

Unmodified Node-RED flow format

edgelinkd.tomlconfig

Merged with CLI flags at start-up

Admin API · WebSocket
edgelinkdsingle native process
Application hostsrc/
runlist--headlessconfiglog4rs
edgelink-webcrates/web
Admin HTTP APIEditor assetsDebug commsaxum
edgelink-corecrates/core
Engine
load · deploy · redeploy · stop
Flows
flows · subflows · groups · links
Message model
Msg · Variant · MsgHandle
Context
memory & local-file stores
JSONata
pure-Rust jsonata-core
JS bridge
QuickJS · function node only
inject function switch mqtt out
1 node = 1 Tokio task · bounded mpsc inbox · in-order delivery
Node libraryruntime/nodes · node-plugins/
commonfunctionnetworksequenceparserstorage

Self-registered with #[flow_node] and inventory — there is no central node list.

TokioLinuxWindowsx86_64AArch64ARMv7
Edge I/O
MQTTrumqttc

Subscribe and publish to brokers

HTTPaxum · reqwest

Endpoints in, requests out

WebSockettungstenite

Listeners and clients

TCP / UDPtokio

Raw sockets, unicast & multicast

Filesfs

file · file in · watch

Processesexec

Run and signal commands

Network · Files · Processes
Spec harnesstests/ · crates/pymod

Node-RED's mocha specs, ported to pytest, drive the real engine through the edgelink_pymod PyO3 extension on every CI run.

pytestPyO3Node-RED v4.0.9 reference
Process view of edgelinkd. Solid arrows carry flows and messages at run time; the dashed harness drives the same engine in CI.
01

Deploy builds a task graph

The engine parses flows.json, resolves every node type against the registry and spawns one Tokio task per node, wired through per-port senders.

02

Bounded wires, real back-pressure

Every inbox is a bounded channel. A slow consumer slows its producers instead of growing an unbounded queue — memory stays predictable on small devices.

03

Ordered, shared messages

Messages travel as shared Arc<RwLock<Msg>> handles and each node processes them one at a time, preserving Node-RED's ordering guarantees.

04

Native first, scripted last

JSONata is evaluated in pure Rust; only function nodes enter QuickJS. Everything else on the hot path is compiled code.

04Compatibility

Compatible where supported. Explicit everywhere else.

EdgeLinkd is a Node-RED compatible runtime, not a clone. Whatever it ships must behave exactly like Node-RED v4.0.9; whatever does not fit an embedded budget is declined — loudly.

  • Same behaviour, or no behaviour

    For every supported node and option, message semantics, error and status behaviour and the editor contract match upstream.

  • Never fake support

    No silent no-ops, no plausible stubs. Unsupported configuration fails at deploy time or raises NotSupported.

  • Audited, not assumed

    A generated report diffs the ported tests against upstream describe() and it() titles, node by node.

Runtime features

  • FlowsSpec-verified
  • SubflowsSpec-verified
  • Environment variablesSpec-verified
  • RED.util in the function sandboxSpec-verified
  • JSONata via jsonata-coreIn progress
  • Context: memory & local file systemIn progress
  • GroupsIn progress
  • Plug-in subsystem (static)In progress

Core node status

Spec-verifiedAvailableIn progress
Common12/12
  • inject
  • debug
  • complete
  • catch
  • status
  • link in
  • link call
  • link out
  • comment
  • junction
  • unknown
  • global-config
Function9/9
  • function
  • switch
  • change
  • range
  • template
  • filter (rbe)
  • delay
  • trigger
  • exec
Network17/17
  • mqtt in
  • mqtt out
  • mqtt broker
  • http in
  • http out
  • http request
  • websocket listener
  • websocket client
  • websocket in
  • websocket out
  • tcp in
  • tcp out
  • tcp get
  • udp in
  • udp out
  • tls
  • http proxy
Sequence4/4
  • split
  • join
  • sort
  • batch
Parser5/5
  • json
  • xml
  • csv
  • html
  • yaml
Storage3/3
  • file
  • file in
  • watch
Available nodes are implemented and usable; Spec-verified nodes also match the covered Node-RED tests. Full spec coverage report
05Quick start

From clone to running flows in three commands.

EdgeLinkd builds with stable Rust. Prebuilt beta packages are also published on GitHub Releases.

  1. 01

    Clone with submodules

    The pinned Node-RED checkout provides the editor assets and the behavioural reference.

    git clone --recursive https://github.com/oldrev/edgelinkd.gitcd edgelinkd
  2. 02

    Build a release binary

    Requires Rust 1.88 or later. On Windows, keep Git's patch.exe on PATH and install the MSVC toolchain.

    cargo build --release
  3. 03

    Run with the editor

    Starts the engine and serves the Node-RED editor at http://127.0.0.1:1888.

    ./target/release/edgelinkd run
  4. 04

    Go headless in production

    Same flows, no web server. To reach the editor from another machine instead, pass --bind 0.0.0.0:1888.

    ./target/release/edgelinkd run ./flows.json --headless
06Use cases

Where EdgeLinkd fits.

Anywhere Node-RED flows make sense, but a Node.js runtime does not.

IoT edge gateways

Aggregate and filter sensor traffic — MQTT, HTTP, TCP and UDP — right next to the devices, with minimal RAM.

Industrial automation

Run control and data-acquisition flows on embedded controllers, with the web editor at hand for maintenance.

Home automation

Keep smart-home logic on a Raspberry Pi-class board instead of a full Node.js stack.

Cloud-to-edge migration

Move existing Node-RED flows from servers onto devices without rewriting them.

Lean containers

Ship one binary in a small image, with or without the web UI.

Prototype to production

Iterate in the built-in editor during development, then deploy the same flows headless in the field.

Bring your flows to the edge.

EdgeLinkd is open source under Apache-2.0 and developed in the open. Try it, report what breaks, or port the next node.