react-avatar-editor
A React canvas component for interactive avatar and profile picture cropping, resizing, and rotation.
Repository Health
Technical Analysis
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.
Used by 5 apps in this directory
LibreChat
Developer Tools · AI Assistants
Unite every major AI model in one self-hosted chat platform with agents, code execution, MCP tools, and enterprise authentication.
LibrePhotos
File Storage
Self-hosted photo library with AI-powered face recognition, semantic search, and automatic event albums — no cloud required.
LimeSurvey
Forms Surveys
The world's most flexible open-source survey platform with 900+ templates, conditional logic, 80+ languages, and full GDPR compliance for any scale.
Notesnook
Note Taking · File Storage · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Outline
Knowledge Management · Collaboration
A fast, real-time collaborative knowledge base for growing teams built on React, Node.js, and ProseMirror.