[{"data":1,"prerenderedAt":370},["ShallowReactive",2],{"application-guide-nav":3,"agmd-node-red-design-patterns":118},[4,12,16,22,25,31,36,42,47,53,58,64,70,75,81,87,93,98,103,108,112],{"guide":5,"slug":6,"title":7,"navOrder":8,"parent":9,"blurb":10,"path":11},"flowfuse","overview","Overview",1,null,"The map of the FlowFuse guide — apps, architectures, and a worked example.","\u002Fapplication-guide\u002Fflowfuse\u002Foverview\u002F",{"guide":13,"slug":6,"title":7,"navOrder":8,"parent":9,"blurb":14,"path":15},"node-red","The map of the Node-RED guide — the pattern families that turn an app into a clean flow.","\u002Fapplication-guide\u002Fnode-red\u002Foverview\u002F",{"guide":5,"slug":17,"title":18,"navOrder":19,"parent":9,"blurb":20,"path":21},"foundations","Foundations",2,"The foundation to build on: what FlowFuse is, its core pieces, and how code is shared across teams.","\u002Fapplication-guide\u002Fflowfuse\u002Ffoundations\u002F",{"guide":13,"slug":17,"title":18,"navOrder":19,"parent":9,"blurb":23,"path":24},"The handful of concepts you need to build with Node-RED, and how they fit together.","\u002Fapplication-guide\u002Fnode-red\u002Ffoundations\u002F",{"guide":5,"slug":26,"title":27,"navOrder":28,"parent":9,"blurb":29,"path":30},"app-delivery-methods","App delivery methods",3,"Two different units of code, delivered two ways. Ship the whole app — a complete, versioned project promoted through environments — or publish one reusable piece — a package the whole team installs and upgrades in one place. Pick by what you're shipping: the app, or a part of it.","\u002Fapplication-guide\u002Fflowfuse\u002Fapp-delivery-methods\u002F",{"guide":13,"slug":32,"title":33,"navOrder":28,"parent":9,"blurb":34,"path":35},"patterns","Patterns","The moves that turn an architecture into a clean, reusable flow — find the seams and reuse well, then handle data on the right paths.","\u002Fapplication-guide\u002Fnode-red\u002Fpatterns\u002F",{"guide":5,"slug":37,"title":38,"navOrder":39,"parent":26,"blurb":40,"path":41},"hardware-apps","Hardware apps",3.1,"The three shapes a FlowFuse app takes when it runs on a device. Pick by how much varies per site: nothing (Packaged App), a few settings (Configurable App), or you assemble it yourself (Edge Building Block).","\u002Fapplication-guide\u002Fflowfuse\u002Fhardware-apps\u002F",{"guide":13,"slug":43,"title":44,"navOrder":39,"parent":32,"blurb":45,"path":46},"design-patterns","Design patterns","The structural choices you select for a flow: find the seams it breaks into, then reuse each piece at the lightest level that solves it — link in\u002Fout, link call, subflow, or packaged node.","\u002Fapplication-guide\u002Fnode-red\u002Fdesign-patterns\u002F",{"guide":5,"slug":48,"title":49,"navOrder":50,"parent":26,"blurb":51,"path":52},"software-apps","Software apps",3.2,"The three shapes a FlowFuse app takes when it runs on the platform. Pick by what it needs: a headless job (Packaged App), a user-facing app driven by data (Data-Driven App), or a reusable piece other apps embed (Shared Building Block).","\u002Fapplication-guide\u002Fflowfuse\u002Fsoftware-apps\u002F",{"guide":13,"slug":54,"title":55,"navOrder":50,"parent":32,"blurb":56,"path":57},"handling-data","Handling data","Classify each signal by shape, purpose and direction, then pick the methods it needs — separate the paths, pace the flow, hold state in context, and manage config. The methods you select to move a flow's data.","\u002Fapplication-guide\u002Fnode-red\u002Fhandling-data\u002F",{"guide":13,"slug":59,"title":60,"navOrder":61,"parent":32,"blurb":62,"path":63},"good-form","Good form",3.3,"A clean flow isn't luck — it's a handful of habits. Wire for reading, lay it out on a grid, decouple UI from logic, catch errors where you can see them, and keep data on a stable contract. Follow these and a flow stays readable, reusable, and out of spaghetti.","\u002Fapplication-guide\u002Fnode-red\u002Fgood-form\u002F",{"guide":5,"slug":65,"title":66,"navOrder":67,"parent":9,"blurb":68,"path":69},"data-plane","Data plane",4,"Before you pick where things run, decide how data is handled. Two stores come built into every FlowFuse server install — the Team Broker and relational Tables — exposed to every instance with nothing extra to stand up. Everything else you bring your own: run it (a time-series DB, an existing database, a model) and expose it to the fleet over Project Link, no inbound ports. This is the data plane the architectures on the next pages all sit on.","\u002Fapplication-guide\u002Fflowfuse\u002Fdata-plane\u002F",{"guide":13,"slug":71,"title":72,"navOrder":67,"parent":9,"blurb":73,"path":74},"worked-examples","Worked examples","Turn an app concept into a Node-RED flow — or a few — leaning on the design patterns and data handling. The method, then the OEE apps end to end.","\u002Fapplication-guide\u002Fnode-red\u002Fworked-examples\u002F",{"guide":13,"slug":76,"title":77,"navOrder":78,"parent":71,"blurb":79,"path":80},"oee-edge-aggregator","OEE - Edge Aggregator",4.1,"The edge app from the OEE use case as a Node-RED flow — a straight-line flow packaged as a subflow and configured per line (its PLC tags, via a config UI and a get-config node), with the data treated as a stream and its counts held in context.","\u002Fapplication-guide\u002Fnode-red\u002Foee-edge-aggregator\u002F",{"guide":13,"slug":82,"title":83,"navOrder":84,"parent":71,"blurb":85,"path":86},"oee-central-dashboard","OEE - Central Dashboard",4.2,"The cloud app from the OEE use case as a Node-RED flow — one link out fanning to two link ins on separate tabs (dashboard and batched history), so the live and history paths stay separate and easy to read.","\u002Fapplication-guide\u002Fnode-red\u002Foee-central-dashboard\u002F",{"guide":5,"slug":88,"title":89,"navOrder":90,"parent":9,"blurb":91,"path":92},"architectures","Architectures",5,"Every FlowFuse deployment is the same building blocks arranged for where it runs — pick the world you're designing for.","\u002Fapplication-guide\u002Fflowfuse\u002Farchitectures\u002F",{"guide":5,"slug":94,"title":95,"navOrder":96,"parent":88,"blurb":9,"path":97},"it-architectures","IT architectures",5.1,"\u002Fapplication-guide\u002Fflowfuse\u002Fit-architectures\u002F",{"guide":5,"slug":99,"title":100,"navOrder":101,"parent":88,"blurb":9,"path":102},"ot-architectures","OT architectures",5.2,"\u002Fapplication-guide\u002Fflowfuse\u002Fot-architectures\u002F",{"guide":5,"slug":104,"title":105,"navOrder":106,"parent":88,"blurb":9,"path":107},"iiot-architectures","IIoT architectures",5.3,"\u002Fapplication-guide\u002Fflowfuse\u002Fiiot-architectures\u002F",{"guide":5,"slug":71,"title":72,"navOrder":109,"parent":9,"blurb":110,"path":111},6,"Start from a use case, break it into apps, and draw the architecture that ties them together — the same method a FlowFuse Proof of Value runs.","\u002Fapplication-guide\u002Fflowfuse\u002Fworked-examples\u002F",{"guide":5,"slug":113,"title":114,"navOrder":115,"parent":71,"blurb":116,"path":117},"worked-example","OEE, end to end",6.1,"One use case — OEE across three lines — broken into two apps and two shared services, then drawn out end to end.","\u002Fapplication-guide\u002Fflowfuse\u002Fworked-example\u002F",{"id":119,"title":44,"blurb":45,"body":120,"description":132,"extension":363,"guide":13,"meta":364,"navOrder":39,"navTitle":44,"navigation":365,"parent":32,"path":366,"seo":367,"slug":43,"stem":368,"__hash__":369},"applicationGuideDoc\u002Fapplication-guide\u002Fnode-red\u002Fdesign-patterns.md",{"type":121,"value":122,"toc":360},"minimark",[123,126,133,144],[124,125,44],"h1",{"id":43},[127,128,129],"p",{},[130,131,132],"strong",{},"Design patterns — pick how a flow is structured and reused",[127,134,135,136,139,140,143],{},"A design pattern is a structural choice you make for a piece of a flow. Building a flow you'll select one or more: first ",[130,137,138],{},"find the seams"," — the components the flow really breaks into — then, for each piece worth reusing, pick the ",[130,141,142],{},"level of reuse"," that fits. Reuse is a ladder — link in\u002Fout → link call → subflow → palette node — and each rung up buys more reuse but costs more to build and maintain, so climb only when the rung below won't do.",[145,146,147,204,254,294,327],"guide-tabs",{},[148,149,151,157,160,165,168,196],"guide-tab",{"label":150},"Find the seams",[127,152,153,156],{},[130,154,155],{},"Name the pieces first"," — before any reuse, find the components hiding in the flow and draw a box around each.",[127,158,159],{},"Most spaghetti is three or four well-defined components that were never named. A giant flow is bad because it has no seams: you can't reuse, test, or hand off part of a blob, and any edit means reading the whole tab. Naming the structure is the fix — not tidier wires.",[161,162],"flow-diagram",{":edges":163,":nodes":164},"[\"ingest>normalize\",\"normalize>enrich\",\"enrich>publish\"]","[{\"id\":\"ingest\",\"label\":\"Ingest\",\"accent\":\"indigo\"},{\"id\":\"normalize\",\"label\":\"Normalize\",\"accent\":\"indigo\"},{\"id\":\"enrich\",\"label\":\"Enrich\",\"accent\":\"indigo\"},{\"id\":\"publish\",\"label\":\"Publish\",\"accent\":\"indigo\"}]",[127,166,167],{},"Look for one of these and box it off:",[169,170,171,178,184,190],"ul",{},[172,173,174,177],"li",{},[130,175,176],{},"A repeated cluster"," — the same three or four nodes appearing in more than one place.",[172,179,180,183],{},[130,181,182],{},"A logical stage"," — ingest, normalize, enrich, publish; each a bounded step with a clear input and output.",[172,185,186,189],{},[130,187,188],{},"A bounded responsibility"," — one thing the piece owns from end to end.",[172,191,192,195],{},[130,193,194],{},"A reuse magnet"," — a piece other flows will obviously want.",[127,197,198,199,203],{},"Once the seams are named, each becomes a candidate for reuse — and ",[200,201,202],"em",{},"how"," you reuse it is the choice in the tabs that follow. A piece you'll only ever use once still earns its box; it just stays a plain seam.",[148,205,207,216,223,229,232,238,248],{"label":206},"Link in \u002F out",[127,208,209,212,213],{},[130,210,211],{},"Route within one instance"," — ",[200,214,215],{},"local · organization, not reuse.",[127,217,218,219,222],{},"Link in and link out route messages between points and tabs inside a single Node-RED instance, without dragging a wire across the canvas. One link out can feed many link ins — ",[130,220,221],{},"one producer, many consumers"," — so it's the clean way to fan a message out to several independent paths.",[161,224],{":edges":225,":nodes":226,"align":227,":legend":228},"[\"prod>lout\",{\"from\":\"lout\",\"to\":\"lin1\",\"dashed\":true,\"label\":\"link\"},{\"from\":\"lout\",\"to\":\"lin2\",\"dashed\":true},{\"from\":\"lout\",\"to\":\"lin3\",\"dashed\":true},\"lin1>c1\",\"lin2>c2\",\"lin3>c3\"]","[{\"id\":\"prod\",\"label\":\"producer\",\"sub\":\"one source\",\"accent\":\"indigo\",\"col\":1,\"row\":2},{\"id\":\"lout\",\"label\":\"link out\",\"sub\":\"broadcast\",\"accent\":\"indigo\",\"col\":2,\"row\":2},{\"id\":\"lin1\",\"label\":\"link in\",\"accent\":\"indigo\",\"col\":3,\"row\":1},{\"id\":\"c1\",\"label\":\"consumer A\",\"accent\":\"slate\",\"col\":4,\"row\":1},{\"id\":\"lin2\",\"label\":\"link in\",\"accent\":\"indigo\",\"col\":3,\"row\":2},{\"id\":\"c2\",\"label\":\"consumer B\",\"accent\":\"slate\",\"col\":4,\"row\":2},{\"id\":\"lin3\",\"label\":\"link in\",\"accent\":\"indigo\",\"col\":3,\"row\":3},{\"id\":\"c3\",\"label\":\"consumer C\",\"accent\":\"slate\",\"col\":4,\"row\":3}]","left","[{\"line\":\"neutral\",\"dashed\":true,\"label\":\"link out → link in\"}]",[127,230,231],{},"Nothing is packaged or reused, though — the message just teleports to the matching link.",[127,233,234,237],{},[130,235,236],{},"Select it when"," — you need to tidy wiring, route between tabs, or fan one message out to several consumers. It's the bottom rung: routing and organization, no reuse of logic.",[127,239,240,243,244,247],{},[130,241,242],{},"Not this when"," — you're trying to share ",[200,245,246],{},"work",". The moment more than one path needs the same logic or resource, climb to a link call.",[127,249,250,253],{},[130,251,252],{},"Stays local"," — link in\u002Fout never leave the instance and distribute nothing.",[148,255,257,265,268,274,279,289],{"label":256},"Link call",[127,258,259,212,262],{},[130,260,261],{},"A shared, returning service",[200,263,264],{},"local · one instance.",[127,266,267],{},"Turn a link-in \u002F link-out pair into a callable service: a piece of work exposed once that any path calls and that returns the result to whoever called it, with no central router to build. It's the workhorse for shared services inside one instance — a database pool, a model call, a broker connection, a common transform.",[161,269],{":edges":270,":nodes":271,"align":227,":groups":272,":legend":273},"[\"in>lc\",\"lc>resp\",\"lin>pool\",\"pool>lout\",{\"from\":\"lc\",\"to\":\"lin\",\"dashed\":true,\"label\":\"call\",\"accent\":\"teal\"},{\"from\":\"lout\",\"to\":\"lc\",\"dashed\":true,\"label\":\"return\",\"accent\":\"teal\"}]","[{\"id\":\"in\",\"label\":\"http in\",\"sub\":\"a request\",\"accent\":\"indigo\",\"col\":1,\"row\":1},{\"id\":\"lc\",\"label\":\"link call\",\"sub\":\"calls the service\",\"accent\":\"teal\",\"col\":2,\"row\":1},{\"id\":\"resp\",\"label\":\"http response\",\"sub\":\"the end · sends result\",\"accent\":\"indigo\",\"col\":3,\"row\":1},{\"id\":\"lin\",\"label\":\"link in\",\"sub\":\"service entry\",\"accent\":\"green\",\"col\":1,\"row\":2},{\"id\":\"pool\",\"label\":\"SQL pool\",\"sub\":\"one shared connection\",\"accent\":\"green\",\"col\":2,\"row\":2},{\"id\":\"lout\",\"label\":\"link out\",\"sub\":\"return mode\",\"accent\":\"green\",\"col\":3,\"row\":2}]","[{\"id\":\"svc\",\"label\":\"Shared service · every path calls this one link in\",\"accent\":\"green\",\"nodes\":[\"lin\",\"pool\",\"lout\"]}]","[{\"line\":\"teal\",\"dashed\":true,\"label\":\"call \u002F return\"}]",[127,275,276,278],{},[130,277,236],{}," — more than one path needs the same resource or logic and you don't want a copy per path. Each path calls the one shared service, the result comes back, and the path finishes at its own sink — an http response here. No funnel: the shared service has exactly one wire in.",[127,280,281,284,285,288],{},[130,282,283],{},"The trade-off"," — every caller shares ",[200,286,287],{},"one"," configuration. That's the point when the config is fixed; it's the limit when each use needs its own settings — which is when you climb to a subflow.",[127,290,291,293],{},[130,292,252],{}," — reuse within one instance; it doesn't package or distribute.",[148,295,297,305,312,317,322],{"label":296},"Subflow",[127,298,299,212,302],{},[130,300,301],{},"A packaged set of actions, with its own config",[200,303,304],{},"cross-instance.",[127,306,307,308,311],{},"A subflow bundles a ",[200,309,310],{},"set of actions"," — several nodes — into one reusable node you can drop into a flow many times, each instance carrying its own configuration. Unlike a link call, which shares one fixed config, a subflow is a packaged assembly that varies per drop, and it travels between Node-RED instances.",[161,313],{":edges":314,":nodes":315,"align":227,":groups":316},"[\"a1>a2\",\"a2>a3\",{\"from\":\"def\",\"to\":\"uses\",\"dashed\":true,\"label\":\"packaged as one node\"}]","[{\"id\":\"a1\",\"label\":\"validate\",\"col\":1,\"row\":1},{\"id\":\"a2\",\"label\":\"transform\",\"col\":2,\"row\":1},{\"id\":\"a3\",\"label\":\"publish\",\"col\":3,\"row\":1},{\"id\":\"n1\",\"label\":\"subflow\",\"sub\":\"config A\",\"accent\":\"indigo\",\"col\":1,\"row\":2},{\"id\":\"n2\",\"label\":\"subflow\",\"sub\":\"config B\",\"accent\":\"indigo\",\"col\":2,\"row\":2},{\"id\":\"n3\",\"label\":\"subflow\",\"sub\":\"config C\",\"accent\":\"indigo\",\"col\":3,\"row\":2}]","[{\"id\":\"def\",\"label\":\"Subflow · a set of actions packaged into one node, authored once\",\"accent\":\"teal\",\"nodes\":[\"a1\",\"a2\",\"a3\"]},{\"id\":\"uses\",\"label\":\"Reused · that one node dropped in, each with its own config\",\"accent\":\"indigo\",\"nodes\":[\"n1\",\"n2\",\"n3\"]}]",[127,318,319,321],{},[130,320,236],{}," — a piece needs per-instance config (the same logic, different settings each place), or you need to reuse it across other Node-RED instances. Start as a link call and promote to a subflow only once it earns that.",[127,323,324,326],{},[130,325,283],{}," — heavier than a link call: each instance duplicates its connections, and defaulting to subflows for everything adds indirection. Use it for genuine per-instance reuse, not as the default.",[148,328,330,338,350,355],{"label":329},"Palette node",[127,331,332,212,335],{},[130,333,334],{},"Real packaged code",[200,336,337],{},"distributed.",[127,339,340,341,344,345,349],{},"The top rung: package a piece as an installable palette node — real code, versioned and installed like any library dependency. It's the same ",[130,342,343],{},"custom node"," the ",[346,347,348],"a",{"href":30},"FlowFuse app delivery methods"," publish for reuse across apps, and the point where Node-RED reuse hands off to the FlowFuse guide's distribution story.",[127,351,352,354],{},[130,353,236],{}," — a piece is used across many projects or teams and deserves to be versioned, installed, and upgraded like a dependency — not copied, and beyond what a shared subflow can carry.",[127,356,357,359],{},[130,358,283],{}," — it's real code with a real release cycle: a package to build, test, and maintain. The most powerful reuse and the most to own. Don't take this rung until link call and subflow genuinely can't cover it.",{"title":361,"searchDepth":67,"depth":67,"links":362},"",[],"md",{},true,"\u002Fapplication-guide\u002Fnode-red\u002Fdesign-patterns",{"title":44,"description":132},"application-guide\u002Fnode-red\u002Fdesign-patterns","ZQxQfKSs-KfzusNh5nL3Ky0slO9qsVh-AConHsMEOGc",1787068106122]