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

@polygonschmied/stellar-nodes

v0.2.5

Published

Stellar DS node-editor — controlled React Flow canvas with the Stellar skin (Paper-body nodes, Clay handles, inline controls).

Readme

@polygonschmied/stellar-nodes

A controlled node-graph editor on React Flow wrapped in the Stellar skin for Stellar DS — Paper-body nodes, Clay handles, Theater connection wires, and controlled inline controls so the canvas works as a steering surface.

React owns the graph: nodes and edges are props, every canvas interaction (select, move, connect, delete, rename) flows back out through change streams and semantic callbacks.

Install

pnpm add @polygonschmied/stellar-nodes @polygonschmied/stellar-tokens

Peer dependencies: react >= 18, react-dom >= 18. @xyflow/react ships as a direct dependency, and the package imports @xyflow/react/dist/base.css for you — your build needs a bundler that handles CSS imports (Vite, Next.js, etc.; the same constraint @polygonschmied/stellar-core already imposes).

Quick start

import "@polygonschmied/stellar-tokens/styles.css";
import {
  NodeEditor,
  StellarNodeShell,
  NodeSlider,
  useNodesState,
  useEdgesState,
  addEdge,
  type NodeTypes,
  type StellarNodeProps,
} from "@polygonschmied/stellar-nodes";

function AgentNode(props: StellarNodeProps) {
  return (
    <StellarNodeShell
      id={props.id}
      selected={props.selected}
      label={props.data.label}
      subtitle={props.data.subtitle}
      badge={props.data.badge}
      state={props.data.state}
      inputs={[{ id: "in", label: "in" }]}
      outputs={[{ id: "handoff", label: "handoff" }]}
    >
      {/* controlled inline controls — see below */}
    </StellarNodeShell>
  );
}

const nodeTypes: NodeTypes = { agent: AgentNode };

export function TeamGraph() {
  const [nodes, , onNodesChange] = useNodesState([
    { id: "a", type: "agent", position: { x: 0, y: 0 }, data: { label: "Orchestrator" } },
    { id: "b", type: "agent", position: { x: 320, y: 0 }, data: { label: "Researcher" } },
  ]);
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);

  return (
    <div style={{ width: 800, height: 500 }}>
      <NodeEditor
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        nodeTypes={nodeTypes}
        onConnectionCreated={(conn) => setEdges((e) => addEdge(conn, e))}
        fitView
      />
    </div>
  );
}

Node types

Register node renderers via nodeTypes and compose them from StellarNodeShell: header (icon, title + subtitle, badge, accent rail), body slot, footer slot, and labeled pins (inputs render left target handles, outputs right source handles).

Appearance rules:

  • Per type (icon, accent, which controls render) lives in the node-type component.
  • Per instance/state (label, subtitle, badge, state) lives in node.data and stays serializable — no callbacks in data.
  • state maps to modifiers: entry (accent rail), disabled (muted, disable your controls too), error (crimson rail + header tint).

Inline controls

NodeSelect, NodeCheckbox, NodeSlider, NodeTextInput are compact, strictly controlled form elements for node bodies (all nodrag, the slider also nowheel). Close over an updater so React stays the state owner:

<NodeSlider
  label="Budget (k tokens)"
  value={data.budget}
  min={0}
  max={500}
  step={25}
  showValue
  onChange={(budget) => patchNodeData(props.id, { budget })}
/>

Inline rename

Pass onLabelChange to enable double-click rename on node titles. Enter or blur commits, Escape cancels; the commit arrives as (nodeId, label) and you write it into node.data.label — the shell only holds the transient draft.

Events

| Prop | Fires when | | --------------------- | --------------------------------------------- | | onNodesChange | Any node change (move/select/remove stream) | | onEdgesChange | Any edge change | | onNodeSelect | Selection changed ([] on deselect) | | onNodeDoubleClick | Node double-clicked (title dblclick renames) | | onNodeMoved | Drag ended (final position on the node) | | onConnectionCreated | User drew a connection (accept via addEdge) | | onConnectionRemoved | Edges removed | | onNodeRemoved | Nodes removed | | onLabelChange | Inline rename committed |

Helpers you'd otherwise import from @xyflow/react are re-exported: applyNodeChanges, applyEdgeChanges, addEdge, useNodesState, useEdgesState, Position, plus the Node/Edge/NodeChange/… types.

Testing

The editor runs in jsdom. Shim ResizeObserver (callback-invoking, with contentRect), DOMMatrixReadOnly, offsetWidth/offsetHeight and SVGElement.getBBox — see vitest.setup.ts in this package for a working reference. Nodes carry data-testid="stl-node-<id>".

License

MIT — see the repo README for the wider picture.