{"id":12873,"date":"2025-07-23T07:33:15","date_gmt":"2025-07-23T07:33:15","guid":{"rendered":"https:\/\/www.bacancytechnology.com\/qanda\/?p=12873"},"modified":"2025-07-23T07:35:01","modified_gmt":"2025-07-23T07:35:01","slug":"bpmn-workflow-editor-in-react","status":"publish","type":"post","link":"https:\/\/www.bacancytechnology.com\/qanda\/react\/bpmn-workflow-editor-in-react","title":{"rendered":"BPMN (Business Process Model and Notation) Workflow Editor in React"},"content":{"rendered":"<p>We\u2019ll use <a href=\"https:\/\/www.npmjs.com\/package\/reactflow\" target=\"_blank\" rel=\"noopener\">react-flow<\/a> to render and manipulate BPMN workflow as a JSON graph of nodes and edges.<\/p>\n<p>Here\u2019s a minimal end-to-end example showing how you can build a JSON-first \u201cBPMN-style\u201d workflow editor in React (TypeScript) and talk to a TS\/Node REST back-end, no XML required.<\/p>\n<p><strong>WorkflowEditor.tsx<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"typescript\">import React, { useCallback, useEffect } from \"react\";\r\nimport ReactFlow, {\r\n  addEdge,\r\n  MiniMap,\r\n  Controls,\r\n  Background,\r\n  Connection,\r\n  Edge,\r\n  Node,\r\n  useNodesState,\r\n  useEdgesState,\r\n} from \"reactflow\";\r\nimport \"reactflow\/dist\/style.css\";\r\ntype RFNode = Node&lt;{ label: string }&gt;;\r\ntype RFEdge = Edge;\r\nconst initialNodes: RFNode[] = [\r\n  { id: \"1\", position: { x: 50, y: 50 }, data: { label: \"Node 1\" } },\r\n  { id: \"2\", position: { x: 250, y: 50 }, data: { label: \"Node 2\" } },\r\n];\r\n\r\nconst initialEdges: RFEdge[] = [{ id: \"e1-2\", source: \"1\", target: \"2\" }];\r\nexport interface WorkflowData {\r\n  nodes: Node[];\r\n  edges: Edge[];\r\n}\r\nexport const WorkflowEditor: React.FC = () =&gt; {\r\n  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);\r\n  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);\r\n\r\n  \/\/ when user drags a connection\r\n  const onConnect = useCallback(\r\n    (connection: Edge | Connection) =&gt;\r\n      setEdges((eds) =&gt; addEdge(connection, eds)),\r\n    [setEdges]\r\n  );\r\n  \/\/ load existing workflow\r\n  useEffect(() =&gt; {\r\n    fetch(\"\/api\/workflow\")\r\n      .then((res) =&gt; res.json())\r\n      .then((data: WorkflowData) =&gt; {\r\n        setNodes(data.nodes);\r\n        setEdges(data.edges);\r\n      });\r\n  }, [setNodes, setEdges]);\r\n\r\n  \/\/ save back to server\r\n  const save = () =&gt; {\r\n    fetch(\"\/api\/workflow\", {\r\n      method: \"POST\",\r\n      headers: { \"Content-Type\": \"application\/json\" },\r\n      body: JSON.stringify({ nodes, edges }),\r\n    }).then(() =&gt; {\r\n      alert(\"Workflow saved!\");\r\n    });\r\n  };\r\n  return (\r\n    &lt;div style={{ height: 600 }}&gt;\r\n      &lt;ReactFlow\r\n        nodes={nodes}\r\n        edges={edges}\r\n        onNodesChange={onNodesChange}\r\n        onEdgesChange={onEdgesChange}\r\n        onConnect={onConnect}\r\n        fitView\r\n        attributionPosition=\"bottom-left\"\r\n      &gt;\r\n        &lt;MiniMap \/&gt;\r\n        &lt;Controls \/&gt;\r\n        &lt;Background gap={16} \/&gt;\r\n      &lt;\/ReactFlow&gt;\r\n      &lt;button onClick={save} style={{ marginTop: 10 }}&gt;\r\n        Save Workflow\r\n      &lt;\/button&gt;\r\n    &lt;\/div&gt;\r\n  );\r\n};\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/23073257\/nod-ouput.png\" alt=\"node-ouput\" width=\"777\" height=\"407\" class=\"alignright size-full wp-image-12875\" srcset=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/23073257\/nod-ouput.png 777w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/23073257\/nod-ouput-300x157.png 300w, https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/07\/23073257\/nod-ouput-768x402.png 768w\" sizes=\"(max-width: 777px) 100vw, 777px\" \/><\/p>\n<div class=\"qanda-read-box\"><div class=\"bg-light read-more-icon\"><img decoding=\"async\" src=\"https:\/\/assets.bacancytechnology.com\/qanda\/wp-content\/uploads\/2025\/04\/24061434\/read-txt.png\" alt=\"Also Read\"><p><\/p><h3>Also Read:<\/h3><a href=\"https:\/\/www.bacancytechnology.com\/blog\/react-micro-frontend\" target=\"_blank\">React Micro Frontend<\/a><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>We\u2019ll use react-flow to render and manipulate BPMN workflow as a JSON graph of nodes and edges. Here\u2019s a minimal end-to-end example showing how you can build a JSON-first \u201cBPMN-style\u201d workflow editor in React (TypeScript) and talk to a TS\/Node REST back-end, no XML required. WorkflowEditor.tsx import React, { useCallback, useEffect } from &#8220;react&#8221;; import [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":12874,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-12873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-react"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12873"}],"collection":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/comments?post=12873"}],"version-history":[{"count":2,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12873\/revisions"}],"predecessor-version":[{"id":12877,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/posts\/12873\/revisions\/12877"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media\/12874"}],"wp:attachment":[{"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/media?parent=12873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/categories?post=12873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bacancytechnology.com\/qanda\/wp-json\/wp\/v2\/tags?post=12873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}