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

@zenode/designer

v3.5.10

Published

A high-performance, pro-grade diagramming engine for web-based design tools.

Downloads

1,092

Readme

Zenode Designer

A high-performance, D3.js-powered visual workflow canvas for JavaScript.
Engineering-first · JSON-schema-driven · Framework-agnostic · Performance-tuned

npm version License: MIT GitHub Stars TypeScript

Live Demo → · API Documentation → · Report Bug →


@zenode/designer is Layer 1 of the Zenode ecosystem — the visual canvas that powers everything. Drop it into any JavaScript project (React, Vue, Svelte, or vanilla) and get a production-grade diagramming engine with zero lock-in.


Key Capabilities

  • D3-Native Performance: Leverages the power of D3.js for fine-grained SVG control, ensuring thousands of nodes run smoothly at 60fps.
  • Infinite Canvas: A truly unrestricted panning and zooming environment with a synced SVG pattern grid.
  • Generic History Engine: Robust undo/redo system based on the Command pattern, capturing full state snapshots for perfect restoration.
  • Smart Selection: Integrated single-select, lasso multi-select, and renderer-aware selection overlays.
  • Extensible Context Pad: A floating HTML action bar that follows your selection, fully customizable via a simple registration API.
  • Visual Grouping: Encapsulate multiple nodes within collective boundaries with synced movement and ghost previews.
  • Visual Effects Suite: Built-in support for status glows, stroke-flow animations, and progress gradients.

The Zenode Ecosystem

Zenode is built as a modular four-layer system. You can adopt one package for a specific need or use the entire stack for a complete workflow solution.

| Layer | Package | Role | |---|---|---| | Layer 1 | @zenode/designer | Visual Canvas: Shapes, connections, and user interaction (This Package). | | Layer 2 | @zenode/serializer | Data Exchange: High-fidelity export/import (JSON, BPMN 2.0, Mermaid). | | Layer 3 | @zenode/runtime | Execution: Converts diagrams into executable JavaScript workflows. | | Layer 4 | @zenode/transformer | Output Shaping: User-defined data mapping from execution results. |


Quick Start

Installation

npm install @zenode/designer

Initialization

<div id="canvasContainer" style="width: 100vw; height: 100vh;"></div>

<script type="module">
  import * as Zenode from '@zenode/designer';

  // Initialize with optional configuration
  const engine = Zenode.initializeCanvas('#canvasContainer', {
    canvas: { backgroundColor: '#f8fafc' },
    canvasProperties: {
      snapToGrid: true,
      zoomEnabled: true
    }
  });

  // Create shapes programmatically
  Zenode.createShape('rectangle', 'start-node');
</script>

Core Architecture

The ShapeRenderer Contract

Zenode uses a unique renderer contract. Every shape — whether built-in or custom — must implement this interface. This ensures that features like selection rings, ports, and alignment guides work perfectly across any geometry.

export interface ShapeRenderer {
  draw:      (g: D3Selection, config: ResolvedShapeConfig) => void;
  getPath:   (config: ResolvedShapeConfig) => string;     // Exact SVG path data
  getBounds: (config: ResolvedShapeConfig) => BoundingBox; // Collision/Selection box
  getPorts:  (config: ResolvedShapeConfig) => PortMap;    // Connection anchors
}

D3 Layer Stack

Layers are strictly ordered to ensure predictable depth management and event bubbling:

  1. g.grid — The infinite background pattern.
  2. g.connections — The link/edge layer.
  3. g.placed-nodes — The primary interactive shapes.
  4. g.preview — Ghost previews (pointer-events: none).
  5. g.guides — Alignment assistants.
  6. g.lasso — Box selection overlay.

Roadmap

| Component | Status | Progress | |---|---|---| | Core Interaction | ✅ | Drag, Snap, Lasso, Zoom/Pan complete | | Connection Engine | ✅ | Straight, Curved, S-Shape, L-Bent routing | | History System | ✅ | Full Undo/Redo command pattern | | Context Pad | ✅ | Floating actions & Plugin API | | Visual Grouping | ✅ | Boundary containers & collective movement | | BPMN Parity | 🔨 | Resize handles & lane support in progress | | Serialization | ✅ | Mermaid, XML, DOT & JSON support | | Properties | 🔨 | Schema-driven node panels (Layer 1) |


Why Zenode?

| Feature | React Flow | BPMN.js | Zenode | |---|---|---|---| | Agnostic | ❌ (React only) | ✅ | ✅ (Any Framework) | | SVG Control | Limited | High | Absolute | | Visual Effects | Manual | CSS only | Built-in (Glow/Animate) | | Execution | ❌ | ❌ | ✅ (via Layer 3) | | Plugin-first | ⚠️ | ❌ | ✅ |

🛠 API Reference

The Zenode Engine is a high-performance, D3.js-powered diagramming library. This reference documented the Layer 1 (Core) APIs available for node management, viewport control, and data serialization.

1. Core Lifecycle & Configuration

| API | Description | Usage Example | |---|---|---| | initializeCanvas(selector, config) | Starts the engine in the target DOM element. | Zenode.initializeCanvas('#canvas', { ... }) | | updateConfig(config) | Dynamically updates engine settings. | Zenode.updateConfig({ grid: { visible: false } }) | | getDiagramState() | Returns a JSON snapshot of nodes, edges, and viewport. | const state = Zenode.getDiagramState() | | clear() | Wipes all nodes and edges from the workspace. | Zenode.clear() | | reset() | Clears everything and resets zoom/pan to defaults. | Zenode.reset() | | zoomTo(scale, ms?) | Sets absolute zoom level (e.g. 1.0 = 100%). | engine.zoomTo(0.8) | | panTo(x, y, ms?) | Centers the view on a specific coordinate. | engine.panTo(200, 300) | | fitToScreen(ms?) | Autcalculated zoom/pan to show all objects. | engine.fitToScreen(800) |

2. Node & Edge Management

| API | Description | Usage Example | |---|---|---| | addNode(config) | Adds a node. Returns the generated or provided ID. | const id = Zenode.addNode({ type: 'rectangle', ... }) | | removeNode(id) | Deletes a node and its connections. | Zenode.removeNode('n1') | | updateNode(id, patch) | Updates node data (position, meta). | Zenode.updateNode('n1', { x: 200 }) | | addEdge(config) | Creates a connection. Supports type override. | Zenode.addEdge({ ..., type: 's-shaped' }) | | duplicateNode(id) | Clones a node and its content. | const newId = Zenode.duplicateNode('n1') | | focusNode(id, opts?) | Animates the viewport to focus on a node. | Zenode.focusNode('n1', { zoom: 1.5 }) | | groupSelection() | Encapsulates the current selection within a visual group. | Zenode.groupSelection() | | ungroupSelection() | Break apart active selection or selected group. | Zenode.ungroupSelection() | | toggleGroupingSelection()| Smart toggle grouping logic. | Zenode.toggleGroupingSelection() | | getVisualGroups() | Returns array of all active visual groups. | Zenode.getVisualGroups() |

3. Data Serialization & Export

| API | Description | Usage Example | |---|---|---| | toXML() | Exports current state as a Zenode XML string. | const xml = Zenode.toXML() | | fromXML(xmlString) | Restores the canvas from a Zenode XML string. | Zenode.fromXML(myXml) | | toMermaid() | Generates a Mermaid.js flowchart script. | console.log(Zenode.toMermaid()) | | toDOT() | Generates a Graphviz/DOT language script. | const dot = Zenode.toDOT() | | validate() | Runs structural validation (cycles, orphans). | const result = Zenode.validate() |

4. Visual Feedback & Status

| API | Description | Usage Example | |---|---|---| | setNodeStatus(id, type) | Triggers visual cues (running, success, error). | engine.setNodeStatus('n1', 'error') | | updateNodeContent(id, cnt) | Sets text, icons, and layout for a node. | Zenode.updateNodeContent('n1', { items: [...] }) | | highlight(id, opts?) | Pulses a node with target behavior/color. | engine.highlight('n1', { color: '#ff0000', duration: 3000 }) |

5. Placement & Interaction

| API | Description | Usage Example | |---|---|---| | startPlacement(type, id, data?) | Enters placement mode with a ghost preview FOLLOWING the mouse. | engine.startPlacement('rectangle', 'task0') | | updatePlacementPreview(e \| p) | Manually updates the ghost preview's position (e.g. from DND dragover). | engine.updatePlacementPreview(event) | | completePlacement(e \| p?) | Adds the node and exits placement mode. | engine.completePlacement(event) | | cancelPlacement() | Aborts placement mode and removes preview (also mapped to Escape). | engine.cancelPlacement() | | placeShapeAt(type, id, x, y) | Immediately places a shape at exact canvas coordinates. | engine.placeShapeAt('circle', 'c1', 100, 200) | | placeShapeAtSafePos(type, id) | Finds the nearest non-overlapping spot in viewport to place a shape. | engine.placeShapeAtSafePos('rectangle', 'r1') | | handleDrop(event) | Native DND handler: parses drop data and places shape at mouse. | container.ondrop = (e) => Zenode.handleDrop(e) |

[!TIP] Deterministic IDs: If you provide an id in addNode(config), the engine will use it strictly. If not, it will return a UUID which you should captured for future calls.


🌟 Support Zenode

If you find this project useful, please consider leaving a Star on GitHub! It helps the project grow and motivates further development of the execution runtime.


Built with D3.js · TypeScript . GitHub