Highlighters can be used to provide visual emphasis to an element; during user interactions for example.

Highlighters inherit from dia.HighlighterView.

In the above demo, we listen to the paper for the element:pointerclick event and highlight the entire element we clicked on.

paper.on('element:pointerclick', (elementView) => {
    joint.highlighters.mask.add(elementView, { selector: 'root' }, 'my-element-highlight', {
        deep: true,
        attrs: {
            'stroke': '#FF4365',
            'stroke-width': 3

We also listen to the paper for the element:magnet:pointerclick event and highlight the port we clicked on.

paper.on('element:magnet:pointerclick', (elementView, magnet, evt) => {
    // Prevent highlighting the body of the element
    // Find the port ID of the selected magnet
    const port = cellView.findAttribute('port', magnet);
    joint.highlighters.mask.add(elementView, { port }, 'my-port-highlight', {
        attrs: {
            'stroke': '#FF4365',
            'stroke-width': 3

Then we listen for the link:pointerclick event and highlight the line node of the link we clicked on.

paper.on('link:pointerclick', (linkView) => {
    joint.highlighters.mask.add(linkView, { selector: 'line' }, 'my-link-highlight', {
        // Draw the highlighter under the LinkView
        layer: 'back',
        attrs: {
            'stroke': '#FF4365',
            'stroke-width': 3,
            'stroke-linecap': 'square'

Next we set up a listener for a custom event link:label:pointerdown and highlight the label we clicked on.

A custom paper event can be defined with event attribute.
paper.on('link:label:pointerdown', (linkView, evt) => {
    // Prevent highlighting the line of the link
    // Find the index of the selected label
    const label = cellView.findAttribute('label-idx', evt.target);
    joint.highlighters.mask.add(linkView, { label }, 'my-label-highlight', {
        // Decrease the gap between the label and highlighter
        padding: 1,
        attrs: {
            'stroke': '#FF4365',
            'stroke-width': 3

Generally, it's possible to highlight a cell (Element or Link) or a part of the cell calling the add() method of a highlighter.

// Add Mask Highlighter with ID `my-mask-highlighter` to the CellView.
// Note: `root` is a shortcut for `{ selector: 'root' }`
joint.highlighters.mask.add(cellView, 'root', 'my-mask-highlighter', {
    deep: true

// Add class name `my-highlight` to the CellView's body node.
joint.highlighters.addClass.add(cellView, 'body', 'my-class-highlighter', {
    className: 'my-highlight'

// Add Stroke Highlighter to a specific port node (using default options).
joint.highlighters.stroke.add(cellView, { port: 'port-id-1', selector: 'portBody' }, 'my-port-highlighter');

To unhighlight a cell, call the remove() method.

// Remove all highlighters from the CellView

// Remove the highlighter with ID `my-highlighter` from the CellView
joint.dia.HighlighterView.remove(cellView, 'my-highlighter');

// Remove all Mask highlighters from the cellView

// Remove Stroke Highlighter with ID `my-highlighter` from the cellView.
joint.highlighters.stroke.remove(cellView, 'my-highlighter');

// If you have a reference to a highlighter, calling its prototype `remove()` method is also valid.
const highlighter = joint.dia.HighlighterView.get(cellView, 'my-highlighter');

To see if a cell has a highlighter, call the get() method.

// Get all the highlighters (an array) from the CellView

// Get the highlighter with ID `my-highlighter` from the CellView
joint.dia.HighlighterView.get(cellView, 'my-highlighter');

// Get all Mask highlighters from the cellView

// Get Stroke Highlighter with ID `my-highlighter` from the cellView.
// If there is no such highlighter (ID or Type does not match, `null` is returned).
joint.highlighters.stroke.get(cellView, 'my-highlighter');
When adding a highlighter, prefer using a node selector over a reference to an actual node.
// Prefer this:
joint.highlighters.mask.add(elementView, { port: 'port1' }, 'port-highlight');
// Over this:
joint.highlighters.mask.add(elementView, elementView.findPortNode('port1'), 'port-highlight');

If a node (determined by the node selector) stops to exist (e.g. a port is removed) the cell:highlight:invalid event is triggered on the paper.

// If we don't want the highlighter wait for the port to reappear, we can remove it when the event occurs.
paper.on('cell:highlight:invalid', (cellView, id) => {
    joint.dia.HighlighterView.remove(cellView, id);