Model or dataset
fabricjs/fabric.js avatar
fabricjs/fabric.js

Fabric.js: A Canvas Library With a Package Split to Understand Before You Upgrade

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

31,441 stars3,620 forksTypeScriptMIT

At a glance

What is it?
Fabric.js provides an object model over the HTML5 canvas plus SVG parsing in both directions, and its recent releases reorganised the npm surface into @fabricjs/browser, @fabricjs/node and @fabricjs/core. The library is a reasonable fit for interactive editors; the package versioning rules are the part that will bite you.
Who is it for?
Adopt Fabric.js if you are building an interactive canvas editor in a browser and want a maintained object model instead of hand-rolled hit testing and transform maths; the MIT licence and the modular @fabricjs/browser entrypoint make that a low-friction start. Do not adopt it for headless server-side rendering where output fidelity matters, because the README states the Node path depends on node-canvas and jsdom and that you may encounter node-canvas limitations and bugs.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The Problem Fabric.js Solves, and Who Actually Needs It

A raw canvas element gives you a bitmap and a drawing context. It does not give you objects. If you want a user to click a rectangle, drag it, rotate it, group it with a circle, and then serialise the whole scene, you write that layer yourself: hit testing, transform matrices, z-order, selection state, serialisation. Fabric.js is that layer, shipped as a library. The README describes it as a simple and powerful Javascript HTML5 canvas library and lists out of the box interactions such as scale, move, rotate, skew, group alongside built in shapes, controls, animations, image filters, gradients, patterns, brushes. The audience is therefore narrow and specific: teams building design tools, diagram editors, annotation surfaces, whiteboard products, or any browser UI where the canvas holds discrete objects rather than a continuous drawing. If you are rendering a chart from data, a charting library is a better fit and Fabric.js adds weight you will not use. If you are painting pixels in a photo editor, the object model is overhead. The library earns its place when the objects themselves are the product.

The Object Model and the Two-Way SVG Path

The mechanism is a retained scene graph drawn onto a canvas. You construct objects (the README's example builds a fabric.Rect with top, left, width, height and fill), add them to a Canvas instance, and the library handles rendering and pointer interaction. The repository description names the second half of the value proposition directly: SVG-to-Canvas and canvas-to-SVG parsing. That means an SVG file can be loaded into the same object model that user interaction mutates, and the resulting scene can be written back out as SVG. For editors that need import and export, this is the reason to pick Fabric.js over a thinner canvas wrapper, because it means one representation serves both the interactive session and the file format. The README also lists JPG, PNG, JSON and SVG i/o, so raster export and a JSON scene format sit alongside the vector path. The project is written in TypeScript and the README describes it as typed and modular, with unit tests referenced in CONTRIBUTING.md. Note what the README does not claim: it does not promise complete SVG specification coverage, and the presence of a dedicated GOTCHAS document linked from the top of the README suggests there are behaviours worth reading about before you rely on round-trip fidelity.

Installing It: Two Entrypoints and a Version-Matching Rule

The README splits installation by environment. For a browser application the command is npm install @fabricjs/browser; for Node.js it is npm install @fabricjs/node. The older fabric package still works and is documented as npm install fabric --save, with yarn add fabric and pnpm add fabric given as equivalents. Internally, fabric is described as a legacy compatibility facade that re-exports @fabricjs/browser, while @fabricjs/core is the shared, environment-neutral runtime used by both. Imports follow the same split. The README shows import { Canvas } from '@fabricjs/browser' and import { StaticCanvas } from '@fabricjs/node' for new applications, and import { Canvas } from 'fabric' plus import { StaticCanvas } from 'fabric/node' for compatibility, with import { fabric } from 'fabric' retained for v5 code. Optional features are separate packages imported individually; the README names @fabricjs/aligning-guidelines as the example. The constraint to internalise is stated plainly: keep fabric and every @fabricjs/* package on matching versions, because mixing mismatched versions can load separate runtimes. That is a real failure mode, not a style preference, and it is the kind of thing that appears when one dependency pulls fabric while your own code imports @fabricjs/browser. The README also notes that @fabricjs/core has no Node-specific runtime dependencies but is not a DOM-free API, so advanced consumers using core APIs that touch DOM or canvas must supply a suitable environment implementation.

Node.js Rendering Inherits node-canvas Bugs

This is the clearest limitation in the README. The README states that Fabric.js depends on node-canvas for a canvas implementation and jsdom for a window implementation on Node, and then says directly that you may encounter node-canvas limitations and bugs, linking to the node-canvas issue tracker. The practical consequence: a scene that renders correctly in Chrome may not render identically under Node, and when it does not, the defect may live in a dependency rather than in Fabric.js. Teams that generate server-side thumbnails, PDFs, or share images from the same scene graph they edit in the browser should treat that as an accepted risk, not a solved problem. The README also recommends running only LTS versions of Node and sets the minimum supported version at 20, with the note that the minimum is bumped only on a major release when dependencies force it. On the browser side, the support table lists Chrome 64, Firefox 58 and Safari 11, and the README explains the floor is set by the canvas API level the library wants to use, adding that while JS can be easily transpiled, canvas API can't. That sentence is the honest version of the constraint: you cannot polyfill your way to a lower browser target here. Edge Legacy and IE11 are marked unsupported.

Where Fabric.js Is the Wrong Tool

Three cases stand out from the README. First, DOM-based editors. If your shapes are HTML elements, CSS already gives you hit testing, transforms, z-order and accessibility, and moving to canvas discards all of it. Fabric.js is for when you have decided the DOM cannot carry the scene, typically because of object count or freeform drawing. Second, headless pipelines where pixel fidelity is contractual. The Node path runs through node-canvas and jsdom, and the README's own warning about node-canvas bugs means the server is not a mirror of the browser. Third, and less obvious: applications that only need to display SVG. If you never mutate the scene, an SVG element or a static renderer does the job without pulling in an interaction layer. The README's feature list is broad, and broad libraries cost bundle size and API surface. The legacy distribution files illustrate the compatibility burden the project carries: dist/index.js and dist/index.min.js are full browser UMD builds, and dist/index.node.cjs is the legacy CommonJS build for require('fabric/node'). Those exist for existing usage, and the README steers new ESM applications to the @fabricjs packages instead. Choosing the legacy path for a greenfield project means adopting a facade the project itself frames as compatibility.

Comparing the Approach: Fabric.js Versus Konva.js

The closest comparison in this space is Konva.js, which also puts a scene graph and an interaction layer over canvas. The difference is in the surrounding concerns rather than the core idea. Fabric.js pairs its object model with SVG parsing in both directions as a first-class feature, which matters if SVG is your interchange format; Konva.js centres on its own scene serialisation and relies on separate projects for SVG work. Fabric.js has also just restructured its npm surface into environment-specific packages with a shared core, so browser and Node consumers install different entrypoints and share class identities across the facades. Konva.js ships a single package with a separate node entrypoint, which is simpler to reason about and simpler to version. The trade-off is legibility versus structure: Fabric.js's split lets the Node package own its own dependencies (node-canvas, jsdom) without forcing them on browser builds, but it introduces the matching-version rule described above. If your team has been bitten by duplicate copies of a library in a monorepo, that rule is a cost you are opting into. If bundle composition is the priority, the split is the reason to prefer it.

Maintenance, Licensing and What to Check Before You Upgrade

Fabric.js is MIT licensed, which permits commercial use and modification; that is a statement about the licence text, not legal advice, and you should confirm obligations with your own counsel if you redistribute modified sources. The project is not archived, the default branch is master, and the release cadence visible here is steady: v7.3.0 in April 2026, v7.3.1 a day later, v7.4.0 in May 2026, with repository activity continuing through September 2026. That cadence cuts both ways. Patch releases arriving within a day of a minor suggest responsive fixes, and it also means a lockfile pinned loosely to a caret range will move. The upgrade cost is concentrated in the package rename rather than in the API: if you are on fabric and want to move to @fabricjs/browser, the import specifiers change but the README says the facades share the same class identities, so the objects your code constructs are the same classes. The risk is partial migration, where some files import fabric and others import @fabricjs/browser, and the README warns that mismatched versions can load separate runtimes. Check your lockfile for more than one resolved Fabric.js version before and after any upgrade, and verify the Node floor of version 20 against your CI images. The README points to a GOTCHAS page and to separate V5 documentation, which tells you the maintainers expect migration questions; read both before a major bump rather than after.

Editorial conclusion

Adopt Fabric.js if you are building an interactive canvas editor in a browser and want a maintained object model instead of hand-rolled hit testing and transform maths; the MIT licence and the modular @fabricjs/browser entrypoint make that a low-friction start. Do not adopt it for headless server-side rendering where output fidelity matters, because the README states the Node path depends on node-canvas and jsdom and that you may encounter node-canvas limitations and bugs. Before committing, verify three things: that your Node runtime is 20 or above, that every fabric and @fabricjs/* package in your lockfile resolves to the same version, and that your SVG files survive a round trip through loadSVGFromString and toSVG, since the README does not promise full SVG coverage.

Official sources

  1. fabricjs/fabric.js on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes