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

@mp70/react-networks

v0.9.102

Published

React components for network diagrams using React Flow

Readme

@mp70/react-networks

npm version license TypeScript

A React library for creating interactive network diagrams with support for rack management, fibre networks, and power distribution. Built on React Flow (@xyflow/react v12) with TypeScript support.

Features

  • Rack Management: Full support for 19" rack units with exact U positioning
  • Device Placement: Drag and drop devices with automatic U position snapping
  • Fibre Networks: Visual representation of fibre connections and patch panels
  • Power Distribution: Vertical PDU support with power connections
  • Face Switching: Front/rear face switching for devices and racks
  • Device Images: Front/rear device images supported (PNG, SVG, JPEG, etc.) via frontImageUrl / rearImageUrl (https://, blob:, data:image/*, or relative URLs)
  • Rack Alignment: Align rack bottoms to the same horizontal plane
  • Data Integration: Built-in converters for generic inventory/CMDB data and NetBox, on server-safe subpath entries
  • Server-safe model entry: Import the data model, adapters, and handle-id grammar in Node/SSR without pulling in React or React Flow
  • Customizable: --rn-* CSS custom properties and theme class hooks
  • Responsive: Works on desktop and mobile devices
  • TypeScript: Full TypeScript support with comprehensive type definitions

Quick Start

Installation

Install the library and its peer dependencies:

npm install @mp70/react-networks react react-dom @xyflow/react @xyflow/system
# or
yarn add @mp70/react-networks react react-dom @xyflow/react @xyflow/system
# or
pnpm add @mp70/react-networks react react-dom @xyflow/react @xyflow/system

Peer dependencies

@mp70/react-networks renders on React Flow v12 (@xyflow/react), not the legacy reactflow v11 package. The required peers are:

| Peer | Range | Notes | | --- | --- | --- | | react | ^18 \|\| ^19 | | | react-dom | ^18 \|\| ^19 | | | @xyflow/react | ^12 | The React Flow v12 engine. Do not install the old reactflow package. | | @xyflow/system | 0.0.x | Required transitively by the type surface; install it explicitly. |

You must import two stylesheets — React Flow's own base styles and this library's styles — or the diagram renders unstyled:

import '@xyflow/react/dist/style.css';
import '@mp70/react-networks/index.css';

The library's CSS is emitted as a standalone file (it is not injected by importing the JS entry), so the @mp70/react-networks/index.css import is required, not optional.

Basic Usage

import React from 'react';
import '@xyflow/react/dist/style.css';
import '@mp70/react-networks/index.css';
import { NetworkDiagram } from '@mp70/react-networks';
import type { NetworkNode, NetworkEdge } from '@mp70/react-networks';

const nodes: NetworkNode[] = [
  {
    id: 'rack-1',
    type: 'rack',
    position: { x: 100, y: 100 },
    data: {
      label: 'Main Rack',
      uHeight: 42
    }
  },
  {
    id: 'server-1',
    type: 'server',
    position: { x: 120, y: 150 },
    data: {
      label: 'Web Server',
      uPosition: 1,
      ports: [
        { id: 'eth0', label: 'eth0', group: 'Network Ports', connected: true, type: 'ethernet' },
        { id: 'eth1', label: 'eth1', group: 'Network Ports', connected: false, type: 'ethernet' }
      ]
    }
  }
];

const edges: NetworkEdge[] = [];

function App() {
  return (
    <div style={{ width: '100vw', height: '100vh' }}>
      <NetworkDiagram
        nodes={nodes}
        edges={edges}
        alignRacksToBottom={true}
        onNodeClick={(node) => console.log('Node clicked:', node)}
        onEdgeClick={(edge) => console.log('Edge clicked:', edge)}
      />
    </div>
  );
}

export default App;

Entry points

The package ships four entry points. Import from the narrowest one that fits — the subpaths below . are server-safe and pull in zero React/React Flow runtime code, so Node scripts, SSR, and API routes can use them without the canvas stack.

| Import | What it is | Server-safe | | --- | --- | --- | | @mp70/react-networks (.) | The React components (NetworkDiagram, FibreFlowMap, DiagramErrorBoundary), plus the diagram utilities, hooks, and types. | No — pulls React + React Flow. | | @mp70/react-networks/model | The pure data model: core types, the handle-id grammar, port-contract, port-position, document adapters, path-layout, and the fibre connection policy. | Yes — zero React/React Flow at runtime. | | @mp70/react-networks/netbox | NetBox → diagram converters (netboxToDiagramDocument, netboxToNetworkDiagram, …) and the NetBox* DTO types. | Yes. | | @mp70/react-networks/inventory | Generic CMDB/inventory converters (inventoryToDiagramDocument, inventoryToNetworkDiagram, …) and the Inventory*DTO types. | Yes. | | @mp70/react-networks/index.css | The stylesheet (see Custom styling). | n/a |

// In a Node/SSR API route — no React, no React Flow pulled in.
import { networkGraphToDiagramDocument } from '@mp70/react-networks/model';
import { netboxToDiagramDocument } from '@mp70/react-networks/netbox';
import { inventoryToDiagramDocument } from '@mp70/react-networks/inventory';

Server-side usage

Import pure helpers and types from @mp70/react-networks/model (or /netbox / /inventory), not from the root @mp70/react-networks.

The root entry carries the 'use client' directive and pulls in React and the React Flow runtime. Server code — API routes, SSR loaders, cron jobs, migration scripts — that only needs the data model, adapters, handle-id/node-id grammar, or pure geometry should import from the server-safe /model subpath so none of the canvas stack lands in the server bundle. Everything on /model is tree-shakeable and framework-free.

// ✅ server-safe — zero React / React Flow at runtime
import {
  networkGraphToDiagramDocument,
  buildPortHandleId,
  handlesMatch,
  calculateSplicePositionFromNumber,
} from '@mp70/react-networks/model';

// ❌ in server code this drags in React + React Flow
import { networkGraphToDiagramDocument } from '@mp70/react-networks';

Enforce it with ESLint

Add a no-restricted-imports rule scoped to your server globs so a stray root import fails lint instead of bloating the server bundle. Copy-paste (flat config):

// eslint.config.js (flat config)
export default [
  {
    files: ['**/server/**', '**/api/**', '**/*.server.{ts,tsx}'],
    rules: {
      'no-restricted-imports': [
        'error',
        {
          paths: [
            {
              name: '@mp70/react-networks',
              message:
                'Server code must import from @mp70/react-networks/model (or /netbox, /inventory) — the root entry pulls in React + React Flow.',
            },
          ],
        },
      ],
    },
  },
];

The same rule in legacy .eslintrc form, an overrides variant, and a typescript-eslint note live in docs/eslint-server-imports.md.

Documentation

Data Model

@mp70/react-networks supports two control layers:

  • document / initialDocument / onDocumentChange use DiagramDocument, the canonical persisted/editor schema. Prefer this for saved diagrams, import/export, and external integrations. DiagramDocument now carries a required version: 1 discriminator (see CHANGELOG).
  • nodes / edges remain the lower-level React Flow-shaped control surface when you want direct control of rendered nodes and edges.

For device-style nodes, prefer the flat ports: DevicePort[] input. Use portGroups and rearPortGroups only when you need explicit grouped front/rear layout control.

Rendering primitives

You render diagrams through NetworkDiagram and FibreFlowMap. The individual node/edge components (rack, device, PDU, splice, tube, cable, coupler, patch panel, closure, fibre-split, fibre edge, power edge, …) are registered internally by those components and are not part of the public surface — do not mount them directly.

API Reference

Components

  • NetworkDiagram — main diagram component
  • FibreFlowMap — standalone fibre-flow diagram (closures, cables, tubes, splices, circuits)
  • DiagramErrorBoundary — error boundary for diagram errors

Utilities (selected)

Rack schema:

  • buildNodesFromRackConfig / createRackConfigFromNodes
  • addDeviceToRack / removeDeviceFromRack / updateDeviceUPosition
  • validateRackDevicePlacements

Splice schema:

  • buildNodesFromSpliceConfig / createSpliceConfigFromNodes
  • addSpliceToTray / removeSpliceFromTray / updateSpliceHolderPosition
  • validateSplicePlacements

U positioning: snapToUPosition, isUPositionAvailable, findNextAvailableUPosition, calculateDevicePositionFromU, validateAndSnapDevice

Data integration (on the server-safe subpaths — see Entry points):

  • inventoryToDiagramDocument / inventoryToNetworkDiagram (/inventory)
  • netboxToDiagramDocument / netboxToNetworkDiagram (/netbox)

Power: getPowerPortStyle, getConnectorConfig, getDeviceConnectorType, getPDUPortType, isHighPowerConnector, POWER_CONNECTORS

Fibre colours: FIBRE_COLORS_12, baseColorFor, isStriped, fibreSolidOrStriped, getFibreColor

Rack geometry: getRackBounds, isPointInRack, findNearestRack

Constants: U_HEIGHT_PX, RACK_HEADER_HEIGHT, RACK_WIDTH_PX, HANDLE_EXTENSION_PX

Status: getStatusColor

Edges: replaceEdge

Connection validation (pure functions): validateNetworkConnection, computeEdgeZIndex, createNodeMap, getHandleSide

Handle & node identity (pure; on /model): handlesMatch, findEdgesForPortHandle, encodeHandle / decodeHandle (structured Handle type), buildPortHandleId / buildFibreHandleId / buildTubeHandleId / buildSpliceHandleId (+ siblings), buildRackNodeId / buildDeviceNodeId / parseRackChildNodeId / isRackNode / isDeviceNode / getNodeKind. See API.md § Handle & node identity. sanitizeHandleIdForMatching is deprecated for matching — use handlesMatch.

Fibre scene geometry (pure; on /model): calculateSplicePositionFromNumber plus the HOLDER_HEIGHT_PX / TRAY_HEADER_HEIGHT / TRAY_* layout constants, for hand-composing closure/tray/splice scenes that line up with rendered nodes.

The full type-level surface is enforced by API Extractor reports (etc/*.api.md) generated per entry point. Those reports are the source of truth for what is public.

NetworkDiagram Props

For new code, prefer the document-model props. The graph props and React Flow escape hatches remain available for advanced integrations and compatibility with older code.

| Prop | Type | Default | Description | |------|------|---------|-------------| | document | DiagramDocument | - | Controlled canonical diagram document. Takes precedence over nodes / edges. | | initialDocument | DiagramDocument | - | Initial canonical document for uncontrolled document mode. | | onDocumentChange | (document: DiagramDocument) => void | - | Callback when the canonical document changes. | | alignRacksToBottom | boolean | false | Align rack bottoms to baseline | | onNodeClick | (node: NetworkNode \| null) => void | - | Node click / selection handler | | onEdgeClick | (edge: NetworkEdge) => void | - | Edge click handler | | onFaceChange | (nodeId: string, face: 'front' \| 'rear') => void | - | Device face change handler | | onRackFaceChange | (rackId: string, face: 'front' \| 'rear') => void | - | Rack face change handler | | className | string | - | CSS class name | | style | React.CSSProperties | - | Inline styles | | readOnly | boolean | false | Force lock diagram (no drag/connect/delete/reconnect/pan/zoom) | | interaction | NetworkDiagramInteractionOptions | - | Fine-grained interaction controls for editing, pan, zoom, minimap, and controls | | actionPanel | NetworkDiagramActionPanelOptions | - | Configure action panel (enabled, showRearToggle, showDeRack) | | nodes | NetworkNode[] | [] | Advanced: controlled lower-level graph nodes | | edges | NetworkEdge[] | [] | Advanced: controlled lower-level graph edges | | onNodesChange | (nodes: NetworkNode[]) => void | - | Advanced: callback when lower-level nodes change | | onEdgesChange | (edges: NetworkEdge[]) => void | - | Advanced: callback when lower-level edges change | | initialNodes | NetworkNode[] | - | Advanced: initial lower-level nodes | | initialEdges | NetworkEdge[] | - | Advanced: initial lower-level edges | | nodeTypes | NodeTypes | - | Custom React Flow node types | | edgeTypes | EdgeTypes | - | Custom React Flow edge types | | onConnect | (connection: Connection) => void | - | Connection handler override | | onEdgeUpdate | (oldEdge: Edge, newConnection: Connection) => void | - | Edge update (reconnect) override | | isValidConnection | (connection: Connection) => boolean | - | Connection validation override | | connectionMode | ConnectionMode | - | React Flow connection mode | | connectionRadius | number | React Flow default | Pointer snap distance (px) for handles. Raise to make small ports easier to target; lower to avoid mis-targeting on dense devices | | onConnectRejected | (payload: NetworkConnectionRejection) => void | - | Fired when a connect/reconnect attempt is rejected, so you can surface feedback instead of failing silently | | reAssignable | boolean | true | Allow devices to move between racks / ungroup on drag | | colorMode | 'light' \| 'dark' \| 'system' | - | Diagram color mode | | onInit | (instance: ReactFlowInstance) => void | - | Called when React Flow is ready | | onFlowMethods | (methods: NetworkDiagramFlowMethods) => void | - | Receive toObject/setViewport/toImage/fitView etc. | | fitViewOnInit | boolean | true | Run React Flow's fit-on-init once dimensions are measured. Pass false to keep a restored viewport. | | showDownloadButton | boolean | - | Show export image button | | downloadButtonPosition | 'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left' | - | Download button position | | useSmoothstepEdgesForTubes | boolean | false | Use smoothstep edges for tube connections | | debug | boolean | false | Enable debug mode | | fitViewOptions | FitViewOptions | - | React Flow fitView options | | highlightGroups | HighlightGroup[] | - | Declarative multi-group emphasis: colour sets of node/edge IDs and (with dimUnhighlighted) dim the rest. See Highlight groups | | highlightedNodeIds | string[] | - | Node IDs kept at full opacity when focus dimming is active | | highlightedEdgeIds | string[] | - | Edge IDs kept at full opacity when focus dimming is active | | dimUnhighlighted | boolean | false | Dim nodes/edges not in the focus ID lists | | dimOpacity | number | 0.25 | Opacity applied to dimmed elements (0-1) |

Edge highlighting

Per-edge emphasis uses NetworkEdge.data:

{
  id: 'edge-1',
  source: 'switch-1',
  target: 'server-1',
  type: 'fiber',
  data: {
    highlight: true,
    highlightColor: '#dc2626',
    highlightWidth: 5,
    label: 'Cable A',
  },
}

Diagram-level focus (trace, DRC row click):

<NetworkDiagram
  nodes={nodes}
  edges={edges}
  highlightedEdgeIds={focusedEdgeIds}
  highlightedNodeIds={focusedNodeIds}
  dimUnhighlighted
/>

For multi-severity emphasis (several colours at once, dim the rest) prefer the declarative highlightGroups prop over hand-maintaining per-edge highlight* data. Pass groups highest-severity first; when an element is in more than one group the earliest wins:

<NetworkDiagram
  nodes={nodes}
  edges={edges}
  dimUnhighlighted
  highlightGroups={[
    { edgeIds: errorEdgeIds, color: '#dc2626', width: 5, label: 'Error' },
    { edgeIds: warnEdgeIds, color: '#d97706', width: 3, label: 'Warning' },
  ]}
/>

The library does not define severity enums. Apps pick highlightColor / group color hex values. Common conventions:

| Meaning | Suggested highlightColor | |---|---| | Error | #dc2626 | | Warning | #d97706 | | Complete | #16a34a | | Installer power step | #f97316 | | Installer network step | #ef4444 |

Focus dimming survives a diagramDocumentToNetworkGraph round-trip: the exported applyDiagramFocusToNodes / applyDiagramFocusToEdges helpers write opacity to node/edge style and, for edges, to data.opacity as well, so a dimmed edge stays dimmed after conversion. Use the library helpers rather than app-local copies.

Pass showDeviceImages={false} on NetworkDiagram to hide rack photos; status border colors from getStatusColor(status) still apply. Use onPortClick and highlightedPortHandles for port trace UX.

NetworkNode Types

type NetworkNodeType =
  | 'rack'
  | 'switch'
  | 'router'
  | 'server'
  | 'fiber'
  | 'patch-panel'
  | 'device'
  | 'vertical-pdu'
  | 'splice'
  | 'splice-tray'
  | 'tube'
  | 'cable'
  | 'multi-tube-cable'
  | 'coupler'
  | 'closure'
  | 'fibre-split'
  | 'fibre-flow-cable'
  | 'fibre-flow-closure';

Note: the 'fiber' node-type string and edge-data keys such as fiberId / ribbonFiberIds are serialized wire values and are deliberately unchanged by the FiberFibre symbol rename (see CHANGELOG).

NetworkEdge Types

type NetworkEdgeType = 'fiber' | 'ethernet' | 'power' | 'smoothstep' | 'step' | 'thick-cable' | 'fibre-flow' | 'fibre-flow-link';

Advanced Usage

Rack Configuration

import { RackConfig, buildNodesFromRackConfig, Width } from '@mp70/react-networks';

const rackSchema: RackConfig[] = [
  {
    id: 'rack-1',
    name: 'Main Rack',
    position: { x: 100, y: 100 },
    units: 42,
    devices: [
      {
        id: 'server-1',
        name: 'Web Server',
        unit: 1,
        height: 1,
        type: 'server',
        width: Width.FULL,
        ports: [
          { id: 'eth0', label: 'eth0', group: 'Network Ports', connected: true, type: 'ethernet' },
          { id: 'eth1', label: 'eth1', group: 'Network Ports', connected: false, type: 'ethernet' }
        ]
      },
      {
        id: 'switch-1',
        name: 'Core Switch',
        unit: 3,
        height: 1,
        type: 'switch',
        width: Width.FULL,
        ports: [
          { id: 'port-1', label: 'port-1', group: 'Uplink Ports', connected: true, type: 'fiber' },
          { id: 'port-2', label: 'port-2', group: 'Uplink Ports', connected: false, type: 'fiber' }
        ]
      }
    ]
  }
];

const nodes = buildNodesFromRackConfig(rackSchema);

For the simplest device API, pass a flat ports: DevicePort[] array and set group / face per port. Use portGroups and rearPortGroups only when you need explicit grouped front/rear control.

Device images (e.g. server front/rear photos or SVGs) use frontImageUrl and rearImageUrl on each device; supported formats include PNG, SVG, JPEG, GIF, and WebP.

Inventory Integration

The inventory and NetBox converters live on server-safe subpaths, so you can run them in a Node/SSR import pipeline without loading React or React Flow:

import { inventoryToNetworkDiagram } from '@mp70/react-networks/inventory';

const inventoryData = {
  racks: [...],
  devices: [...],
  cables: [...]
};

const { nodes, edges } = inventoryToNetworkDiagram(inventoryData);

To produce the canonical persisted document instead, use inventoryToDiagramDocument (or netboxToDiagramDocument from @mp70/react-networks/netbox).

Custom styling

The stylesheet is emitted as a separate file (it is not injected by importing the JS entry), so a consumer must import it once, alongside React Flow's own stylesheet:

import '@xyflow/react/dist/style.css';
import '@mp70/react-networks/index.css';

Without both imports the diagram renders unstyled.

Theming

The supported theming API is (1) two theme class hooks you place on a wrapper element and (2) a set of --rn-* CSS custom properties. These names are stable and covered by semver from 1.0 onward; nothing else in the stylesheet is a public contract.

Theme classes

| Class | Purpose | | --- | --- | | react-flow-dark | Selects the dark palette for the canvas, controls, and minimap. | | react-flow-light | Selects the light palette. | | react-networks-attribution | Hook for styling the attribution badge. |

Apply react-flow-dark or react-flow-light to an ancestor of the diagram to switch palettes; each class sets the --rn-flow-* variables below.

:root override points

These variables have a built-in fallback and are not written as inline styles by the components, so a plain :root (or scoped) override takes effect:

/* Canvas / controls / minimap palette (set by the theme classes; override to
   retint). */
.react-flow-dark,
.react-flow-light {
  --rn-flow-background: #1a1a1a;
  --rn-flow-text: #ffffff;
  --rn-flow-border: #404040;
  --rn-flow-controls-bg: #2d2d2d;
  --rn-flow-controls-border: #404040;
  --rn-flow-minimap-bg: #2d2d2d;
  --rn-flow-minimap-border: #404040;
}

/* Device node base colours (override to restyle). */
:root {
  --rn-device-bg-color: #1f2937;
  --rn-device-text-color: white;
}

Set by the components — not :root override points

The following variables are written unconditionally as inline styles by the components (per device, per edge, or per handle) from node/edge data. An inline custom property shadows any :root declaration, so overriding these in a :root block has no effect — style the source data (device status, images, edge highlight*, etc.) or target the elements directly instead:

| Variable(s) | Set by | Driven from | | --- | --- | --- | | --rn-device-bg-image, --rn-device-bg-position, --rn-device-bg-repeat, --rn-device-bg-size | Device node | frontImageUrl / rearImageUrl + imageFit/imagePosition/imageRepeat | | --rn-device-border-color, --rn-device-status-color | Device node | getStatusColor(status) | | --rn-device-box-shadow | Device node | selection state | | --rn-edge-highlight-from, --rn-edge-highlight-to | Edge components | per-edge highlight stroke width | | --rn-hit-expand-top / -right / -bottom / -left | Device node handles | per-port hit-area expansion | | --rn-fibre-bg, --rn-fibre-bg-image | Fibre/tube handles | per-handle cable/tube fibre colour |

Performance

  • Large canvases: enable onlyRenderVisibleElements. React Flow viewport culling keeps multi-rack floor and ODF-scale surfaces responsive. It is safe to leave on for image export — the library force-disables culling for the duration of a toImage render so off-screen nodes still appear in the PNG, then restores the setting (see Export-safe culling). Leave it off for a single-rack editor, where everything is on-screen anyway.
  • Document-mode drag cost is memoized. When you drive NetworkDiagram with document / onDocumentChange, endpoint derivation is WeakMap-memoized on node.data identity, so a position-only change during a drag frame skips re-deriving (and deep-cloning) ports. If your host already holds NetworkNode[] / NetworkEdge[], you can also render nodes / edges with onNodesChange directly and skip the document round-trip entirely.

Public API & stability

From 1.0 the following are the public, semver-covered surface:

  • JavaScript / TypeScript exports of the four entry points: . (components + diagram utilities), ./model, ./netbox, and ./inventory. What each exports is pinned by committed API Extractor reports (etc/*.api.md).
  • CSS hooks: the --rn-* custom properties and the react-flow-dark, react-flow-light, and react-networks-attribution class names.
  • Handle-id strings are a frozen wire format (used inside React Flow handles). Build/parse them only through the handle-id grammar exports (buildPortHandleId, parseHandleId, encodeHandle / decodeHandle, …); do not hand-construct or hand-parse them. To test whether two handle strings denote the same handle, use handlesMatch (or findEdgesForPortHandle for the edge lookup); sanitizeHandleIdForMatching is deprecated for matching, intentionally many-to-one, and must never be persisted. For persisted identity, reference DiagramEndpoint.id (an opaque, relabel-stable key) — the handle string is derived from the endpoint at the rendering boundary, so persist the endpoint id, not the handle.

Anything not listed above (internal node/edge components, other CSS selectors, DOM structure) is an implementation detail and may change without a major bump.

Development

Prerequisites

  • Node.js 22+
  • npm, yarn, or pnpm

Setup

# Clone the repository, then:
cd react-networks/packages/network-diagrams
npm install

Build

npm run build

Development

npm run dev

Testing

npm test

Linting

npm run lint

Distribution

The library is distributed as:

  • ES Modules: dist/index.mjs
  • CommonJS: dist/index.js
  • TypeScript: dist/index.d.ts (and .d.mts for ESM)
  • CSS: dist/index.css (imported via @mp70/react-networks/index.css)

Server-safe subpath entries (./model, ./netbox, ./inventory) ship the same .mjs / .js / .d.mts / .d.ts set.

Contributing

We welcome contributions! See CONTRIBUTING.md for details.

Development Workflow

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Run the test suite
  6. Submit a pull request

License

Dual-licensed under:

  • AGPL-3.0-only (Free) - For open source, personal, and educational use. Copyleft applies.
  • Commercial (LicenseRef-Commercial) - For proprietary/commercial use without copyleft obligations.

The SPDX license expression is AGPL-3.0-only OR LicenseRef-Commercial. See ../../LICENSE for details. By installing, you agree to use under either license.

Acknowledgments

  • React Flow for the diagram foundation

Made by matt from rackout.net.