{"id":26661320,"url":"https://github.com/tisoap/react-flow-smart-edge","last_synced_at":"2026-01-25T10:32:19.881Z","repository":{"id":37991081,"uuid":"427014682","full_name":"tisoap/react-flow-smart-edge","owner":"tisoap","description":"Custom Edge for React Flow that never intersects with other nodes","archived":false,"fork":false,"pushed_at":"2025-08-20T17:34:05.000Z","size":17217,"stargazers_count":334,"open_issues_count":12,"forks_count":52,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-23T16:19:07.355Z","etag":null,"topics":["edge","flow","flowchart","graph","pathfinding","react","smart","typescript"],"latest_commit_sha":null,"homepage":"https://tisoap.github.io/react-flow-smart-edge/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tisoap.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"ko_fi":"tisoap","github":"tisoap"}},"created_at":"2021-11-11T13:39:39.000Z","updated_at":"2025-11-22T15:36:14.000Z","dependencies_parsed_at":"2023-09-23T20:58:13.343Z","dependency_job_id":null,"html_url":"https://github.com/tisoap/react-flow-smart-edge","commit_stats":{"total_commits":148,"total_committers":2,"mean_commits":74.0,"dds":"0.020270270270270285","last_synced_commit":"cb9267749fc54d67e3c3c43600e302d9e9c723b0"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/tisoap/react-flow-smart-edge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tisoap%2Freact-flow-smart-edge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tisoap%2Freact-flow-smart-edge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tisoap%2Freact-flow-smart-edge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tisoap%2Freact-flow-smart-edge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tisoap","download_url":"https://codeload.github.com/tisoap/react-flow-smart-edge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tisoap%2Freact-flow-smart-edge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28751816,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-25T10:25:12.305Z","status":"ssl_error","status_checked_at":"2026-01-25T10:25:11.933Z","response_time":113,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["edge","flow","flowchart","graph","pathfinding","react","smart","typescript"],"created_at":"2025-03-25T13:16:16.946Z","updated_at":"2026-01-25T10:32:19.872Z","avatar_url":"https://github.com/tisoap.png","language":"TypeScript","funding_links":["https://ko-fi.com/tisoap","https://github.com/sponsors/tisoap","https://ko-fi.com/J3J472RAJ"],"categories":[],"sub_categories":[],"readme":"# React Flow Smart Edge\n\nCustom Edges for React Flow that never intersect with other nodes, using pathfinding.\n\n![TypeScript](https://shields.io/badge/TypeScript-3178C6?logo=TypeScript\u0026logoColor=white)\n![Storybook](https://img.shields.io/badge/Storybook-FF4785?logo=storybook\u0026logoColor=white)\n![ESLint](https://img.shields.io/badge/ESLint-3A33D1?logo=eslint\u0026logoColor=white)\n\n![Smart Edge](./.github/images/example-image.gif)\n\n## Install\n\nWith `npm`:\n\n```bash\nnpm install @tisoap/react-flow-smart-edge\n```\n\nWith `yarn`:\n\n```bash\nyarn add @tisoap/react-flow-smart-edge\n```\n\nThis package is only compatible with [**version 12** of React Flow Edge](https://reactflow.dev/learn/troubleshooting/migrate-to-v12).\n\n## Support\n\nLike this project and want to show your support? Buy me a coffee:\n\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/J3J472RAJ)\n\n_Really_ like this project? Sponsor me on GitHub:\n\n[![GitHub Sponsors](https://img.shields.io/static/v1?label=Sponsor%20Me\u0026message=%E2%9D%A4\u0026logo=GitHub\u0026color=%23fe8e86)](https://github.com/sponsors/tisoap)\n\n## Usage\n\nThis package ships with the following Smart Edges components:\n\n- `SmartBezierEdge`: A smart equivalent to React Flow's [BezierEdge](https://reactflow.dev/docs/api/edges/edge-types/)\n- `SmartStraightEdge`: A smart equivalent to React Flow's [StraightEdge](https://reactflow.dev/docs/api/edges/edge-types/)\n- `SmartStepEdge`: A smart equivalent to React Flow's [StepEdge](https://reactflow.dev/docs/api/edges/edge-types/)\n\nEach one can be imported individually as a named export.\n\n### Example\n\n```jsx\nimport React from \"react\";\nimport { ReactFlow } from \"reactflow\";\nimport { SmartBezierEdge } from \"@tisoap/react-flow-smart-edge\";\nimport \"@xyflow/react/dist/style.css\";\n\nconst nodes = [\n  {\n    id: \"1\",\n    data: { label: \"Node 1\" },\n    position: { x: 300, y: 100 },\n  },\n  {\n    id: \"2\",\n    data: { label: \"Node 2\" },\n    position: { x: 300, y: 200 },\n  },\n];\n\nconst edges = [\n  {\n    id: \"e21\",\n    source: \"2\",\n    target: \"1\",\n    type: \"smart\",\n  },\n];\n\n// You can give any name to your edge types\n// https://reactflow.dev/docs/api/edges/custom-edges/\nconst edgeTypes = {\n  smart: SmartBezierEdge,\n};\n\nexport const Graph = (props) =\u003e {\n  const { children, ...rest } = props;\n\n  return (\n    \u003cReactFlow\n      defaultNodes={nodes}\n      defaultEdges={edges}\n      edgeTypes={edgeTypes}\n      {...rest}\n    \u003e\n      {children}\n    \u003c/ReactFlow\u003e\n  );\n};\n```\n\n## Edge Options\n\nAll smart edges will take the exact same options as a [React Flow Edge](https://reactflow.dev/docs/api/edges/edge-options/).\n\n## Custom Smart Edges\n\nYou can have more control over how the edge is rerendered by creating a [custom edge](https://reactflow.dev/docs/api/edges/custom-edges/) and using the provided `getSmartEdge` function. It takes an object with the following keys:\n\n- `sourcePosition`, `targetPosition`, `sourceX`, `sourceY`, `targetX` and `targetY`: The same values your [custom edge](https://reactflow.dev/docs/examples/edges/custom-edge/) will take as props\n- `nodes`: An array containing all graph nodes, you can get it from the [`useNodes` hook](https://reactflow.dev/docs/api/hooks/use-nodes/)\n\n### Example\n\nJust like you can use `getBezierPath` from `reactflow` to create a [custom edge with a button](https://reactflow.dev/docs/examples/edges/edge-with-button/), you can do the same with `getSmartEdge`:\n\n```jsx\nimport React from \"react\";\nimport { useNodes, BezierEdge } from \"@xyflow/react\";\nimport { getSmartEdge } from \"@tisoap/react-flow-smart-edge\";\n\nconst foreignObjectSize = 200;\n\nexport function SmartEdgeWithButtonLabel(props) {\n  const {\n    id,\n    sourcePosition,\n    targetPosition,\n    sourceX,\n    sourceY,\n    targetX,\n    targetY,\n    style,\n    markerStart,\n    markerEnd,\n  } = props;\n\n  const nodes = useNodes();\n\n  const getSmartEdgeResponse = getSmartEdge({\n    sourcePosition,\n    targetPosition,\n    sourceX,\n    sourceY,\n    targetX,\n    targetY,\n    nodes,\n  });\n\n  // If the value returned is an Error, it means \"getSmartEdge\" was unable\n  // to find a valid path, and you should do something else instead\n  if (smartResponse instanceof Error) {\n    return \u003cBezierEdge {...props} /\u003e;\n  }\n\n  const { edgeCenterX, edgeCenterY, svgPathString } = getSmartEdgeResponse;\n\n  return (\n    \u003c\u003e\n      \u003cpath\n        style={style}\n        className=\"react-flow__edge-path\"\n        d={svgPathString}\n        markerEnd={markerEnd}\n        markerStart={markerStart}\n      /\u003e\n      \u003cforeignObject\n        width={foreignObjectSize}\n        height={foreignObjectSize}\n        x={edgeCenterX - foreignObjectSize / 2}\n        y={edgeCenterY - foreignObjectSize / 2}\n        requiredExtensions=\"http://www.w3.org/1999/xhtml\"\n      \u003e\n        \u003cbutton\n          onClick={(event) =\u003e {\n            event.stopPropagation();\n            alert(`remove ${id}`);\n          }}\n        \u003e\n          X\n        \u003c/button\u003e\n      \u003c/foreignObject\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n## Advanced Custom Smart Edges\n\nThe `getSmartEdge` function also accepts an optional object `options`, which allows you to configure aspects of the path-finding algorithm. You may use it like so:\n\n```js\nconst myOptions = {\n  // your configuration goes here\n  nodePadding: 20,\n  gridRatio: 15,\n};\n\n// ...\n\nconst getSmartEdgeResponse = getSmartEdge({\n  sourcePosition,\n  targetPosition,\n  sourceX,\n  sourceY,\n  targetX,\n  targetY,\n  nodes,\n  // Pass down options in the getSmartEdge object\n  options: myOptions,\n});\n```\n\nThe `options` object accepts the following keys (they're all optional):\n\n- `nodePadding`: How many pixels of padding are added around nodes, or by how much should the edge avoid the walls of a node. Default `10`, minimum `2`.\n- `gridRatio`: The size in pixels of each square grid cell used for path-finding. Smaller values for a more accurate path, bigger for faster path-finding. Default `10`, minimum `2`.\n- `drawEdge`: Allows you to change the function responsible to draw the SVG line, by default it's the same used by `SmartBezierEdge` ([more below](#drawedge))\n- `generatePath`: Allows you to change the function for the path-finding, by default it's the same used by `SmartBezierEdge` ([more below](#generatepath))\n\n### `drawEdge`\n\nWith the `drawEdge` option, you can change the function used to generate the final [SVG path string](https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths), used to draw the line. By default it's the `svgDrawSmoothLinePath` function (same as used by the `SmartBezierEdge`), but the package also includes `svgDrawStraightLinePath` (same as used by the `SmartStraightEdge` and `SmartStepEdge`), or you can provide your own.\n\n```jsx\nimport {\n  getSmartEdge,\n  // Available built-in SVG draw functions\n  svgDrawSmoothLinePath,\n  svgDrawStraightLinePath,\n} from \"@tisoap/react-flow-smart-edge\";\n\n// Using provided SVG draw functions:\nconst result = getSmartEdge({\n  // ...\n  options: {\n    drawEdge: svgDrawSmoothLinePath,\n  },\n});\n\n// ...or using your own custom function\nconst result = getSmartEdge({\n  // ...\n  options: {\n    drawEdge: (source, target, path) =\u003e {\n      // your code goes here\n      // ...\n      return svgPath;\n    },\n  },\n});\n```\n\nThe function you provided must comply with this signature:\n\n```ts\ntype SVGDrawFunction = (\n  source: XYPosition, // The starting {x, y} point\n  target: XYPosition, // The ending  {x, y} point\n  path: number[][], // The sequence of points [x, y] the line must follow\n) =\u003e string; // A string to be used in the \"d\" property of the SVG line\n```\n\nFor inspiration on how to implement your own, you can check the [`drawSvgPath.ts` source code](https://github.com/tisoap/react-flow-smart-edge/blob/main/src/functions/drawSvgPath.ts).\n\n### `generatePath`\n\nWith the `generatePath` option, you can change the function used to do [Pathfinding](https://en.wikipedia.org/wiki/Pathfinding). By default, it's the `pathfindingAStarDiagonal` function (same as used by the `SmartBezierEdge`), but the package also includes `pathfindingAStarNoDiagonal` (used by `SmartStraightEdge` and `SmartStepEdge`), or your can provide your own.\n\n```jsx\nimport {\n  getSmartEdge,\n  // Available built-in pathfinding functions\n  pathfindingAStarDiagonal,\n  pathfindingAStarNoDiagonal,\n} from \"@tisoap/react-flow-smart-edge\";\n\n// Using provided pathfinding functions:\nconst result = getSmartEdge({\n  // ...\n  options: {\n    generatePath: pathfindingAStarDiagonal,\n  },\n});\n\n// ...or using your own custom function\nconst result = getSmartEdge({\n  // ...\n  options: {\n    generatePath: (grid, start, end) =\u003e {\n      // your code goes here\n      // ...\n      return { fullPath, smoothedPath };\n    },\n  },\n});\n```\n\nThe function you provide must comply with this signature:\n\n```ts\ntype PathFindingFunction = (\n  grid: Grid, // Grid representation of the graph\n  start: XYPosition, // The starting {x, y} point\n  end: XYPosition, // The ending  {x, y} point\n) =\u003e number[][]; // Array of points [x, y] representing the full path with all points\n```\n\nFor inspiration on how to implement your own, you can check the [`generatePath.ts` source code](https://github.com/tisoap/react-flow-smart-edge/blob/main/src/functions/generatePath.ts).\n\n### Advanced Examples\n\n```jsx\nimport {\n\tgetSmartEdge,\n\tsvgDrawSmoothLinePath,\n\tsvgDrawStraightLinePath\n\tpathfindingAStarDiagonal,\n\tpathfindingAStarNoDiagonal,\n} from '@tisoap/react-flow-smart-edge'\n\n// ...\n\n// Same as importing \"SmartBezierEdge\" directly\nconst bezierResult = getSmartEdge({\n\t// ...\n\toptions: {\n\t\tdrawEdge: svgDrawSmoothLinePath,\n\t\tgeneratePath: pathfindingAStarDiagonal,\n\t}\n})\n\n// Same as importing \"SmartStepEdge\" directly\nconst stepResult = getSmartEdge({\n\t// ...\n\toptions: {\n\t\tdrawEdge: svgDrawStraightLinePath,\n\t\tgeneratePath: pathfindingAStarNoDiagonal,\n\t}\n})\n\n// Same as importing \"SmartStraightEdge\" directly\nconst straightResult = getSmartEdge({\n\t// ...\n\toptions: {\n\t\tdrawEdge: svgDrawStraightLinePath,\n\t\tgeneratePath: pathfindingAStarNoDiagonal,\n\t}\n})\n```\n\n## Storybook\n\nYou can see live Storybook examples by visiting [this page](https://tisoap.github.io/react-flow-smart-edge/), and see their source code [here](https://github.com/tisoap/react-flow-smart-edge/blob/main/src/stories/SmartEdge.stories.tsx).\n\n## License\n\nThis project is [MIT](https://github.com/tisoap/react-flow-smart-edge/blob/main/LICENSE) licensed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftisoap%2Freact-flow-smart-edge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftisoap%2Freact-flow-smart-edge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftisoap%2Freact-flow-smart-edge/lists"}