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

@unlayer/react-image-editor

v1.0.0

Published

Unlayer's Image Editor Component for React.js

Readme

React Image Editor

npm version License: MIT CI

The excellent Unlayer Image Editor as a React.js wrapper component — crop, resize, draw, text, shapes, stickers, frames, filters, and an optional AI Assistant.

Live Demo

Try the live demo: react-image-editor-example.vercel.app

Installation

npm install @unlayer/react-image-editor

Usage

Requires React >= 18.

import React, { useRef } from 'react';
import ImageEditor from '@unlayer/react-image-editor';

const App = () => {
  const editorRef = useRef(null);

  return (
    <ImageEditor
      ref={editorRef}
      image="https://example.com/photo.jpg"
      options={{ theme: 'light' }}
      onSave={({ dataUrl, blob }) => {
        // Persist the edited image
        console.info('Saved', dataUrl.length, 'bytes');
      }}
      onCancel={() => console.info('Editing cancelled')}
    />
  );
};

The component works out of the box in React Server Components environments (e.g. Next.js App Router) — it ships with the 'use client' directive and touches the DOM only inside effects.

Props

| Prop | Type | Description | | ------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | image | string (required) | Image URL or base64 data URL to edit. | | options | ImageEditorOptions | Editor configuration: projectId, user, features, theme, locale, translations, env, offline, licenseUrl, defaultPrompt, autoSubmitPrompt, aiAssistantOpenState. | | editorId | string | id for the container div. Cosmetic — the editor mounts by element reference. | | minHeight | number \| string | Minimum height of the editor container. Defaults to 500. | | style | CSSProperties | Styles applied to the container div. | | onLoad | (editor) => void | Called with the editor instance once it is mounted. | | onSave | ({ dataUrl, blob }) => void | Called when the user saves the edited image. | | onCancel | () => void | Called when the user cancels editing. | | onLoadError | () => void | Called when the image fails to load into the canvas (CORS, 404, decode error). | | onError | (error: Error) => void | Wrapper-level failures: embed script load, editor creation, or image reset. Falls back to console.error when absent. |

Editor instance (ref)

The ref exposes { editor }null until the editor mounts, then an instance with:

| Method | Description | | ------------------------ | ---------------------------------------------------------------------------- | | getImage() | Current canvas as a data URL (flattened), or null. | | hasChanges() | Whether there are unsaved edits. | | reset(imageUrl?) | Reset editor state (clears undo/redo and chat), optionally load a new image. | | updateOptions(partial) | Update options like theme / locale at runtime. | | destroy() | Unmount the editor (the component does this automatically on unmount). |

const dataUrl = editorRef.current?.editor?.getImage();

How prop changes are applied

| Change | Behavior | | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | image | Applied via reset(newImage)clears undo/redo history and AI chat. Rapid changes are serialized and collapse to the latest value. | | options.theme, options.locale, options.translations | Applied via updateOptions() — no remount, editor state preserved. | | Any other options key | Full remount — the editor is destroyed and recreated with the new configuration. | | onSave / onCancel / onLoadError / onLoad / onError | Always call the latest handler; changing them never remounts. |

Error handling

Two distinct channels:

  • onLoadError — the editor loaded fine, but the image couldn't be loaded into the canvas (CORS, dead URL, decode error).
  • onError — the wrapper couldn't reach a working editor: the embed script failed to load, editor creation was rejected, or re-applying a changed image failed. After a CDN failure the wrapper automatically resets its loader state, so a later remount retries from scratch.

Tools

The editor ships eight tools, rendered as a tab rail beside the canvas:

| Tool | What it does | | ---------- | ---------------------------------------------------------------------------------------------- | | crop | Crop with rotate (90° steps), flip, and a straighten slider. | | resize | Change the output dimensions. | | filter | One-tap presets plus adjustment sliders (brightness, contrast, saturation, hue, blur, noise…). | | draw | Freehand brush with color, type, and size controls. | | text | Text layers with style presets, fonts, color/background/outline/shadow. | | shapes | Filled/outline/gradient shape palettes with drag, resize, rotate, and styling. | | stickers | A bundled sticker library grouped by category, with color/outline/shadow for vector sets. | | frame | Frame presets with a size slider and color picker. |

All tools are enabled by default. Configure them through options.features.imageEditor.tools — each entry is either a boolean shorthand or { enabled?: boolean; icon?: string }:

// Hide the tools you don't want
<ImageEditor
  image={url}
  options={{
    features: {
      imageEditor: {
        tools: {
          draw: false,
          stickers: false,
          frame: { enabled: false }, // object form, same effect
        },
      },
    },
  }}
/>
// Allow-list style: a minimal crop-and-filter editor
<ImageEditor
  image={url}
  options={{
    features: {
      imageEditor: {
        tools: {
          resize: false,
          draw: false,
          text: false,
          shapes: false,
          stickers: false,
          frame: false,
          // crop and filter stay enabled by default
        },
      },
    },
  }}
/>
// Custom tool icon: a URL, raw <svg>…</svg> markup, or a Font Awesome name
<ImageEditor
  image={url}
  options={{
    features: {
      imageEditor: {
        tools: {
          crop: { icon: 'fa-crop-simple' },
          text: { icon: 'https://example.com/icons/text.svg' },
        },
      },
    },
  }}
/>

Two things to keep in mind:

  • features is a remount-tier option (see the table above): changing the tools config destroys and recreates the editor, discarding unsaved edits — decide the toolset before mounting rather than toggling it live.
  • features.imageEditor: false disables the editing UI entirely; newer editor versions also support features.imageEditor.dock: 'left' | 'right' for the rail position and a corners entry (the rounded-corners control inside Crop) — these type-check once your @unlayer/types version includes them.

AI Assistant

The editor includes an optional AI Assistant for chat-based edits. It requires a projectId from your Unlayer account with the feature enabled.

Enable AI Assistant

<ImageEditor
  image={url}
  options={{
    projectId: 1234, // get from console
    features: { ai: { enabled: true, assistant: true } },
  }}
/>

Localization

Set options.locale (bundled: en, es, fr, de, it, pt, nl, ja, ko, zh) and optionally override strings with options.translations.

Demo

Try the live demo at react-image-editor-example.vercel.app, or run it locally — a Vite-based demo lives in demo/:

cd demo
npm install
npm run dev

License

Copyright (c) 2026 Unlayer. MIT Licensed.