npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bensitu/image-editor

v2.9.0

Published

TypeScript-first Fabric.js v7 image editor with masks, annotations, crop, mosaic, history, and export APIs

Readme

@bensitu/image-editor

npm npm

ImageEditor demo landing page showing selectable masks, filters, mosaic-style redaction, and annotations

Click the screenshot to open the live demo.

A TypeScript-first image editor built on Fabric.js v7. It provides a focused canvas editing API for loading images, transforming the base image, creating masks and annotations, applying crop and mosaic operations, maintaining undo/redo history, and exporting edited output as Base64, File, or downloadable image assets.

The package is framework-agnostic and works from plain browser pages, bundled ESM applications, CommonJS consumers, and UMD/CDN environments. React, Vue, Next.js, and Nuxt integrations should create and dispose the editor inside client-side lifecycle hooks.

Contents

Quick Start

Install

npm install @bensitu/image-editor fabric
# or
pnpm add @bensitu/image-editor fabric
# or
yarn add @bensitu/image-editor fabric

fabric@>=7.4.0 <8 is a peer dependency. Install it explicitly so the editor uses the same Fabric version as your application.

Add Markup

<div id="editorContainer" style="width: 100%; height: 600px">
    <canvas id="canvas"></canvas>
</div>

<button id="zoomInButton">Zoom In</button>
<button id="rotateRightButton">Rotate Right</button>
<button id="enterCropModeButton">Crop</button>
<button id="downloadImageButton">Download</button>
<button id="undoButton">Undo</button>
<button id="redoButton">Redo</button>
<input id="imageInput" type="file" accept="image/*" />

Initialize

import * as fabric from 'fabric';
import { ImageEditor } from '@bensitu/image-editor';

const editor = new ImageEditor(fabric, {
    canvasWidth: 800,
    canvasHeight: 600,
    defaultLayoutMode: 'fit',
    backgroundColor: '#ffffff',
});

editor.init({
    canvas: 'canvas',
    canvasContainer: 'editorContainer',
    zoomInButton: 'zoomInButton',
    rotateRightButton: 'rotateRightButton',
    enterCropModeButton: 'enterCropModeButton',
    downloadImageButton: 'downloadImageButton',
    undoButton: 'undoButton',
    redoButton: 'redoButton',
    imageInput: 'imageInput',
});

await editor.loadImage('data:image/jpeg;base64,...');

editor.createMask({ shape: 'rect', width: 120, height: 80, left: '25%', top: '25%' });
editor.createTextAnnotation({ text: 'Label', left: 120, top: 80 });

const dataUrl = await editor.exportImageBase64({ fileType: 'png' });

The demo pages show larger DOM maps with image filters, masks, annotations, crop controls, mosaic controls, lists, and layer actions.

Features

Image and Layout

  • Load PNG, JPEG, and WebP data URLs or files.
  • Normalize supported JPEG EXIF orientation during file-input loading.
  • Choose fit, cover, or expand layout strategies.
  • Resize to explicit dimensions, hidden-container fallbacks, or current container size.
  • Downsample large images and guard input size before browser decode.

Editing Tools

  • Scale, rotate, flip, and reset the base image with undoable history.
  • Apply Fabric-backed brightness, contrast, saturation, blur, sharpen, grayscale, sepia, and vintage filters.
  • Create editable rectangle, circle, ellipse, polygon, and custom masks.
  • Add Text, Shape, and Draw annotations with update, delete, lock, hide, and layer-order APIs.
  • Crop with fixed or custom aspect ratios and optional mask preservation.
  • Use Mosaic mode to commit circular pixelation strokes into the base image.

State, Export, and Persistence

  • Bounded undo/redo history with serialized transform and history operations.
  • Export Base64, browser File, or direct downloads as PNG, JPEG, or WebP.
  • Choose image-bounds or full-canvas export areas.
  • Render masks and annotations independently during export without mutating editor state.
  • Save/load editor snapshots with saveState() and loadFromState().
  • Store editable overlays separately from image pixels with overlay-state JSON.

Integration

  • One public ImageEditor class exported as both default and named.
  • Fabric.js v7 is a peer dependency; the package does not bundle Fabric.
  • ESM, CommonJS, UMD, and TypeScript declaration outputs are published.
  • DOM binding accepts string IDs, HTMLElement refs, or null for unmanaged optional controls.
  • dispose() and disposeAsync() support framework lifecycle cleanup.

Demo and Examples

Documentation

Framework Integration

The core editor is framework-agnostic and can be mounted with string IDs or HTMLElement refs. React, Vue, Next.js, Nuxt, and other frameworks should create and dispose the editor inside client-side lifecycle hooks.

SSR guidance is strict: runtime imports, new ImageEditor(...), init(), image loading, canvas resizing, and export all require browser DOM/canvas APIs. Type imports are safe in server code.

API Overview

ImageEditor is the only public class. Public types and editor object guards are re-exported from the package root.

| Area | Core APIs | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | Lifecycle | init(), dispose(), disposeAsync() | | Image and layout | loadImage(), isImageLoaded(), isBusy(), isProcessing(), setLayoutMode(), setCanvasSize(), resizeToContainer(), relayout() | | State snapshots | getEditorState(), getImageInfo(), getMasks(), getAnnotations(), getSelection(), getActiveToolMode() | | Transforms | scaleImage(), rotateImage(), flipHorizontal(), flipVertical(), resetImageTransform() | | Image filters | setImageFilterConfig(), getImageFilterConfig(), resetImageFilterConfig(), clearImageFilters(), commitImageFilters() | | Masks | createMask(), removeSelectedMask(), removeAllMasks() | | Crop | enterCropMode(), setCropAspectRatio(), applyCrop(), cancelCrop() | | Mosaic | enterMosaicMode(), exitMosaicMode(), getMosaicConfig(), setMosaicConfig(), resetMosaicConfig() | | Text, Shape, Draw | enterTextMode(), createTextAnnotation(), enterShapeMode(), createShapeAnnotation(), enterDrawMode(), setDrawSubMode(), update/delete APIs | | Layer operations | bringSelectedObjectForward(), sendSelectedObjectBackward(), bringSelectedObjectToFront(), sendSelectedObjectToBack() | | Export and merge | exportImageBase64(), exportImageFile(), downloadImage(), mergeMasks(), mergeAnnotations() | | Overlay persistence | exportOverlayState(), validateOverlayState(), importOverlayState() | | History and snapshots | saveState(), loadFromState(), undo(), redo() |

See API reference for method behavior, state payloads, export options, object metadata, and guard semantics.

Configuration

Pass ImageEditorOptions to the constructor:

const editor = new ImageEditor(fabric, {
    canvasWidth: 960,
    canvasHeight: 640,
    defaultLayoutMode: 'fit',
    maxHistorySize: 25,
    exportAreaByDefault: 'image',
    mergeMasksByDefault: true,
    mergeAnnotationsByDefault: true,
    defaultMaskConfig: {
        color: 'rgba(255, 0, 0, 0.35)',
        alpha: 0.35,
        styles: {
            stroke: '#ff0000',
            strokeWidth: 2,
        },
    },
});

Common options include canvas sizing, layout mode, downsampling, input/export limits, history size, default mask/text/draw/shape/mosaic config, export defaults, DOM list order, and lifecycle callbacks. See Options reference for the full table.

Requirements

  • Node.js: >= 20 for development and building from source.
  • Fabric.js: peer dependency >=7.4.0 <8.
  • Browsers: Chrome 100+, Firefox 100+, Safari 15+, Edge 100+.
  • JavaScript target: distributed files target ES2019 and modern DOM APIs.
  • TypeScript: strict consumers that compile dependencies with skipLibCheck: false should include the ES2019 and DOM libraries in tsconfig.json. Fabric v7.4 declarations also reference jsdom types, so install @types/jsdom when your project type-checks Fabric's declaration files.

Older runtime targets must be transpiled by the consumer.

Module Formats

The package ships one public entry resolved through the exports map:

| Consumer | Resolves to | | ------------------------------------- | ------------------------------ | | ESM (import) | dist/esm/index.js | | CommonJS (require) | dist/cjs/index.cjs | | TypeScript (types) | dist/types/index.d.ts | | UMD (<script>, unpkg, jsdelivr) | dist/umd/image-editor.umd.js | | default fallback | dist/esm/index.js |

The constructor accepts Fabric explicitly in bundled apps:

import * as fabric from 'fabric';
import { ImageEditor } from '@bensitu/image-editor';

const editor = new ImageEditor(fabric, options);

UMD consumers can load Fabric and the editor as globals:

<script src="https://cdn.jsdelivr.net/npm/fabric@7/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@bensitu/image-editor/dist/umd/image-editor.umd.js"></script>
<script>
    const editor = new ImageEditor.ImageEditor({ canvasWidth: 800, canvasHeight: 600 });
</script>

require('@bensitu/image-editor') returns a namespace object with ImageEditor, default, and editor object guards; it does not return the constructor directly.

Runtime Guarantees

  • The editor owns the Fabric objects it creates and tags them as base image, mask, annotation, or session objects.
  • Session objects such as crop rectangles, mask labels, previews, selections, and transform handles are excluded from persistence and export.
  • Public read methods return safe snapshots where possible. Methods that expose Fabric objects, such as getMasks(), getAnnotations(), selection callbacks, and lifecycle callbacks, expose live editor-owned objects. Treat those objects as read-only from integration code.
  • loadImage(), crop, merge, and overlay import are transactional: failures restore the previous canvas state where applicable.
  • Lifecycle callback exceptions are caught and logged so host callback failures do not replace the editor operation.

Development

npm install
npm run build
npm test

See Contributing and local checks for browser tests, visual tests, release checks, and CI-equivalent commands.

License

MIT © Ben Situ.

Fabric.js is distributed under its own MIT license.