react-avatar-editor

A React canvas component for interactive avatar and profile picture cropping, resizing, and rotation.

Library
npm
v15.1.0
2,499stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
51/100Fair
Development Activity8
Maintenance20
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
77/100Good
Architecture88
Code Quality90
Innovation68
Learning Curve60

react-avatar-editor is a lightweight React component that renders an interactive HTML canvas for cropping, resizing, and rotating profile pictures and avatars. It ships a fully typed core package (@react-avatar-editor/core) that separates the pure image-manipulation math from the React rendering layer, plus a useAvatarEditor hook that gives function components ref-free access to the editor’s imperative API.

The component supports mouse, touch, and keyboard interaction out of the box, including pinch-to-zoom on touch devices and trackpads, arrow-key repositioning, and optional wheel-based zoom, along with configurable border, border radius for circular or pill-shaped crops, grid overlays, and background color for transparent images. It has zero runtime dependencies beyond React itself and supports React 17 through 19.

What You Get

  • An <AvatarEditor> canvas component with drag, touch, pinch, and keyboard interaction built in
  • A useAvatarEditor() hook for ref-free access to getImage, getImageScaledToCanvas, and getCroppingRect
  • Full TypeScript types for props, ref methods, and the underlying ImageState/Position shapes
  • A framework-agnostic @react-avatar-editor/core package containing the canvas math, usable independently of React

Common Use Cases

  • Cropping and uploading a profile picture during signup or account settings
  • Standardizing headshots or product photos in an admin dashboard
  • Building a drag-and-drop image uploader alongside react-dropzone
  • Adding animated zoom or rotate controls driven by an external animation library

Under The Hood

Architecture The project is a pnpm monorepo split into packages/core (AvatarEditorCore in AvatarEditor.ts), a framework-agnostic class that owns all canvas math, cropping-rect calculation, drag-position math, and paint routines, and packages/lib (src/index.ts), a React wrapper that instantiates one AvatarEditorCore per component instance via useRef and drives it through hooks. State that must avoid stale closures in document-level event listeners (drag position, pinch state, latest prop values) is deliberately kept in refs rather than React state, while drag, loading, and imageState remain in useState to trigger re-renders. This separation means the core crop/zoom/rotate logic can be tested and reasoned about independently of React, and a change to the canvas math only touches core.

Tech Stack TypeScript throughout, built with Vite (vite-plugin-dts for type declarations) and tested with Vitest, including a jsdom environment for the React layer and coverage via @vitest/coverage-v8. The workspace uses pnpm workspaces with oxlint/oxfmt for linting and formatting instead of ESLint/Prettier. A separate packages/demo app (using motion, react-dropzone) is deployed via Wrangler/Cloudflare and doubles as living documentation for the props API.

Code Quality Both packages carry unit test suites (Vitest, React Testing Library for the component layer), and packages/lib additionally runs Playwright-based visual regression tests against committed screenshot baselines covering zoom, rotation, resize, and keyboard-accessibility scenarios. CI (GitHub Actions) runs install, build, lint, format-check, both unit test suites, and the Playwright visual suite on every push, so regressions in rendering output are caught automatically rather than relying on manual review.

API Design The public surface is a single <AvatarEditor> component with a wide but well-documented props table (covering size, border, mask color/shape, grid, boundary/HiDPI/rotation toggles, and a full set of lifecycle callbacks), plus a useAvatarEditor() hook that wraps the imperative ref API (getImage, getImageScaledToCanvas, getCroppingRect) so consumers avoid manual ref plumbing and get null-safe fallbacks when the editor isn’t ready. The design favors flexibility over minimalism: most crop/zoom/rotate behavior is configurable via props rather than hardcoded, which lowers friction for common cases (a plain <AvatarEditor image={...} /> renders a usable editor) while still exposing lower-level controls for custom UIs.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search