Fabric.js 696,666 (github.com/fabricjs/fabric.js (https://github.com/fabricjs/fabric.js 31,463 ), npm 2,036 install fabric, MIT) is an interactive object model: objects get selection handles, text boxes wrap and edit in place, and scenes round-trip through JSON and SVG. Version 7 positions objects by their center (originX and originY are deprecated). Konva (github.com/konvajs/konva (https://github.com/konvajs/konva 14,832 ), npm install konva, MIT) is a scene graph of stages, layers, groups and shapes with DOM-like events, dragging and a Transformer, drawing each layer on its own canvas. Both handle devicePixelRatio.
<div style="display:flex; gap:24px"><canvas id="fab" width="290" height="150"></canvas>
<div id="kon"></div></div>
<script src="https://cdn.jsdelivr.net/npm/fabric@7.4.0/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/konva@10.7.0/konva.min.js"></script>
<script>
const f = new fabric.Canvas('fab'); // left/top are the object's center
const title = new fabric.Textbox('Small Steps to Big Summits', { left: 55, top: 60,
width: 76, fontSize: 15, fontWeight: 'bold', fontFamily: 'Georgia', fill: '#fff3e0' });
f.add(new fabric.Rect({ left: 55, top: 75, width: 90, height: 130, rx: 4, fill: '#3f7d3a' }),
title);
f.setActiveObject(title);
const stage = new Konva.Stage({ container: 'kon', width: 290, height: 150 });
const layer = new Konva.Layer(); stage.add(layer); // add() returns the stage
const book = new Konva.Group({ x: 10, y: 10, draggable: true });
book.add(new Konva.Rect({ width: 90, height: 130, cornerRadius: 4, fill: '#b5452f' }),
new Konva.Text({ x: 8, y: 10, width: 78, text: "The Clockmaker's Paradox", fontSize: 13,
fontStyle: 'bold', fontFamily: 'Georgia', fill: '#fff3e0' }));
layer.add(book, new Konva.Transformer({ nodes: [book] }));
setTimeout(() => __done = true, 300);
</script>
Fabric put handles on the text box itself; Konva framed the group, and its word wrap split Clockmaker's, too wide for the line, where fitTitle() (Cover Designer) shrinks the font. Konva's add() returns the parent, not the child. Fabric suits editors and annotators; Konva suits diagrams, games and seat maps, with official React 7,897 , Vue 5,482 , Svelte 36,701 and Angular 42,088 bindings.