[{"data":1,"prerenderedAt":362},["ShallowReactive",2],{"agmd-flowfuse-app-delivery-methods":3,"application-guide-nav":258},{"id":4,"title":5,"blurb":6,"body":7,"description":20,"extension":248,"guide":249,"meta":250,"navOrder":251,"navTitle":5,"navigation":252,"parent":253,"path":254,"seo":255,"slug":13,"stem":256,"__hash__":257},"applicationGuideDoc\u002Fapplication-guide\u002Fflowfuse\u002Fapp-delivery-methods.md","App delivery methods","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.",{"type":8,"value":9,"toc":244},"minimark",[10,14,21,23,208,226],[11,12,5],"h1",{"id":13},"app-delivery-methods",[15,16,17],"p",{},[18,19,20],"strong",{},"App delivery methods — start here",[15,22,6],{},[24,25,26,116],"guide-tabs",{},[27,28,30,36,41,44,50,56,61,89,106,112],"guide-tab",{"label":29},"Whole app",[15,31,32,35],{},[18,33,34],{},"Snapshots & pipelines"," — promote a complete, versioned project through dev → staging → prod to every place that runs it.",[37,38],"flow-diagram",{":edges":39,":nodes":40},"[{\"from\":\"golden\",\"to\":\"fleet\",\"accent\":\"indigo\",\"label\":\"snapshot · pipeline\"}]","[{\"id\":\"golden\",\"label\":\"Dev instance\",\"sub\":\"the golden one you build & test\",\"accent\":\"indigo\"},{\"id\":\"fleet\",\"label\":\"Instances\",\"sub\":\"every place it runs\",\"accent\":\"slate\",\"many\":true}]",[15,42,43],{},"Take the whole app — every flow, setting and dependency — as a versioned snapshot, then promote that one controlled build through pipeline stages to every place that should run it.",[15,45,46,49],{},[18,47,48],{},"Use it when"," — You're shipping a complete application and every site should run the same, controlled version.",[15,51,52,55],{},[18,53,54],{},"How it works"," — A pipeline promotes a snapshot dev → staging → production; each target is parameterised by its own env vars, so one controlled build serves every site.",[15,57,58],{},[18,59,60],{},"Major components",[62,63,64,71,77,83],"ul",{},[65,66,67,70],"li",{},[18,68,69],{},"Snapshot"," — the whole app, frozen as one versioned build",[65,72,73,76],{},[18,74,75],{},"Pipeline"," — promotes that snapshot through dev → staging → prod",[65,78,79,82],{},[18,80,81],{},"Dev instance"," — where you build and test the project",[65,84,85,88],{},[18,86,87],{},"Remote \u002F Hosted Instances"," — the fleet each snapshot rolls out to",[15,90,91,94,95,100,101,105],{},[18,92,93],{},"Where config & data live"," depends on the kind of app you're shipping — a hardware app tied to a device, or a software app on the platform. See ",[96,97,99],"a",{"href":98},"\u002Fapplication-guide\u002Fflowfuse\u002Fhardware-apps\u002F","Hardware apps →"," and ",[96,102,104],{"href":103},"\u002Fapplication-guide\u002Fflowfuse\u002Fsoftware-apps\u002F","Software apps →",".",[15,107,108,111],{},[18,109,110],{},"More phases when you need them"," — a pipeline isn't limited to two stages. Add the phases your process needs — an extra staging tier, an approval gate, per-region rollouts — each one a controlled promotion of the same golden build:",[37,113],{":edges":114,":nodes":115},"[\"dev>stage\",\"stage>prod\"]","[{\"id\":\"dev\",\"label\":\"Dev\",\"sub\":\"golden build\",\"accent\":\"indigo\"},{\"id\":\"stage\",\"label\":\"Staging\"},{\"id\":\"prod\",\"label\":\"Production\",\"sub\":\"every place it runs\",\"accent\":\"slate\",\"many\":true}]",[27,117,119,125,130,137,142,154,158,190,194],{"label":118},"Pieces",[15,120,121,124],{},[18,122,123],{},"Subflow export"," — publish one piece as a package the team installs, like a shared library.",[37,126],{":edges":127,":nodes":128,":legend":129},"[{\"from\":\"sub\",\"to\":\"node\",\"label\":\"export as\"},{\"from\":\"node\",\"to\":\"inst\",\"accent\":\"red\",\"dashed\":true,\"label\":\"install\"},{\"from\":\"inst\",\"to\":\"bom\",\"label\":\"version-tracked\"}]","[{\"id\":\"sub\",\"label\":\"Subflow\",\"sub\":\"reusable block\",\"accent\":\"indigo\"},{\"id\":\"node\",\"label\":\"Custom node\",\"sub\":\"installable package\",\"accent\":\"slate\"},{\"id\":\"inst\",\"label\":\"Instances\",\"sub\":\"install & run the piece\",\"accent\":\"indigo\",\"many\":true},{\"id\":\"bom\",\"label\":\"Bill of Materials\",\"sub\":\"which version each runs\",\"accent\":\"slate\"}]","[{\"line\":\"red\",\"dashed\":true,\"label\":\"install\"},{\"line\":\"neutral\",\"label\":\"version-tracked\"}]",[15,131,132,133,136],{},"Package a single piece of a flow — a block of logic or UI — as a reusable subflow, export it as a ",[18,134,135],{},"custom node"," other apps install, and pull it in instead of copying code between projects.",[15,138,139,141],{},[18,140,48],{}," — A part of an app should be reused across many apps and upgraded in one place — a shared library, not a whole application.",[15,143,144,146,147,149,150,153],{},[18,145,54],{}," — Export the subflow as a ",[18,148,135],{}," — an installable package apps pull in like any library dependency. Apps install it and the Bill of Materials tracks every version in use. Share an ",[18,151,152],{},"example flow"," in the Team Library to show how to wire it up.",[15,155,156],{},[18,157,60],{},[62,159,160,166,172,178,184],{},[65,161,162,165],{},[18,163,164],{},"Subflow"," — the one reusable piece you package",[65,167,168,171],{},[18,169,170],{},"Custom node"," — the installable package your subflow is exported to",[65,173,174,177],{},[18,175,176],{},"Team Library"," — example flows the team shares (a custom node can ship with one to show its use)",[65,179,180,183],{},[18,181,182],{},"Instances"," — the apps that install and run the piece",[65,185,186,189],{},[18,187,188],{},"Bill of Materials"," — tracks which version each app runs",[15,191,192],{},[18,193,93],{},[62,195,196,202],{},[65,197,198,201],{},[18,199,200],{},"Config"," — the subflow's instance properties \u002F env where it's installed.",[65,203,204,207],{},[18,205,206],{},"Distribution"," — export once as a custom node; apps install and upgrade from it, like a library.",[209,210,212],"callout",{"icon":211},"i-lucide-triangle-alert",[15,213,214,217,218,221,222],{},[18,215,216],{},"Dev and prod in the same team?"," Every instance on a team reaches the same shared resources — the Team Broker, FlowFuse Tables, project links, any external Postgres. So a dev instance can read and write the very data prod depends on. ",[18,219,220],{},"Name and namespace resources per environment"," so test data and real data never mix: separate broker topic prefixes, table or schema names, and project-link targets, driven by each instance's env vars. ",[96,223,225],{"href":224},"\u002Fapplication-guide\u002Fflowfuse\u002Fdata-plane\u002F","See the Data plane →",[209,227,229],{"icon":228},"i-lucide-git-branch",[15,230,231,232,235,236,239,240],{},"Dev and prod on ",[18,233,234],{},"separate servers"," — dev in IT or the cloud, prod in OT or air-gapped? A ",[18,237,238],{},"GitHub bridge"," carries the same versioned code across the boundary. That's an architecture decision. ",[96,241,243],{"href":242},"\u002Fapplication-guide\u002Fflowfuse\u002Farchitectures\u002F","See Architectures →",{"title":245,"searchDepth":246,"depth":246,"links":247},"",4,[],"md","flowfuse",{},3,true,null,"\u002Fapplication-guide\u002Fflowfuse\u002Fapp-delivery-methods",{"title":5,"description":20},"application-guide\u002Fflowfuse\u002Fapp-delivery-methods","lhjFW0h0IvgSc6s2TPDnjmR3AWcUUkGPIbjbPDtU3gs",[259,265,269,275,278,280,285,290,295,300,305,311,315,320,326,332,337,342,347,352,356],{"guide":249,"slug":260,"title":261,"navOrder":262,"parent":253,"blurb":263,"path":264},"overview","Overview",1,"The map of the FlowFuse guide — apps, architectures, and a worked example.","\u002Fapplication-guide\u002Fflowfuse\u002Foverview\u002F",{"guide":266,"slug":260,"title":261,"navOrder":262,"parent":253,"blurb":267,"path":268},"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":249,"slug":270,"title":271,"navOrder":272,"parent":253,"blurb":273,"path":274},"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":266,"slug":270,"title":271,"navOrder":272,"parent":253,"blurb":276,"path":277},"The handful of concepts you need to build with Node-RED, and how they fit together.","\u002Fapplication-guide\u002Fnode-red\u002Ffoundations\u002F",{"guide":249,"slug":13,"title":5,"navOrder":251,"parent":253,"blurb":6,"path":279},"\u002Fapplication-guide\u002Fflowfuse\u002Fapp-delivery-methods\u002F",{"guide":266,"slug":281,"title":282,"navOrder":251,"parent":253,"blurb":283,"path":284},"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":249,"slug":286,"title":287,"navOrder":288,"parent":13,"blurb":289,"path":98},"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).",{"guide":266,"slug":291,"title":292,"navOrder":288,"parent":281,"blurb":293,"path":294},"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":249,"slug":296,"title":297,"navOrder":298,"parent":13,"blurb":299,"path":103},"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).",{"guide":266,"slug":301,"title":302,"navOrder":298,"parent":281,"blurb":303,"path":304},"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":266,"slug":306,"title":307,"navOrder":308,"parent":281,"blurb":309,"path":310},"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":249,"slug":312,"title":313,"navOrder":246,"parent":253,"blurb":314,"path":224},"data-plane","Data plane","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.",{"guide":266,"slug":316,"title":317,"navOrder":246,"parent":253,"blurb":318,"path":319},"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":266,"slug":321,"title":322,"navOrder":323,"parent":316,"blurb":324,"path":325},"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":266,"slug":327,"title":328,"navOrder":329,"parent":316,"blurb":330,"path":331},"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":249,"slug":333,"title":334,"navOrder":335,"parent":253,"blurb":336,"path":242},"architectures","Architectures",5,"Every FlowFuse deployment is the same building blocks arranged for where it runs — pick the world you're designing for.",{"guide":249,"slug":338,"title":339,"navOrder":340,"parent":333,"blurb":253,"path":341},"it-architectures","IT architectures",5.1,"\u002Fapplication-guide\u002Fflowfuse\u002Fit-architectures\u002F",{"guide":249,"slug":343,"title":344,"navOrder":345,"parent":333,"blurb":253,"path":346},"ot-architectures","OT architectures",5.2,"\u002Fapplication-guide\u002Fflowfuse\u002Fot-architectures\u002F",{"guide":249,"slug":348,"title":349,"navOrder":350,"parent":333,"blurb":253,"path":351},"iiot-architectures","IIoT architectures",5.3,"\u002Fapplication-guide\u002Fflowfuse\u002Fiiot-architectures\u002F",{"guide":249,"slug":316,"title":317,"navOrder":353,"parent":253,"blurb":354,"path":355},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":249,"slug":357,"title":358,"navOrder":359,"parent":316,"blurb":360,"path":361},"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",1787843651622]