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

react-native-customizable-image-crop-picker

v1.1.3

Published

Fully customizable React Native image crop picker (JS UI + native performance).

Downloads

1,185

Readme

react-native-customizable-image-crop-picker

License NPM Downloads Platform - Android Platform - iOS

A high-performance, fully customizable image crop picker for React Native (iOS + Android).

  • Android: system photo picker / camera + uCrop
  • iOS: UIImagePickerController / camera + TOCropViewController

This library is developed and maintained by Amit Kumar.

Table of contents

Features

  • Camera + gallery
  • Cropping with configurable aspect ratio (cropWidth / cropHeight)
  • Circular crop (circularCrop)
  • Crop overlays: dimmed layer + grid (dimmedLayerColor, cropGridEnabled)
  • Native crop controls/toolbar via showNativeCropControls
  • Output compression controls (compressQuality, compressFormat)
  • Optional base64 output (includeBase64)
  • Native full-screen crop UI customization from JS (header/footer/buttons/icons/layout)
  • Icons: remote (http/https) + local (file:// / Android content://) + base64 + bundled assets (require(...))
  • Events: onCropStart, onCropEnd, onProgress (base64/encoding progress on Android + iOS)

Demo

Installation

npm install react-native-customizable-image-crop-picker --save

or

yarn add react-native-customizable-image-crop-picker

iOS

cd ios
pod install
cd ..

Permissions (Info.plist)

Add:

  • NSCameraUsageDescription
  • NSPhotoLibraryUsageDescription
  • NSPhotoLibraryAddUsageDescription

If CocoaPods fails: TOCropViewController modular headers

If pod install fails with a Swift modular headers error (TOCropViewController), add this to your app ios/Podfile (inside your app target):

pod 'TOCropViewController', :modular_headers => true

Then run pod install again.

If you see an rsync error about missing simulator slice (RN 0.84+ prebuilt pods)

cd ios
RCT_USE_PREBUILT_RNCORE=0 pod install
cd ..

Permissions

iOS (Info.plist)

Add:

  • NSCameraUsageDescription
  • NSPhotoLibraryUsageDescription
  • NSPhotoLibraryAddUsageDescription (only if saving to library)

Android

  • Request CAMERA permission at runtime before opening source: 'camera'.
  • Ensure the following is present (usually merged from the library):
<uses-permission android:name="android.permission.CAMERA" />

If you use remote icons (http/https) for buttons:

<uses-permission android:name="android.permission.INTERNET" />

Notes

  • iOS Simulator: camera isn’t available on the simulator. Test camera on a real device.

Quick start

import {
  openImageCropPicker,
} from 'react-native-customizable-image-crop-picker';

Select from gallery

const result = await openImageCropPicker({
  source: 'gallery',
  cropWidth: 1,
  cropHeight: 1,
});

console.log(result.path);

Select from camera

const result = await openImageCropPicker({
  source: 'camera',
  cropWidth: 1,
  cropHeight: 1,
});

Callbacks / progress (base64)

onProgress emits 0..1 while doing the slow work of generating base64 (only when includeBase64: true).

const result = await openImageCropPicker({
  source: 'gallery',
  includeBase64: true,
  onCropStart: () => console.log('crop started'),
  onProgress: (p) => console.log('progress', p), // 0..1 (Android: real streaming encode, iOS: best-effort)
  onCropEnd: (res, err) => console.log('crop end', { res, err }),
});

Examples (recommended)

Usage

Import:

import {
  openImageCropPicker,
} from 'react-native-customizable-image-crop-picker';

Select from gallery

const result = await openImageCropPicker({
  source: 'gallery',
  cropWidth: 1,
  cropHeight: 1,
});

console.log(result.path);

Select from camera

const result = await openImageCropPicker({
  source: 'camera',
  cropWidth: 1,
  cropHeight: 1,
});

Icons (including SVG on Android)

Button icon props like uploadButtonIconUri / cancelButtonIconUri accept:

  • Remote URI: https://...
  • Local file: file://...
  • Android content URI: content://...
  • Bundled asset: require('./icon.png') (recommended)

SVG

  • Android native UI supports SVG for these icon URIs.
  • iOS native UI does not support SVG (use PNG/JPG/WebP).

API: openImageCropPicker(options)

Backwards compatible alias: open(options)

Defaults shown below are the current native defaults.

Picker options

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | source | 'camera' \| 'gallery' | Yes | - | Open camera or gallery | | mediaType | 'photo' | No | 'photo' | Media type (photos only) |

Crop options

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | cropWidth | number | No | 100 | Aspect ratio width (native crop) | | cropHeight | number | No | 100 | Aspect ratio height (native crop) | | aspectRatio | { width: number; height: number } | No | - | Alternative to cropWidth/cropHeight | | freeStyleCropEnabled | boolean | No | false | If true, user can resize the crop box (free-style) | | circularCrop | boolean | No | false | Circular crop (iOS/Android) | | cropGridEnabled | boolean | No | false | Show crop grid (iOS/Android) | | cropOverlayColor | string | No | - | Alias for dimmedLayerColor | | cropFrameColor | string | No | - | Android: crop frame color | | cropGridColor | string | No | - | Android: crop grid color. iOS: used for circular grid overlay | | compressQuality | number | No | 1 | 0..1 (output encoding quality) | | compressFormat | 'jpeg' \| 'png' \| 'webp' | No | 'jpeg' | Output encoding format (iOS WebP is best-effort; falls back to JPEG if unavailable) | | includeBase64 | boolean | No | false | If true, resolves base64 (slower) |

Native full-screen crop UI (header/footer/buttons)

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | preferNativeUI | boolean | No | true | Prefer native full-screen UI (current implementation uses native UI) | | headerTitle | string | No | Preview Image | Native header title | | headerAlignment | 'left' \| 'center' \| 'right' | No | 'center' | Header title alignment | | headerHeight | number | No | 84 | Header height | | headerPaddingHorizontal | number | No | 20 | Header padding | | headerPaddingTop | number | No | 20 | Header padding | | headerPaddingBottom | number | No | 20 | Header padding | | controlsPlacement | 'bottom' \| 'top' | No | 'bottom' | Render actions in footer or header | | topLeftControl | 'cancel' \| 'upload' \| 'none' | No | 'cancel' | Left header control when controlsPlacement: 'top' | | topRightControl | 'cancel' \| 'upload' \| 'none' | No | 'upload' | Right header control when controlsPlacement: 'top' | | cancelText | string | No | Cancel | Cancel label | | uploadText | string | No | Upload | Upload label | | footerPaddingHorizontal | number | No | 20 | Footer padding | | footerPaddingTop | number | No | 16 | Footer padding | | footerPaddingBottom | number | No | 24 | Footer padding | | footerButtonGap | number | No | 12 | Gap between footer buttons | | footerButtonHeight | number | No | 54 | Button height | | footerButtonLayout | 'vertical' \| 'horizontal' | No | 'vertical' | Footer layout | | footerButtonOrder | 'uploadFirst' \| 'cancelFirst' | No | 'uploadFirst' | Footer order | | cancelButtonRadius | number | No | 28 | Cancel button radius | | uploadButtonRadius | number | No | 28 | Upload button radius |

Button content + icons

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | uploadButtonContent | 'text' \| 'icon' \| 'iconText' \| 'textIcon' \| 'TextIcon' \| 'icon+text' \| 'text+icon' | No | 'text' | Upload content mode | | cancelButtonContent | same as above | No | 'text' | Cancel content mode | | uploadButtonIconUri | string \| ImageSourcePropType | No | '' | Icon URI (http/https/file/content) or bundled asset require(...) | | cancelButtonIconUri | string \| ImageSourcePropType | No | '' | Icon URI (http/https/file/content) or bundled asset require(...) | | uploadButtonIconBase64 | string | No | '' | Icon base64 (optionally data:image/...;base64,) | | cancelButtonIconBase64 | string | No | '' | Icon base64 | | uploadButtonIconSize | number | No | 18 | Icon size | | cancelButtonIconSize | number | No | 18 | Icon size | | buttonIconGap | number | No | 8 | Gap between icon and text | | uploadButtonIconTintColor | string | No | '' | Tint (only applied if provided) | | cancelButtonIconTintColor | string | No | '' | Tint (only applied if provided) | | buttonContentPaddingHorizontal | number | No | 12 | Internal button padding (both buttons) | | buttonContentPaddingVertical | number | No | 0 | Internal button padding (both buttons) | | uploadButtonContentPaddingHorizontal | number | No | - | Upload internal padding override | | uploadButtonContentPaddingVertical | number | No | - | Upload internal padding override | | cancelButtonContentPaddingHorizontal | number | No | - | Cancel internal padding override | | cancelButtonContentPaddingVertical | number | No | - | Cancel internal padding override |

Using bundled images (require(...))

uploadButtonIconUri / cancelButtonIconUri accept:

  • a string URI (https://, file://, etc.)
  • or a bundled asset via require(...) (recommended)
import { openImageCropPicker } from 'react-native-customizable-image-crop-picker';

await openImageCropPicker({
  source: 'gallery',
  uploadButtonContent: 'icon',
  uploadButtonIconUri: require('./upload.jpg'),
});

Theme / status bar / overlay

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | isDarkTheme | boolean | No | false | Native theme hint | | statusBarColor | string | No | #FFFFFF (light), #000000 (dark) | Status bar color | | statusBarStyle | 'dark' \| 'light' | No | - | Android only: status bar icon/text color | | dimmedLayerColor | string | No | #B3000000 (light), #E0000000 (dark) | Dimmed overlay around crop box | | showNativeCropControls | boolean | No | false | Show native crop controls/toolbar |

showNativeCropControls + controlsPlacement

When showNativeCropControls: true, the native crop toolbar is visible.

  • To avoid the footer covering the native toolbar, showNativeCropControls works only with controlsPlacement: 'top'.
  • If you pass controlsPlacement: 'bottom', the library will auto-force it to 'top'.

Platform-specific props / behavior

  • Android only

    • drawUnderStatusBar: edge-to-edge header under the status bar.
    • statusBarStyle: controls status bar icons/text ('dark' | 'light').
    • cropFrameColor: crop frame color.
    • cropGridColor: crop grid line color (rectangle mode).
    • SVG button icons: uploadButtonIconUri / cancelButtonIconUri support SVG on Android native UI.
  • iOS only

    • compressFormat: 'webp': best-effort (falls back to JPEG if the encoder/type is unavailable).
  • Both (with small differences)

    • cropGridEnabled: rectangle uses native grid on iOS; circular uses a custom grid overlay.
    • showNativeCropControls: requires header controls (controlsPlacement: 'top'), library auto-forces when enabled.

Style objects (partial support)

These are read from React Native styles and mapped into native values (subset only).

| Prop | Type | Required | Default | Description | | --- | --- | --- | --- | --- | | headerStyle | { containerStyle?, titleStyle? } | No | - | Supports containerStyle.backgroundColor, titleStyle.color/fontSize/fontFamily | | footerStyle | { containerStyle?, cancelButtonStyle?, uploadButtonStyle?, cancelTextStyle?, uploadTextStyle? } | No | - | Supports background/border/textColor/fontSize/fontFamily/borderRadius subset |

Response Object

| Property | Type | Description | | --- | --- | --- | | path | string | Cropped image URI/path | | width | number | Image width (if available) | | height | number | Image height (if available) | | mime | string | MIME type (if available) | | size | number | Size in bytes (if available) | | exif | object | EXIF metadata (if available) | | base64 | string | Only when includeBase64: true |

Errors

The library throws CropPickerError with a code:

  • E_PICKER_CANCELLED
  • E_PERMISSION_MISSING
  • E_NO_IMAGE_DATA_FOUND
  • E_NO_APP_AVAILABLE
  • E_PICKER_ERROR
  • E_ACTIVITY_DOES_NOT_EXIST
  • E_MODULE_DESTROYED
  • E_UNAVAILABLE
  • E_INVALID_OPTIONS

Known limitations

  • Multiple selection options exist in types but native multiple picking is not implemented yet.
  • iOS grid/frame color customization is limited (rectangle grid uses the native overlay; circular grid uses a custom overlay).

Peer Dependencies

| Package | Version | | --- | --- | | react | >=18 | | react-native | >=0.72 |

Contributing

Contributions are welcome. Please open an issue with reproduction details or submit a PR with a clear description + test plan.

Support

  • Bug reports / feature requests: open an issue with a minimal repro (device/OS, RN version, and logs).
  • Questions / help: start a GitHub discussion or issue (whichever you prefer) with your use-case and desired UI.

License

MIT