npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

flowinger

v1.1.0

Published

A small, dependency-free React Flow alternative: a node-graph and flowchart renderer for React with React Flow's API, ~20 kB gzipped core, SSR, and free undo/redo, export and smart edges

Readme

Status: 1.1 — semantic versioning: a change that breaks what that page covers waits for 2.0. It is what QueryLens draws its diagrams with, and its API follows React Flow's — 12's, and 13's names as well; Upgrading says what 2.0, which follows React Flow 13, will change, and what 1.0 did. These docs describe main; what is newer than the latest npm release is listed under Unreleased there.

Why Flowinger

  • Small, and only what you use. The core is about 19.9 kB gzipped; drag, connect, selection and the rest are opt-in features that add only their own code, so the whole canvas is about 37 kB. In QueryLens, swapping React Flow for it took the diagram chunk from 60.5 kB to 19.0 kB gzipped.
  • No dependencies. react and react-dom (18 or 19) are the only peers. Plain DOM, SVG and CSS.
  • Your components are the nodes. Anything you can render in a div is a node; handles are measured where they are really drawn, so an edge follows a handle you moved with CSS.
  • An API you already know. React Flow's names for components, hooks, props, class names, data-testids and types — all 210 of its exports, and every one of the 302 members of the props, instance and components you write against does something (the audit counts a name that compiles and does nothing apart, and there are none) — measured from its own type declarations, with a migration guide. <ReactFlow> has React Flow's defaults, so moving from React Flow is changing an import.
  • The "pro" extras, free. Undo/redo, copy and paste, snap guides, export, smart edges, flowchart shapes and a collapsible tree, each its own entry point (flowinger/history…), so they cost the core nothing unless you import them.
  • Server rendering that works. Renders and hydrates on React 18 and 19, with the first paint already framed.
  • Accessible when you ask. Keyboard navigation, focusable nodes and edges, ARIA fields — opt-in, so a page that only shows a diagram does not gain tab stops it did not want.
  • Tested against the real thing. More than 1,000 unit tests (React Flow itself is the oracle for geometry and behaviour), mutation-tested guards, a real-browser suite, and CI that installs the packed package.

At a glance: Flowinger and React Flow

| | Flowinger | React Flow (@xyflow/react 12) | |---|---|---| | Runtime dependencies | 0 | 3 direct (@xyflow/system, zustand, classcat), plus d3-zoom, d3-drag, d3-selection… through @xyflow/system | | Stylesheet to import | None (CSS variables) | @xyflow/react/dist/style.css | | Diagram chunk in a real app (QueryLens) | 19.0 kB gzipped | 60.5 kB gzipped | | Mount 10,000 nodes (benchmarks) | 0.6 s | 1.2 s | | Mount 10,000 nodes, culled | 55 ms | 594 ms | | Pan / zoom 10,000 nodes, no culling | 8.5 / 10.7 ms a frame | 32.6 / 33.0 ms a frame | | Pan / zoom 10,000 nodes, culled | 3.6 / 2.5 ms a frame | 4.2 / 4.7 ms a frame | | Drag at 10,000 nodes, culled | 4.0 ms a move | 4.8 ms a move | | Undo/redo, copy-paste, snap lines, export, smart edges | Free, separate entry points | React Flow Pro examples (paid subscription) | | API | React Flow's names: 210 of 210 exports, 119 of 119 props | — | | Ecosystem, examples, answers online | Small and new | Large and mature |

The culled pan is level within the noise (React Flow's read 2.6–4.2 ms across runs); the zoom is about half React Flow's cost, and a culled mount a tenth, because Flowinger's first render is culled too. Where React Flow is still ahead is the last row: its ecosystem.

Install

npm install flowinger      # or: pnpm add flowinger · yarn add flowinger

React 18 or 19 is a peer dependency. The package ships ESM, CommonJS and TypeScript declarations for both.

Quick start

import {
  Background, Controls, FlowingerCanvas, FlowingerProvider, Handle, Position,
  type Edge, type Node, type NodeProps,
} from 'flowinger';

function Step({ data }: NodeProps) {
  return (
    <div className="step">
      <Handle id="in" type="target" position={Position.Top} />
      {String(data.label)}
      <Handle id="out" type="source" position={Position.Bottom} />
    </div>
  );
}

// Defined outside the component, so they keep their identity between renders.
const nodeTypes = { step: Step };
const nodes: Node[] = [
  { id: 'a', type: 'step', position: { x: 0, y: 0 }, data: { label: 'Scan' } },
  { id: 'b', type: 'step', position: { x: 0, y: 120 }, data: { label: 'Filter' } },
];
const edges: Edge[] = [
  { id: 'a-b', source: 'a', target: 'b', sourceHandle: 'out', targetHandle: 'in', markerEnd: 'arrowclosed' },
];

export function Diagram() {
  return (
    // The canvas fills its parent, so the parent needs a height.
    <div style={{ position: 'relative', height: 400 }}>
      <FlowingerProvider>
        <FlowingerCanvas nodes={nodes} edges={edges} nodeTypes={nodeTypes}>
          <Background />
        </FlowingerCanvas>
        <Controls style={{ position: 'absolute', right: 12, bottom: 12 }} />
      </FlowingerProvider>
    </div>
  );
}

That draws a diagram you can pan and zoom. On <FlowingerCanvas> nothing is draggable, connectable or selectable until you say so — a viewer wants none of it — so an editor opts in. (<ReactFlow> has React Flow's defaults, with those on; {...reactFlowDefaults} gives them to any canvas.)

const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);

<FlowingerCanvas
  nodes={nodes}
  edges={edges}
  onNodesChange={onNodesChange}
  onEdgesChange={onEdgesChange}
  onConnect={(connection) => setEdges((current) => addEdge(connection, current))}
  nodesDraggable
  nodesConnectable
  elementsSelectable
/>

More in Getting started, or run the examples.

Pay for what you use

FlowingerCanvas (also exported as ReactFlow) has every feature and is what most apps want. An app that only shows a graph needs far less, so the canvas is a small core plus features, and you import the ones you use:

import { FlowingerCore, connectFeature, dragFeature } from 'flowinger';

<FlowingerCore
  nodes={nodes} edges={edges}
  features={[dragFeature, connectFeature]}
  nodesDraggable nodesConnectable
/>

| Build | Gzipped | |---|---| | FlowingerCore, no features | about 19.9 kB | | …plus each feature you name | only its own code | | FlowingerCanvas, every feature | about 37 kB |

Both are held by budgets in CI, measured on a small consumer's real bundle. A prop for a feature the canvas lacks does nothing — and in development the console says so. See Features.

Documentation

| | | |---|---| | Getting started | Install, a first diagram, making it interactive, and the first things that trip people | | API reference | Canvas props, nodes and edges, handles, sub-flows, the instance, controlled flows | | Components and hooks | Handle, Background, Controls, MiniMap, NodeToolbar, NodeResizer, useReactFlow… | | Features | What each feature adds, what needs it, and how to write your own | | The "pro" modules | Undo/redo, copy and paste, snap guides, export, smart edges, shapes, a collapsible tree | | Theming | The --flowinger-* CSS variables | | Server rendering | What renders on the server and what waits for the client | | Migrating from React Flow | Defaults, types, what is missing and what to do instead | | React Flow coverage | How much of its API this covers, measured | | Benchmarks | Mount, pan, zoom and drag against React Flow at 1,000–10,000 nodes, and how to re-run them |

Examples

Each is a complete Vite + React + TypeScript project you can copy out and run, and CI builds each one against the packed library on every pull request. To try one in the browser with nothing installed, open it in StackBlitz: layouts · editor · export · presence · save-load · stepper · swimlanes · tree · Next.js.

Is it for you?

Reach for Flowinger when your app draws a graph — a query plan, a syntax tree, a dependency map, a workflow — and what it costs matters: the bundle, the dependencies, the markup.

Reach for React Flow instead when you need something on the missing list and cannot wait for it, or you want its larger ecosystem of examples, templates and answers. Flowinger is not a drop-in for all of React Flow, and does not try to be: it covers the part of the API that apps like the one above use, and says plainly where it stops.

Neither library lays a graph out for you. Feed x / y from d3-hierarchy, dagre or elkjs — the layouts example does all three.

Compatibility

| | | |---|---| | React | 18 and 19, both tested in CI | | Modules | ESM and CommonJS, with TypeScript declarations for each (checked with publint and Are the Types Wrong) | | Rendering | Client, server and hydration (react-dom/server) | | Browsers | Current evergreen browsers — pointer events, ResizeObserver. The browser suite runs in Chromium, Firefox and WebKit; two-finger touch pinch is unit-tested but not yet seen on a physical device (roadmap) |

Contributing

Bug reports, a repro of something React Flow does differently, layout recipes and examples are all welcome. Start with CONTRIBUTING.md — it says what fits, what "done" means here, and how to run everything:

pnpm install
pnpm dev                 # the demo
pnpm test                # unit tests
pnpm e2e                 # the real-browser suite (Playwright)
pnpm check:package       # publint + Are the Types Wrong on the packed tarball

By taking part you agree to the Code of Conduct. Security issues go to SECURITY.md, not a public issue. plan.md is the design record: what was built, what was measured, and what was tried and dropped.

Acknowledgements

Flowinger's API follows React Flow by xyflow, and was built to match its behaviour — by running it, reading its published types, and using it as a test oracle. A few formulas (the bezier control points and where a label sits on the curve) are adapted from it under its MIT licence and credited in NOTICE.md.

License

MIT © Naveen Boddepalli