react-cropper vs react-avatar-editor vs react-image-crop
React Image Cropping Libraries
react-cropperreact-avatar-editorreact-image-cropSimilar Packages:

React Image Cropping Libraries

react-avatar-editor, react-cropper, and react-image-crop are React libraries that enable image cropping functionality in web applications. They allow users to select a region of an image, adjust boundaries, enforce aspect ratios, and export the cropped result. Each takes a different technical approach: react-avatar-editor uses HTML canvas, react-cropper wraps the vanilla Cropper.js library, and react-image-crop implements cropping purely with React and CSS. These differences affect performance, customization, maintainability, and ease of integration.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-cropper374,5982,07820.5 kB153 years agoMIT
react-avatar-editor02,489148 kB5a month agoMIT
react-image-crop04,089112 kB72a year agoISC

React Image Cropping Libraries Compared: react-avatar-editor vs react-cropper vs react-image-crop

When you need to let users crop images in a React app — for profile pictures, content uploads, or design tools — you have several solid options. The three most common libraries are react-avatar-editor, react-cropper, and react-image-crop. They all solve the same basic problem but with very different approaches, APIs, and trade-offs. Let’s break them down from an engineering perspective.

🖼️ Core Philosophy: Canvas vs DOM vs Pure React

Each library uses a fundamentally different rendering strategy, which affects performance, customization, and integration.

react-avatar-editor uses the <canvas> element under the hood. It draws the image onto a canvas and manipulates it directly using 2D context APIs. This gives you pixel-level control and makes exporting easy, but limits styling flexibility.

import AvatarEditor from 'react-avatar-editor';

function Editor() {
  return (
    <AvatarEditor
      image="/photo.jpg"
      width={250}
      height={250}
      border={50}
      color={[255, 255, 255, 0.6]} // RGBA
      scale={1.2}
      rotate={0}
    />
  );
}

react-cropper wraps the popular Cropper.js library (a vanilla JavaScript tool) in a React component. It manipulates the DOM directly using absolute-positioned overlays on top of an <img> tag. This means it’s not "React-native" — it uses refs and side effects heavily.

import Cropper from 'react-cropper';
import 'cropperjs/dist/cropper.css';

function Editor() {
  const cropperRef = useRef(null);

  const getCropData = () => {
    const imageElement = cropperRef?.current;
    const cropper = imageElement?.cropper;
    console.log(cropper.getCroppedCanvas().toDataURL());
  };

  return (
    <>
      <Cropper
        src="/photo.jpg"
        style={{ height: 400, width: '100%' }}
        initialAspectRatio={1}
        guides={false}
        ref={cropperRef}
      />
      <button onClick={getCropData}>Crop</button>
    </>
  );
}

react-image-crop is built entirely with React and CSS — no canvas, no external DOM manipulation. It uses absolutely positioned <div> elements to draw the crop area over an <img>. This makes it lightweight and easier to theme with standard CSS.

import React, { useState } from 'react';
import ReactCrop from 'react-image-crop';
import 'react-image-crop/dist/ReactCrop.css';

function Editor() {
  const [crop, setCrop] = useState({ aspect: 1 });

  return (
    <ReactCrop
      src="/photo.jpg"
      crop={crop}
      onChange={c => setCrop(c)}
    />
  );
}

📐 Aspect Ratio & Constraint Handling

How each library enforces aspect ratios and minimum/maximum sizes varies significantly.

react-avatar-editor only supports fixed width and height. You define exact pixel dimensions, and the crop area is always that size. There’s no dynamic resizing by the user — they can only move and zoom the image within the fixed frame.

// Fixed 300x300 crop area — user cannot change shape
<AvatarEditor width={300} height={300} />

react-cropper offers full control: freeform, fixed aspect ratio, min/max dimensions, and even grid snapping. You configure this via props like aspectRatio, minWidth, viewMode, etc.

<Cropper
  aspectRatio={16 / 9}
  minWidth={200}
  minHeight={100}
  viewMode={1} // restrict crop box to container
/>

react-image-crop supports both freeform and fixed aspect ratios, and lets users resize the crop box unless you lock it. You control behavior via the crop state object.

// Allow user to resize, but keep 1:1 aspect
const [crop, setCrop] = useState({ unit: '%', width: 50, aspect: 1 });

<ReactCrop crop={crop} onChange={setCrop} />

🖨️ Exporting Cropped Images

Getting the final cropped image out is critical — and the methods differ.

react-avatar-editor provides a direct method to get a canvas reference, then export as data URL or blob:

const editorRef = useRef(null);

const handleSave = () => {
  if (editorRef.current) {
    const canvas = editorRef.current.getImage();
    const dataUrl = canvas.toDataURL();
    // Or: canvas.toBlob(blob => upload(blob));
  }
};

<AvatarEditor ref={editorRef} />

react-cropper requires accessing the underlying Cropper.js instance through a ref:

const cropperRef = useRef(null);

const handleSave = () => {
  const cropper = cropperRef.current?.cropper;
  if (cropper) {
    const canvas = cropper.getCroppedCanvas();
    const dataUrl = canvas.toDataURL('image/jpeg');
  }
};

<Cropper ref={cropperRef} />

react-image-crop doesn’t include export logic — you must implement cropping yourself using a canvas:

import { getCroppedImg } from './utils'; // You write this

const [completedCrop, setCompletedCrop] = useState(null);

useEffect(() => {
  if (completedCrop?.width && completedCrop?.height) {
    getCroppedImg(imageRef.current, completedCrop)
      .then(canvas => canvas.toDataURL());
  }
}, [completedCrop]);

<ReactCrop onComplete={c => setCompletedCrop(c)} />

The library provides a helper example in its docs, but you own the implementation.

🎨 Styling and Customization

react-avatar-editor is hard to style beyond background color and border size because it’s canvas-based. You can’t use CSS to change handles or overlay appearance.

react-cropper inherits Cropper.js’s extensive but non-React styling system. You override CSS classes like .cropper-view-box or .cropper-face. This works but feels disconnected from your component tree.

react-image-crop exposes CSS classes you can target (e.g., .ReactCrop__crop-selection), and since it’s pure React + CSS, you can easily wrap it in styled-components or pass custom class names.

⚙️ Maintenance Status (Critical!)

As of 2024:

  • react-avatar-editor is deprecated. Its npm page states: "This package has been deprecated. Please use @davidtheclark/react-avatar-editor instead." However, the suggested fork hasn’t gained traction and lacks recent updates. Avoid in new projects.
  • react-cropper is actively maintained and tracks updates to Cropper.js.
  • react-image-crop is actively maintained, with regular releases and TypeScript support.

🧪 Real-World Use Case Guidance

Use react-cropper if:

  • You need advanced features like rotation, flipping, zoom-to-pointer, or grid guides.
  • Your designers require pixel-perfect control over the UI (via CSS overrides).
  • You’re okay with a larger bundle and non-React internals.

Use react-image-crop if:

  • You want a lightweight, React-first solution.
  • Your app uses modern React patterns (hooks, functional components).
  • You prefer to own the export logic for maximum flexibility (e.g., Web Workers for large images).
  • You need TypeScript support out of the box.

Avoid react-avatar-editor if:

  • You’re starting a new project — it’s deprecated.
  • You need user-resizable crop areas — it only supports fixed frames.
  • You care about long-term maintenance.

📊 Summary Table

Featurereact-avatar-editorreact-cropperreact-image-crop
RenderingCanvasDOM (Cropper.js wrapper)Pure React + CSS
User Resizing❌ Fixed frame only✅ Full control✅ Configurable
Aspect Ratio Lock❌ (Fixed dims only)✅ Yes✅ Yes
Export Built-in✅ Direct canvas access✅ Via Cropper.js API❌ Manual implementation
Styling Flexibility❌ Very limited✅ Via global CSS✅ Component-scoped CSS
Maintenance Status⚠️ Deprecated✅ Active✅ Active
Bundle ImpactMediumLarge (includes Cropper.js)Small

💡 Final Recommendation

For new projects, choose between react-cropper and react-image-crop based on your needs:

  • Need batteries-included, enterprise-grade cropping with minimal custom code? → react-cropper.
  • Prefer lightweight, composable, React-native behavior and don’t mind writing a few lines for export? → react-image-crop.

And do not use react-avatar-editor in any new codebase — its deprecation makes it a technical liability.

How to Choose: react-cropper vs react-avatar-editor vs react-image-crop

  • react-cropper:

    Choose react-cropper when you need a mature, feature-rich cropping experience with advanced capabilities like rotation, zoom-to-pointer, grid guides, and precise aspect ratio controls. It’s ideal if your team is comfortable working with a DOM-manipulating wrapper around a vanilla JS library and can manage the larger bundle size. Ensure you’re prepared to customize appearance via global CSS overrides rather than React props.

  • react-avatar-editor:

    Do not use react-avatar-editor in new projects — it is officially deprecated as noted on its npm page. While it offers simple canvas-based cropping with fixed dimensions, its lack of active maintenance and inability to support user-resizable crop areas make it unsuitable for modern applications. If you encounter it in legacy code, plan a migration to an alternative.

  • react-image-crop:

    Choose react-image-crop for a lightweight, React-native solution that integrates cleanly with modern hooks-based architecture and TypeScript. It’s best when you want full control over the export pipeline (e.g., offloading cropping to a Web Worker) and prefer styling via standard CSS or CSS-in-JS. Accept that you’ll need to implement the canvas-based image extraction logic yourself, though the library provides clear examples.

README for react-cropper

react-cropper

Cropperjs as React component

NPM NPM NPM downloads Bundle Size minZip Bundle Size min License codecov

Demo

Click for a Demo

Docs

Installation

Install via npm

npm install --save react-cropper

You need cropper.css in your project which is from cropperjs. Since this project have dependency on cropperjs, it located in /node_modules/react-cropper/node_modules/cropperjs/dist/cropper.css or node_modules/cropperjs/dist/cropper.css for npm version 3.0.0 later

Quick Example

import React, { useRef } from "react";
import Cropper, { ReactCropperElement } from "react-cropper";
import "cropperjs/dist/cropper.css";

const Demo: React.FC = () => {
  const cropperRef = useRef<ReactCropperElement>(null);
  const onCrop = () => {
    const cropper = cropperRef.current?.cropper;
    console.log(cropper.getCroppedCanvas().toDataURL());
  };

  return (
    <Cropper
      src="https://raw.githubusercontent.com/roadmanfong/react-cropper/master/example/img/child.jpg"
      style={{ height: 400, width: "100%" }}
      // Cropper.js options
      initialAspectRatio={16 / 9}
      guides={false}
      crop={onCrop}
      ref={cropperRef}
    />
  );
};

Options

src

  • Type: string
  • Default: null
<Cropper src="http://fengyuanchen.github.io/cropper/images/picture.jpg" />

alt

  • Type: string
  • Default: picture

crossOrigin

  • Type: string
  • Default: null

dragMode

https://github.com/fengyuanchen/cropperjs#dragmode

scaleX

https://github.com/fengyuanchen/cropperjs#scalexscalex

scaleY

https://github.com/fengyuanchen/cropperjs#scalexscaley

enable

https://github.com/fengyuanchen/cropperjs#enable

disable

https://github.com/fengyuanchen/cropperjs#disable

zoomTo

https://github.com/fengyuanchen/cropperjs#zoomto

rotateTo

https://github.com/fengyuanchen/cropperjs#rotateto

Other options

Accept all options in the docs as properties.

Methods

Use the cropper instance from onInitialized to access cropperjs methods

Build

npm run build

Development

npm start

Author

Fong Kuanghuei

Maintainer

Shubhendu Shekhar

License

MIT