Skip to main content
Version: 4.3

Installation & Setup

Three things get you to a working canvas: install the package, import the styles, and give the canvas a size.

1. Install

Pick your edition and install with your package manager of choice. The JointJS tab is the free, open-source package; the JointJS+ tab is the commercial one. It's the same choice you'll see on every example in this guide.

@joint/react is published on npm:

npm install @joint/react

Requirements

  • React 18 or 19. react and react-dom are peer dependencies, so your project must already have them installed (any React app does).
  • Any modern React setup. @joint/react ships both ESM and CommonJS builds, so it drops into Vite, Next.js, Create React App, Remix, and the rest. Starting fresh? Vite (npm create vite@latest) is the quickest.
@joint/core comes with it

@joint/react depends on the JointJS engine (@joint/core) and pulls it in automatically. You never import from @joint/core directly to get started; @joint/react re-exports everything you need.

2. Import the stylesheet

The package ships a stylesheet that draws links, ports, highlighters, and the canvas chrome. Import it once, near your app entry point. Without it, links and built-in visuals will not render correctly. Importing it once is enough for the whole app; every example in this guide includes this line.

import '@joint/react/styles.css';

The diagram chrome it draws is themed through --jj-* CSS variables. Customizing them (and using a CSS framework if you have one) is covered in Theming.

3. Size the canvas

This is the one rule that trips people up: Paper has no width or height props. It fills the element you size with CSS: give its parent, or the Paper itself, a real height, or you will see nothing.

Any CSS works: an inline style, a plain class, CSS Modules, or a utility framework. The examples in this guide use plain CSS, no framework required:

// ✅ Size the Paper directly with an inline style
<Paper renderElement={Element} style={{ height: 500 }} />
// ✅ Or with a plain CSS class
// .canvas { height: 100%; } ← in your stylesheet
<div style={{ height: 500 }}>
<Paper renderElement={Element} className="canvas" />
</div>
// ❌ No size anywhere → 0px tall → blank canvas
<Paper renderElement={Element} />

A percentage height (height: 100%) only works when an ancestor has a concrete height.

You are set up

That is the whole setup: installed, styled, sized. Here is a complete starting point: paste it into your app and you have a draggable two-element diagram:

import { GraphProvider, Paper, HTMLBox } from '@joint/react';
import '@joint/react/styles.css';

const initialCells = [
  { id: '1', type: 'element', position: { x: 300, y: 140 }, data: { label: 'Hello' } },
  { id: '2', type: 'element', position: { x: 500, y: 200 }, data: { label: 'World' } },
  {
    id: '1→2',
    type: 'link',
    source: { id: '1' },
    target: { id: '2' },
    style: { targetMarker: 'arrow' },
  },
];

export default function App() {
  return (
    <GraphProvider initialCells={initialCells}>
      <Paper
        renderElement={({ label }) => <HTMLBox>{label}</HTMLBox>}
        style={{ height: 400 }}
      />
    </GraphProvider>
  );
}


Press Edit above to see and tweak the full App.tsx.

Two elements on a 400px-tall canvas, joined by an arrow. (That third cell with type: 'link' is the connection between them. It lives in the same initialCells array; you'll build links properly in Connecting Elements.) The next chapter breaks this down line by line.

Stuck? The usual suspects
  • Blank canvas → the Paper has no height. Size it (or its parent) with CSS; see step 3.
  • Links or visuals look wrong → you forgot import '@joint/react/styles.css'.
  • Your HTML doesn't show → wrap it in HTMLHost. JointJS is SVG-first, so plain HTML needs it.
  • Elements won't drag → check you didn't set interactive={false} on the Paper.