Node‑RED Subflows: Build Reusable Flow Modules for Cleaner, Maintainable Projects
Node‑RED subflows let you bundle nodes into reusable components, exposing only the ports you need. This guide walks through creating a simple "add‑ten" subflow, shows JSON export, and covers limits and common pitfalls.
06 Feb 2026, 11:17 UTC

Why Subflows Matter
When a flow grows beyond a handful of nodes, readability and maintainability suffer. Subflows let you bundle a group of nodes into a single, self‑contained component. Each instance of the subflow behaves like a single node, exposing only the ports you choose. This keeps the editor tidy, reduces duplication, and makes changes propagate automatically.
Quick Takeaway
To create a reusable module: drag the nodes you want, select them, choose Export → Selection to subflow, give it a name, expose the desired ports, and then drop copies of that subflow anywhere in your workspace.
Step‑by‑Step Example
- Build the Core Nodes
- Create an
Injectnode (payload:5, repeat:once). - Add a
Functionnode with the code:msg.payload = msg.payload + 10; return msg; - Place a
Debugnode to view the output.
- Create an
- Encapsulate into a Subflow
- Select the
FunctionandDebugnodes. - From the editor menu, pick
Export → Selection to subflow. - In the dialog, name the subflow
add-tenand expose a single input port (default) and a single output port. - Click Create. A new node labeled
add‑tenappears in the palette.
- Select the
- Instantiate the Subflow
- Drag the
add‑tennode onto the workspace. - Wire the
Injectnode to the subflow’s input and the subflow’s output to theDebugnode. - Deploy and observe the debug panel:
15should appear.
- Drag the
- Multiple Instances
- Copy the
add‑tennode and paste it elsewhere. - Change the
Injectpayload to20for the second instance. - Deploy again; the first instance still outputs
15, the second outputs30.
- Copy the
Exported Flow JSON
Below is a minimal JSON representation of the flow and its subflow definition. Import this into the editor to see the exact structure.
{
"id":"flow-1",
"label":"Add Ten Demo",
"nodes":[
{"id":"in","type":"inject","name":"Start","payload":"5","payloadType":"num","wires":[["subflow-1"]]},
{"id":"subflow-1","type":"subflow:add-ten","name":"Add Ten","wires":[["debug"]]},
{"id":"debug","type":"debug","name":"Result","wires":[]}
],
"subflows":[
{"id":"subflow:add-ten","name":"add-ten","type":"subflow","nodes":[
{"id":"func","type":"function","name":"Add 10","func":"msg.payload = msg.payload + 10;\nreturn msg;","wires":[["out"]]},
{"id":"out","type":"subflowout","name":"","wires":[]}
],"inputs":1,"outputs":1}
]
}
Limitations to Keep in Mind
- Global Context: Subflows cannot directly read or write
globalcontext unless you pass it explicitly via an input port. This is by design to preserve encapsulation. - Hot‑Swapping: Changing a node inside a subflow (e.g., upgrading the function code) requires a full
Deploy. Running instances will keep using the old version until redeployed. - Size Impact: Each instance adds its own node object to the flow JSON. Hundreds of instances can bloat the file and slow the editor startup.
Common Mistakes & How to Avoid Them
- Missing Ports: If you forget to expose an input or output, wires will appear disconnected. Always confirm that the subflow’s ports match the nodes you intend to connect.
- Editing the Wrong Copy: In the editor, right‑click a subflow instance and choose
Edit Subflow Templateto modify the master definition. ChoosingEdit This Instancecreates a new, independent copy that will not affect others. - Unintended Global Variables: Accidentally referencing
global.get()inside a subflow can create hidden dependencies. If you need shared state, expose it via a dedicated input port or use anode‑globalnode outside the subflow.
Verifying Your Subflow Works
- Deploy the flow and send a test payload (e.g.,
5) through the first instance. The debug panel should show15. - Deploy the second instance with a different payload (e.g.,
20) and confirm it outputs30. - Open the
Exportdialog for the flow and verify that the subflow definition appears only once undersubflowsand that each instance references it viatype: "subflow:add-ten".
When to Use Subflows
- Repeated logic across multiple flows (e.g., authentication, data formatting).
- Complex sequences that benefit from abstraction (e.g., multi‑step device provisioning).
- Team environments where a single source of truth for a routine is valuable for consistency.
Conclusion
Subflows are a lightweight, editor‑friendly way to encapsulate logic, reduce duplication, and enforce consistency. By exposing only the necessary ports, you keep each instance isolated while still sharing a common implementation. Remember the limits around global context and redeploys, and you’ll have a robust, maintainable flow architecture.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.