
Product
Introducing Rust Support in Socket
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.
@joint/react
Advanced tools
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.
Before installing @joint/react, ensure you have:
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
The documentation is available online:
Before diving into the code, let's understand the basic building blocks:
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>
);
}
@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}
/>
);
}
@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>
);
To ensure optimal performance:
// Memoize render functions
const renderElement = useCallback((element) => {
return <CustomNode element={element} />;
}, []);
// Memoize event handlers
const handleElementClick = useCallback((element) => {
// Handle click
}, []);
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>
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} />
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>
);
useElements()
: Retrieve all diagram elements (requires GraphProvider
context).useElement()
: Retrieve individual element data, typically used within renderElement
.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.
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' },
]);
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()
.
<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:
<foreignObject>
.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.
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
Unknown package
The npm package @joint/react receives a total of 59 weekly downloads. As such, @joint/react popularity was classified as not popular.
We found that @joint/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
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.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.
Product
Socket’s precomputed reachability slashes false positives by flagging up to 80% of vulnerabilities as irrelevant, with no setup and instant results.
Product
Socket is launching experimental protection for Chrome extensions, scanning for malware and risky permissions to prevent silent supply chain attacks.