A React Flow alternative with the Pro features built in

React Flow is an excellent library with the largest community in this space — if it fits, use it. Teams reach for Grafloria when the features they need next (undo, copy/paste, helper lines, collaboration, exports) turn out to live in the Pro subscription, or when the same canvas must also ship in Angular, Vue, or a plain web component.

When to stay with React Flow

You're all-in on React, you want the biggest ecosystem of examples and integrations, and you're happy assembling editor features yourself or paying for Pro (≈ $169–289/month) to get the closed-source examples and support. Its extensibility and accessibility are first-rate.

Why teams switch

GrafloriaReact Flow
License / priceMIT — everything, $0MIT core; Pro subscription for undo, copy-paste, helper lines, collab examples + support
FrameworksReact · Angular · Vue · web component — one engineReact only
Edge routingObstacle-avoiding router built in — edges walk around nodesBezier/step edges; avoidance is DIY
Auto-layoutELK, dagre, tree, force, grid — one call, ELK lazy-loadedBring your own (elkjs/dagre wiring is on you)
Undo / redoCommand-based, ⌘Z works with zero wiringPro example
CollaborationPer-property CRDT in the engine; bring any transportPro example
Nested sub-flowsContainers with live drag-adoption in and out — one undo stepparentId + extent primitives; the editor behaviour is DIY
ExportSVG / PNG / PDF built in, server-side tooScreenshot via html-to-image (community recipe)
Text formatMermaid-compatible import/export with a lossless sidecar—
Minimap / controlsBuilt in (plugins)Built in

The same flow, both ways

The API is deliberately React-Flow-shaped — controlled state, the same hooks pattern — so an evaluation is a diff, not a rewrite. React Flow:

import { ReactFlow, useNodesState, useEdgesState } from '@xyflow/react';

export default function App() {
  const [nodes, , onNodesChange] = useNodesState(initialNodes);
  const [edges, , onEdgesChange] = useEdgesState(initialEdges);
  return (
    <div style={{ height: '100vh' }}>
      <ReactFlow nodes={nodes} edges={edges}
        onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} />
    </div>
  );
}

Grafloria:

import { GrafloriaFlow, useNodesState, useEdgesState } from '@grafloria/react';

export default function App() {
  const [nodes, , onNodesChange] = useNodesState(initialNodes);
  const [edges, , onEdgesChange] = useEdgesState(initialEdges);
  return (
    <div style={{ height: '100vh' }}>
      <GrafloriaFlow nodes={nodes} edges={edges}
        onNodesChange={onNodesChange} onEdgesChange={onEdgesChange}
        layout="elk" plugins />
    </div>
  );
}

The mental model maps one-to-one

React FlowGrafloria
nodes/edges, useNodesStatesame names, same shapes — id, position, data
nodeTypes componentsnodeTypes components, marked custom: true on the node
<Handle> in JSXports on the node spec — data that serializes with the document
fitView, minimap, controlsfitView(), plugins flag
subflows (parentId)containers with drag-adoption — live demo

Migration notes: position/data carry over as-is; handles become ports on the node spec (no <Handle> components); mark nodeTypes nodes custom: true. The React deep guides cover each mapping.

Measured, not claimed

We publish a reproducible two-library benchmark — one deterministic scene, real mouse gestures, both libraries measured in the same session against the published npm packages. As of the current release (engine 0.3.6 / renderer 0.4.6, Apple M1 Pro): at 2,000 nodes Grafloria mounts ~1.8× faster, both pan gestures hold 60fps, and node drag averages 25.6ms/frame against React Flow's 38.5 — with neither library at 60fps on that last row yet. The harness throws if the two libraries are not driven identically; the first version of it was wrong in our favour and the README documents exactly how. cd benchmarks && npm install && node run.mjs reproduces the table on your machine.

Building in Angular or Vue?

The same engine ships native components for both — see React Flow alternative for Angular and the Vue tutorial.

Pricing and feature cells reflect vendor pages and shipped type definitions as of July–August 2026 — always confirm on the vendor's site. Corrections welcome on GitHub; this page aims to stay honest, not to win.