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

Fabric.js: the canvas object model behind browser and Node.js editors

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

31,463 stars3,623 forksTypeScriptMIT

At a glance

What is it?
Fabric.js wraps the HTML5 canvas with a serializable object model and an SVG parser. This review covers the 7.x package split, the Node.js install path, and where the library stops being the right choice.
Who is it for?
Adopt Fabric.js if you are building an interactive canvas editor in the browser, or an SVG-to-canvas pipeline in Node.js, and you accept node-canvas as a dependency. Do not adopt it if you only need static charts or DOM-driven SVG.
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 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Fabric.js adds on top of a raw canvas element

The canvas API gives you pixels and a 2D context. It does not give you objects. Once you draw a rectangle, nothing in the browser remembers it as a rectangle: no bounds, no rotation angle, no hit test, no way to serialize it back out. Fabric.js exists to put that layer back. The package description calls it an "Object model for HTML5 canvas, and SVG-to-canvas parser", and that is the whole pitch in one line.

The audience is narrow but deep. If you are building a design tool, a meme generator, a diagramming surface, an annotation layer over an image, or anything where a user drags, scales and rotates shapes, you would otherwise write hit testing and transform math yourself. Fabric.js ships those interactions out of the box, along with shapes, controls, animations, image filters, gradients, patterns and brushes. It also handles JPG, PNG, JSON and SVG input and output, which matters because JSON serialization is what lets you save a document and reload it later without re-deriving state from pixels.

It is not a rendering engine for data visualization. It is not a scene graph for 3D. It is a document model for 2D vector-ish content that happens to render through canvas.

How the object model, serialization and SVG parser fit together

The architecture visible in the repository is a workspace. The root package.json still publishes `fabric`, but the README describes it as a "Legacy compatibility facade" that re-exports `@fabricjs/browser`. Underneath sit `@fabricjs/core`, which the README calls the "Shared, environment-neutral runtime used by the browser and Node packages", plus `@fabricjs/browser` and `@fabricjs/node` as the preferred entrypoints. Optional features live in separate packages such as `@fabricjs/aligning-guidelines`.

That split has a real consequence. The README warns that the facades "share the same class identities as their corresponding workspace packages", and that mixing mismatched versions "can load separate runtimes". In practice this means an `instanceof` check or a type comparison can fail silently when two copies of the core are present in a bundle. Keeping `fabric` and every `@fabricjs/*` package on matching versions is not cosmetic advice.

The data flow is: you construct objects (Rect, Circle, Text, Image, Path), add them to a Canvas or StaticCanvas, and the library maintains their transforms. Serialization to JSON walks that object list. SVG parsing runs the other direction, reading an SVG document and producing the same object types, which is why the same JSON can round-trip between a browser session and a Node.js render job.

One caveat the README states plainly: `@fabricjs/core` has "no Node-specific runtime dependencies, but it is not a DOM-free API". Consumers using core APIs that touch DOM or canvas must supply a suitable environment. The environment-neutral label describes dependencies, not purity.

Installing Fabric.js from npm and drawing a first object

For a new application the README gives environment-specific packages rather than the legacy one. Browser code installs `@fabricjs/browser`; Node.js code installs `@fabricjs/node`.

bash
# Browser applications
npm install @fabricjs/browser

# Node.js applications
npm install @fabricjs/node

Existing applications can stay on `fabric`, which the README says "remains supported". All three of npm, yarn and pnpm are shown for that path.

bash
npm install fabric --save
# or use yarn
yarn add fabric
# or use pnpm
pnpm add fabric

The imports differ by target. New browser code should prefer the explicit entrypoint.

js
import { Canvas } from '@fabricjs/browser';
import { StaticCanvas } from '@fabricjs/node';

For a plain HTML page with no bundler, the README shows a script tag and a rectangle. Note that the pinned CDN version in that example is 6.4.3, while the current release line is 7.x, so treat the version in the URL as illustrative rather than current.

html
<canvas id="canvas" width="300" height="300"></canvas>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js"></script>
<script>
  const canvas = new fabric.Canvas('canvas');
  const rect = new fabric.Rect({
    top: 100,
    left: 100,
    width: 60,
    height: 70,
    fill: 'red',
  });
  canvas.add(rect);
</script>

After loading that page you should see a red rectangle at (100, 100) that you can drag, scale and rotate with the default controls. That interactivity is not something you wrote: it comes from the Canvas class. The v5 style import `import { fabric } from 'fabric'` is also listed as a compatibility entrypoint.

The Node.js path depends on node-canvas and jsdom

Running Fabric.js on the server is not the same library with a different import. The README states that it "depends on node-canvas for a canvas implementation (HTMLCanvasElement replacement) and jsdom for a window implementation on node", and then adds the sentence that should shape your decision: "you may encounter node-canvas limitations and bugs". Those limitations are inherited, not created by Fabric.js, but they are inherited by you.

The supported Node floor is explicit. The README recommends running only LTS versions and states that "the minimum supported version of node is 20". The policy for raising it is also stated: the minimum moves up with a major release only when dependencies force it. That is a reasonable contract, and it means a Node 18 deployment cannot be assumed to work.

There is also a browser support table with hard edges. Firefox 58, Safari 11, Chrome 64, Chromium-based Opera and Edge are marked supported. IE11 and Edge Legacy are marked unsupported. The README explains the reason: Fabric.js does not use polyfills by default, and "while JS can be easily transpiled, canvas API can't". If your product still has an IE11 requirement, this library is not a candidate, and no build step will change that.

Where Fabric.js is the wrong tool, and what to use instead

The clearest boundary is interactivity. If your output is a static chart, a server-rendered PNG, or a diagram the user never manipulates, you are paying for an object model, a control system and a serialization format you will not use. A plain 2D context, or a charting library that owns its own layout, will be smaller and simpler.

The most common comparison people search for is Fabric.js against Konva.js. The difference in approach is where the object graph lives. Konva.js builds a scene graph of nodes rendered to canvas, with its own stage, layer and node hierarchy, and it is designed around that tree from the start. Fabric.js starts from a flat canvas with objects added to it, and its distinguishing feature is the parser direction: SVG in, canvas objects out, and JSON as the intermediate format. If your workflow is "import an SVG, let the user edit it, export SVG or JSON again", Fabric.js is built for that round trip. If your workflow is "compose a scene programmatically and animate it", a scene-graph-first library is a closer fit.

There is a second comparison worth naming. Against D3.js the split is not about quality but about who owns the DOM. D3 binds data to DOM elements and lets the browser render them; you get CSS, accessibility and text selection for free. Fabric.js renders into a single canvas element, so text inside it is pixels. That is the trade: canvas gives you uniform transforms and export, and takes away the browser's own text and accessibility behavior.

A third limitation is honest and comes from the README itself: the old V5 documentation is hosted separately at fabric5.fabricjs.com. If you find a tutorial written against v5 and you are on 7.x, the import style and package names may not match what you are running.

Maintenance, version alignment and the MIT licence

The repository is not archived, and the last push was on 2026-09-09, which is within the last two weeks. Recent releases are v7.4.0 on 2026-05-18, v7.3.1 on 2026-04-19 and v7.3.0 on 2026-04-18. The cadence is real and the project is moving.

The upgrade cost is concentrated in the package split. The README's migration table is the thing to read before upgrading: `fabric` is a facade over `@fabricjs/browser`, and `fabric/node` mirrors `@fabricjs/node`. The version-alignment warning is the practical risk. If a transitive dependency pulls a second copy of `@fabricjs/core`, you can end up with two runtimes and broken identity checks. A lockfile audit after upgrading is worth more than reading the changelog.

Extension packages add a second axis of version drift. `@fabricjs/aligning-guidelines` is imported individually, and it must track the same version line as the core packages.

On licensing: the package.json declares MIT, and the repository carries a LICENSE file. MIT is permissive, which generally means you can use the library in proprietary software provided the copyright notice and permission notice are retained. That is a description of the licence text, not legal advice. If your organization has specific obligations around attribution in distributed binaries, have counsel confirm how the notice should be surfaced.

One thing the README does not document is a rollback procedure. There is a CHANGELOG.md and a CONTRIBUTING.md, but no stated path for reverting a bad upgrade beyond reinstalling the previous version.

Editorial conclusion

Adopt Fabric.js if you are building an interactive canvas editor in the browser, or an SVG-to-canvas pipeline in Node.js, and you accept node-canvas as a dependency. Do not adopt it if you only need static charts or DOM-driven SVG. Before committing, verify that your bundler resolves @fabricjs/browser, that every fabric and @fabricjs/* package sits on the same version, and that node-canvas builds on your target Node release.

Frequently asked questions

Can I use Fabric.js in React?

Nothing in the README forbids it, and the library is imported as an ES module, so it can be used inside a component. The practical concern is that a Canvas instance owns a DOM canvas element and its own event handling, so you need to decide which side controls the lifecycle. The README does not document a React integration.

How do I install Fabric.js?

For new applications the README says to install `@fabricjs/browser` for browser code or `@fabricjs/node` for Node.js code. The legacy `fabric` package remains supported and can be installed with npm, yarn or pnpm.

What is Fabric.js used for?

It is an object model for HTML5 canvas plus an SVG-to-canvas parser. The README lists out of the box interactions such as scale, move, rotate, skew and group, built in shapes, controls, animations, image filters, gradients, patterns and brushes, and JPG, PNG, JSON and SVG input and output.

Is Fabric.js free and open source?

The package.json declares the MIT licence and the repository includes a LICENSE file. MIT is a permissive open source licence, so the source is available and usable under its terms.

What is the difference between Fabric.js and Konva.js?

Konva.js is built around a scene graph of stages, layers and nodes. Fabric.js starts from a canvas with objects added to it, and its distinguishing feature is the SVG-to-canvas parser with JSON as the intermediate format, which suits import-edit-export workflows. The README does not compare the two directly.

Official sources

  1. fabricjs/fabric.js on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fabricjs-fabric-js.svg)](https://hysenlabs.com/projects/fabricjs-fabric-js)