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

@oguzhnatly/react-native-image-manipulator

v1.0.17

Published

ImageManipulator for react native without Expo and Unimodules. Based on Expo ImageManipulator

Readme

🖼 react-native-image-manipulator

Crop, rotate, flip, and resize images in React Native without Expo or Unimodules. Fully typed. Built on the same API as expo-image-manipulator so it feels familiar, but works in any bare React Native project.

npm version npm downloads license platforms


Why this package?

Most image manipulation libraries for React Native either require Expo or pull in a heavy dependency tree through Unimodules. This package is a standalone drop-in that gives you the same clean, chainable API without any of that overhead. Crop, rotate, flip, resize, compress and export to JPEG or PNG in a single call.


Features

  • ✅ No Expo or Unimodules dependency
  • ✅ Full TypeScript support with typed actions and return values
  • ✅ Works on iOS and Android
  • ✅ Crop, rotate, flip, and resize in a single invocation
  • ✅ Chain multiple transformations in one call
  • ✅ JPEG and PNG output formats
  • ✅ Optional Base64 output alongside the file URI
  • ✅ Configurable compression level

Installation

npm install @oguzhnatly/react-native-image-manipulator
yarn add @oguzhnatly/react-native-image-manipulator

iOS Setup

Install native pods after adding the package:

cd ios && pod install

Mostly Automatic Installation (React Native < 0.60)

react-native link @oguzhnatly/react-native-image-manipulator

Android Setup

No additional setup required for Android on React Native 0.60+. The package links automatically via autolinking.

Manual Linking (React Native < 0.60)

iOS

  1. In Xcode, right click Libraries and select Add Files to [your project]
  2. Navigate to node_modules/@oguzhnatly/react-native-image-manipulator and add RNImageManipulator.xcodeproj
  3. In your project target, go to Build PhasesLink Binary With Libraries and add libRNImageManipulator.a

Android

Add the following to android/settings.gradle:

include ':react-native-image-manipulator'
project(':react-native-image-manipulator').projectDir = new File(rootProject.projectDir, '../node_modules/@oguzhnatly/react-native-image-manipulator/android')

Add the following to the dependencies block in android/app/build.gradle:

implementation project(':react-native-image-manipulator')

Open android/app/src/main/java/[...]/MainActivity.java and add:

import com.oguzhnatly.rnimagemanipulator.RNImageManipulatorPackage;

Then register the package inside getPackages():

new RNImageManipulatorPackage()

Usage

Basic Example

import RNImageManipulator from '@oguzhnatly/react-native-image-manipulator';

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ rotate: 90 }, { flip: { vertical: true } }],
  { format: 'png' }
);

console.log(result.uri);    // URI of the output image
console.log(result.width);  // Output image width
console.log(result.height); // Output image height

Resize with Aspect Ratio Preserved

Provide only one dimension and the other is calculated automatically:

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ resize: { width: 800 } }],
  { format: 'jpeg', compress: 0.9 }
);

Crop to a Specific Region

const result = await RNImageManipulator.manipulate(
  imageUri,
  [{ crop: { originX: 50, originY: 50, width: 400, height: 400 } }],
  { format: 'jpeg', compress: 1 }
);

Multiple Transformations in One Call

Actions are applied in the order they are provided:

const result = await RNImageManipulator.manipulate(
  imageUri,
  [
    { rotate: 90 },
    { flip: { horizontal: true } },
    { resize: { width: 600 } },
    { crop: { originX: 0, originY: 0, width: 600, height: 400 } },
  ],
  { format: 'jpeg', compress: 0.85, base64: true }
);

// result.base64 is available when base64: true
const dataUri = `data:image/jpeg;base64,${result.base64}`;

API

RNImageManipulator.manipulate(uri, actions, saveOptions)

Applies a sequence of transformations to the image at uri and writes the result to a new file. The source file is never modified.

Parameters

| Parameter | Type | Required | Description | |---------------|-----------------|----------|-------------------------------------------------------| | uri | string | Yes | URI of the source image. Must be within app scope | | actions | Action[] | Yes | Ordered array of transformations to apply | | saveOptions | SaveOptions | Yes | Output format, compression level, and base64 flag |

Action Types

resize

{ resize: { width?: number; height?: number } }

Resizes the image. If only one dimension is provided, the other is computed automatically to preserve the original aspect ratio.

rotate

{ rotate: number }

Rotates the image by the given number of degrees. Positive values rotate clockwise, negative values rotate counter-clockwise.

flip

{ flip: { vertical?: boolean; horizontal?: boolean } }

Flips the image along the specified axis or axes. Both can be set to true at the same time.

crop

{ crop: { originX: number; originY: number; width: number; height: number } }

Crops the image to a rectangle. originX and originY define the top-left corner of the crop area in pixels relative to the current image size.

Save Options

| Option | Type | Default | Description | |------------|------------------------|------------|--------------------------------------------------------------------------| | format | 'jpeg' | 'png' | 'jpeg' | Output format. PNG is lossless. JPEG produces smaller files with compression artifacts | | compress | number (0 to 1) | 1 | Compression amount. 1 means no compression. 0 is maximum compression. Only applies to JPEG | | base64 | boolean | false | When true, the result includes a base64 string of the output image |

Return Value

{
  uri: string;      // URI to the output image file
  width: number;    // Width of the output image in pixels
  height: number;   // Height of the output image in pixels
  base64?: string;  // Base64 encoded image data, present only when saveOptions.base64 is true
}

Prepend data:image/jpeg;base64, or data:image/png;base64, to the base64 value to construct a data URI usable directly in an <Image> source.


Notes

  • Each call to manipulate always produces a new file. Passing the same URI as input and overwriting is not supported due to how React Native caches images.
  • Actions are applied sequentially in the order provided. The output of each action becomes the input for the next.
  • Rotation that is not a multiple of 90 degrees may introduce transparent padding on iOS depending on the image dimensions.

Changelog

See CHANGELOG.md for release history.


License

MIT © Oguzhan Atalay