Using Node-RED Subflows to Keep Your Flows DRY and Maintainable
Learn how to turn a repeated group of nodes into a reusable subflow, expose configurable properties, and see the impact of changes across all instances.
17 Feb 2026, 08:46 UTC

The problem: duplicated logic makes flows hard to change
When you build Node-RED dashboards or integrations, you often find yourself copying the same set of nodes – for example, a temperature-sensor reading, a scaling function, and a debug output – across multiple tabs. If you later need to adjust the scaling factor or add a new status check, you must edit each copy manually. This repetition increases the chance of inconsistencies and makes maintenance tedious.
Thesis: subflows give you a single source of truth for reusable node groups
Node-RED subflows let you package any selection of nodes into a new, reusable node that appears in the palette. You can drop multiple instances of that subflow onto any flow tab, configure each instance with its own properties, and when you edit the subflow definition, every instance updates automatically. Subflows are supported in Node-RED 1.0 and later; check your version in the editor's menu or startup log if you're unsure.
How to create a subflow
- Open the flow that contains the nodes you want to reuse.
- Select the nodes (click and drag or Shift-click).
- Right-click the selection and choose
Convert to Subflowfrom the context menu. - Node-RED creates a subflow template, adds a new entry to the palette under the
subflowssection, and replaces the selected nodes on the canvas with a single instance of that subflow.
You can verify the creation by opening the palette and looking for your new subflow name, then dragging a fresh instance onto the canvas.
Making the subflow configurable with environment variables
Often you need each instance to behave slightly differently – for example, applying a different gain to a sensor reading. Subflows expose an Env tab where you can define custom properties.
- Double-click the subflow instance (or click the
Edit subflowbutton in the palette) to open its editor. - Go to the
Envtab and clickAdd. Enter a name likegainand set a default value, e.g.,1. - Inside the subflow, use a
functionnode to read the property:
// inside a function node within the subflow
const gain = Number(env.get('gain')) || 1;
msg.payload = msg.payload * gain;
return msg;Click Done to save the subflow definition. Now each time you drag a new instance of the subflow onto a canvas, you can set its gain value in the instance's edit dialog. Changing the default in the subflow's Env tab updates the default for future instances, while existing instances keep their overridden values unless you reset them.
Worked example: a reusable temperature-processing subflow
Suppose you have three temperature sensors (MQTT topics sensor/temp1, sensor/temp2, sensor/temp3) that each need an mqtt in node, a function node to convert Celsius to Fahrenheit, and a debug node. Instead of recreating these three nodes three times:
- Build the flow for one sensor (MQTT in → function → debug).
- Select the three nodes and convert them to a subflow named
tempProcessor. - In the subflow's Env tab, add a property
topicwith no default. - In the
mqtt innode, set the topic field to reference the environment variable (Node-RED supports${topic}-style env substitution in many node fields; if the field doesn't support it, read the value in a small function node and setmsg.topicbefore a dynamic-subscribe MQTT node instead). - Close the subflow editor. Drag three instances onto the canvas and set each instance's
topicproperty tosensor/temp1,sensor/temp2, andsensor/temp3. - Deploy. Each instance subscribes to its own topic, converts the temperature, and outputs the Fahrenheit value.
If you later decide to add a smoothing step (e.g., a moving-average function), edit the tempProcessor subflow, insert the new node, deploy, and all three instances instantly gain the smoothing behavior.
Trade-offs and limitations
- Editor performance: Very large subflows (hundreds of nodes) can slow the Node-RED editor because the entire definition is loaded each time you open it. Keep subflows focused on a single concern.
- Credential handling: Internal node credentials (e.g., API keys) cannot be exposed directly via the subflow's Env tab. Pass sensitive data through environment variables or separate config nodes.
- Flow file size: Each subflow instance stores only a reference to the definition, but the definition itself lives in the flow JSON. With many large subflows, the file can grow noticeably.
To check that a subflow is working as expected, open the debug sidebar, trigger an input (e.g., publish a test MQTT message), and verify the output matches the expected conversion. Subflows retain full debugging: status indicators show on instances, and you can inspect internal nodes while editing the subflow. If you suspect performance issues, watch the editor's responsiveness when opening the subflow editor; noticeable lag indicates the subflow may be too large.
Actionable closing
Start small: identify a repeated node group in one of your flows, convert it to a subflow, and expose one configurable property via the Env tab. Use the subflow in two or three places, then change a property or the internal logic and watch the updates propagate. This practice reduces duplication, simplifies debugging, and makes future changes far less error-prone. If the editor slows down, split the subflow into smaller, more focused pieces.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.