๐Ÿš€ Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more โ†’
Socket
Book a DemoInstallSign in
Socket

@joint/react

Package Overview
Dependencies
Maintainers
2
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@joint/react

1.0.0-alpha.4
latest
npm
Version published
Weekly downloads
63
-63.58%
Maintainers
2
Weekly downloads
ย 
Created
Source
JointJS Logo

@joint/react

A React library for building interactive diagrams, flowcharts, and graph-based visualizations. This library provides React components and hooks that wrap JointJS, making it easy to create powerful diagramming applications.

What can you build with @joint/react?

  • ๐Ÿ“Š Flowcharts and process diagrams
  • ๐ŸŒ Network topology visualizations
  • ๐Ÿง  Mind maps and organization charts
  • โš™๏ธ State machines and workflow editors
  • ๐Ÿ“ˆ Any interactive connected graphs

Why @joint/react?

  • ๐ŸŽฏ React-First: React components and hooks for modern React applications
  • ๐Ÿ”Œ Easy Integration: Simple drop-in components with minimal setup
  • ๐ŸŽจ Customizable: Full control over node and link appearances
  • โšก Interactive: Built-in support for dragging, connecting, and editing
  • ๐ŸŽญ Type-Safe: Written in TypeScript with full type definitions

Prerequisites

Before installing @joint/react, ensure you have:

  • React 16.8+ (for Hooks support)
  • Node.js 14+
  • A modern browser (Chrome, Firefox, Safari, Edge)

Installation

Install the library using your preferred package manager:

# Using npm
npm install @joint/react

# Using yarn
yarn add @joint/react

# Using bun
bun add @joint/react

Documentation

The documentation is available online:

  • API reference
  • Storybook with examples

Core Concepts

Before diving into the code, let's understand the basic building blocks:

  • Elements: Nodes in your diagram (boxes, circles, or custom shapes)
  • Links: Connections between elements (lines, arrows, or custom connectors)
  • Paper: The canvas (UI) where your diagram is rendered
  • Graph: The data model that holds your diagram's structure

Quick Start

Here's a complete example of a simple diagram with two connected nodes:

import React, { useCallback } from 'react';
import { GraphProvider, Paper, createElements, createLinks } from '@joint/react';

// Define your diagram elements (nodes)
const initialElements = createElements([
  {
    id: '1',
    label: 'Start',
    x: 100,      // Position from left
    y: 50,       // Position from top
    width: 120,
    height: 60
  },
  {
    id: '2',
    label: 'End',
    x: 100,
    y: 200,
    width: 120,
    height: 60
  },
]);

// Define connections between elements
const initialLinks = createLinks([
  {
    id: 'link1',
    source: '1',  // ID of source element
    target: '2'   // ID of target element
  }
]);

// Main component that renders the diagram
function DiagramExample() {
  // Define how each element should look
  const renderElement = useCallback((element) => (
    <div style={{
      padding: '10px',
      border: '2px solid #3498db',
      borderRadius: '8px',
      background: 'white'
    }}>
      {element.label}
    </div>
  ), []);

  return (
    <div style={{ height: '400px', border: '1px solid #ccc' }}>
      <Paper
        initialElements={initialElements}
        width="100%"
        height="100%"
        renderElement={renderElement}
        useHTMLOverlay
      />
    </div>
  );
}

// Wrap your app with GraphProvider
export default function App() {
  return (
    <GraphProvider
      initialElements={initialElements}
      initialLinks={initialLinks}
    >
      <DiagramExample />
    </GraphProvider>
  );
}

Event Handling

@joint/react provides various events to handle user interactions:

function DiagramExample() {
  const handleElementClick = useCallback((element) => {
    console.log('Element clicked:', element);
  }, []);

  return (
    <Paper
      width="100%"
      height="100%"
      onElementPointerClick={handleElementClick}
    />
  );
}

TypeScript Support

@joint/react is written in TypeScript and includes comprehensive type definitions. Here's an example of using types:

import { InferElement } from '@joint/react';

const elements = createElements([
  { id: '1', label: 'Node', x: 0, y: 0, width: 100, height: 40 }
]);

type CustomElement = InferElement<typeof elements>;

const renderElement = (element: CustomElement) => (
  <div>{element.label}</div>
);

Performance Considerations

To ensure optimal performance:

  • Memoization
// Memoize render functions
const renderElement = useCallback((element) => {
  return <CustomNode element={element} />;
}, []);

// Memoize event handlers
const handleElementClick = useCallback((element) => {
  // Handle click
}, []);

๐Ÿ“Œ Core Components

1. GraphProvider

The GraphProvider component manages a shared JointJS Graph instance to handle the state of your diagram. Wrap it around any components that interact with the graph.

import { GraphProvider } from '@joint/react';

<GraphProvider>
  {/* Components like Paper for rendering nodes and edges */}
</GraphProvider>

2. Paper

The Paper component wraps JointJS Paper to render nodes and links. Use the renderElement prop to define how nodes are displayed.

import { Paper } from '@joint/react';

const renderElement = (element) => (
  <rect width={element.size().width} height={element.size().height} fill="cyan" />
);

<Paper width={800} height={600} renderElement={renderElement} />

3. Rendering HTML Elements

Although JointJS is SVG-based, you can render HTML content inside nodes using SVG's <foreignObject>:

const renderElement = ({ width, height }) => (
  <foreignObject width={width} height={height}>
    <div style={{ background: 'lightgray' }}>
      HTML Content here
    </div>
  </foreignObject>
);

๐Ÿ› ๏ธ Core Hooks and Utilities

๐Ÿ”น Accessing Elements

  • useElements(): Retrieve all diagram elements (requires GraphProvider context).
  • useElement(): Retrieve individual element data, typically used within renderElement.

๐Ÿ”น Modifying Elements

  • useUpdateElement(): Update existing elements in the diagram.

  • useCreateElement(): Create new elements in the diagram.

  • useRemoveElement(): Remove elements from the diagram.

  • useCreateLink(): Create new elements in the diagram.

  • useRemoveLink(): Remove elements from the diagram.

๐Ÿ”น Graph and Paper Instances

  • useGraph(): Access the dia.Graph instance directly.
  • usePaper(): Access the dia.Paper instance directly.
  • createElements(): Utility for creating nodes.
import { createElements } from '@joint/react';

const initialElements = createElements([
  { id: '1', type: 'rect', x: 10, y: 10, width: 100, height: 100 },
]);
  • createLinks(): Utility for creating links between nodes.
import { createLinks } from '@joint/react';

const initialLinks = createLinks([
  { source: '1', target: '2', id: '1-2' },
]);

How It Works

Under the hood, @joint/react listens to changes in the dia.Graph, which acts as the single source of truth. When you update the graphโ€”such as adding or modifying cellsโ€”the React components automatically observe and react to these changes, keeping the UI in sync.

Hooks like useUpdateElement provide a convenient way to update the graph, but you can also directly access the graph using useGraph() and call methods like graph.setCells().

Known Issues and Recommendations

Avoid Certain CSS Properties in <foreignObject>

Some CSS properties can cause rendering issues in Safari when used inside an SVG <foreignObject>. To ensure compatibility, avoid the following properties:

  • position (other than static)
  • -webkit-transform-style
  • -webkit-backface-visibility
  • transition
  • transform

If you need to use HTML inside an SVG with cross-browser support:

  • Use minimal CSS inside <foreignObject>.
  • Stick to static positioning and avoid CSS transforms.
  • Consider overlaying HTML outside the SVG using absolute positioning.

Flickering

React's asynchronous rendering can cause flickering when dynamically adding ports or resizing elements. We are aware of this issue and are working on a fix.

Controlled Mode

Currently, @joint/react uses useSyncExternalStore to listen to graph changes. The graph is the source of truth, so initialElements and initialLinks are only used during initialization. To modify the state, update the graph directly using hooks like useGraph, useUpdateElement, or useCreateElement. A fully controlled mode is under development.

FAQs

Package last updated on 24 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts