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

@statelyai/flow-react

v0.6.0

Published

Thin React adapter for @statelyai/flow with core and DOM re-exports.

Readme

@statelyai/flow-react

Thin React adapter for @statelyai/flow with core and DOM re-exports.

Philosophy

@statelyai/flow-react should be completely event-driven and composable. React should not hide a second flow model behind component internals; it should adapt the same FlowInstance that consumers can create, inspect, subscribe to, and trigger directly. It re-exports the lower layers so React consumers can install and import from one package.

The adapter abstracts over two lower layers:

  • @statelyai/flow owns the graph, viewport, selection, interaction state, semantic events, and derived engine queries.
  • @statelyai/flow-dom owns browser-only measurement and container attachment.

The React package owns React lifecycle, context, selector subscriptions, and a convenience renderer. It should be flexible enough for consumers to build their own stateful flow component from the instance alone.

Optimization is part of the architecture, not a later cleanup pass. Components should subscribe only to the data they actually render or use for derived work. For example, an edge layer should not subscribe to the entire store when it only needs edges, viewport, edge-path inputs, and selected edge ids.

The graph data structure is the source of truth for graph content, not for transient UI state. Core node and edge data should not grow flags like selected: true or dragging: true; selection, focus, dragging, hover, connection state, and similar interaction state live in the flow store and are derived into render props such as selected or dragging.

DOM measurement is one-directional by default. Nodes, ports, and edge labels report their inherent rendered size back to the engine, but default renderers should not apply measured width or height back onto the same DOM entities. Consumers can opt into controlled sizing for custom components, but the built-in DOM path should avoid measurement feedback loops.

Core API

| Export | Description | | ------------------------------------- | -------------------------------------------------------------------------------- | | createFlowInstance(options) | Creates the shared instance used by React and custom renderers | | useFlow(options) | TipTap-style hook for creating a stable flow controller | | useCreateFlowInstance(options) | React lifecycle hook for creating an instance and attaching listeners | | useFlowSelector(selector, options?) | Subscribe to any part of the flow store from React | | useFlowValue(selector, isEqual?) | Short selector hook for the nearest provider | | useFlowContext() | Subscribe to the full flow store context | | useFlowNode(id, selector?, isEqual?) | Subscribe to node data plus derived render fields | | useFlowEdge(id, selector?, isEqual?) | Subscribe to edge data plus derived render fields | | useFlowPort(id, selector?, isEqual?) | Subscribe to port data plus derived render fields | | useFlowViewport() | Subscribe to viewport state | | useFlowMeasurement(id) | Subscribe to measured bounds for an addressable | | FlowInstanceProvider | Provides a FlowInstance through React context | | useFlowInstance() | Reads the nearest FlowInstance | | useOptionalFlowInstance() | Reads the nearest FlowInstance or returns null | | StatelyFlow | Convenience component that renders nodes, edges, backgrounds, and overlays | | FlowColorModeScope | Applies the current flow color mode as DOM data attributes and color-scheme | | useFlowColorMode() | Reads the store color mode and resolves system to light or dark | | useApplyFlowColorMode(element) | Applies flow color mode attributes to an existing DOM element from inside a flow |

@statelyai/flow-react/backgrounds exports Background, DotsBackground, LinesBackground, and CrossBackground helpers for viewport-aware canvas backgrounds. Backgrounds are plain React components, so consumers can also build custom ones with useFlowSelector((context) => context.viewport).

Color mode is store data, not engine behavior. @statelyai/flow-dom exports small helpers for resolving and applying light, dark, and system, while React exposes hooks/components that make those values easy to use with CSS variables.

Usage

import {
  createEdge,
  createGraph,
  createNode,
  StatelyFlow,
  useFlow,
  useFlowSelector,
} from "@statelyai/flow-react";

const graph = createGraph({
  nodes: [
    createNode({ id: "a", x: 0, y: 0, data: { label: "Start" } }),
    createNode({ id: "b", x: 240, y: 120, data: { label: "Done" } }),
  ],
  edges: [createEdge({ id: "a-b", sourceId: "a", targetId: "b" })],
});

function Flow() {
  const flow = useFlow({
    graph,
    settings: {
      store: { snapToGrid: true, snapGrid: [16, 16] },
    },
    listeners: [
      {
        selector: (context) => context.selection.size,
        onChange: (selectionSize) => {
          console.log("selection size", selectionSize);
        },
      },
    ],
  });

  return (
    <StatelyFlow
      flow={flow}
      graph={graph}
      renderNode={({ node, selected }) => (
        <div data-selected={selected}>{node.data?.label ?? node.id}</div>
      )}
    />
  );
}

Storybook

pnpm --filter @statelyai/flow-react storybook