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-image-annotator

v0.2.10

Published

A comprehensive image annotation library for React Native

Readme

React Native Image Annotator

A comprehensive image annotation library for React Native that allows users to draw, add text, and shapes to images, with support for saving in various formats including base64.

React Native Image Annotator

Features

  • Multiple annotation tools: pen, line, rectangle, circle, arrow, text, and eraser
  • Color and stroke width selection
  • Undo/redo functionality
  • Enhanced zoom and pan support with pinch-to-zoom
  • Smooth pen drawing with bezier curves
  • Draggable text annotations with selection state
  • Support for base64 encoded images, URLs, and local images
  • Automatic orientation handling (portrait/landscape)
  • Export annotations in various formats (PNG, JPG, Base64)
  • Customizable UI with flexible toolbar positioning
  • Custom image styling support
  • Stable annotation positioning (annotations stay in place when toolbar is toggled)
  • TypeScript support
  • Comprehensive example app

Installation

npm install react-native-image-annotator
# or
yarn add react-native-image-annotator

Dependencies

This library depends on the following packages:

npm install react-native-gesture-handler react-native-reanimated react-native-svg react-native-view-shot
# or
yarn add react-native-gesture-handler react-native-reanimated react-native-svg react-native-view-shot

Corepack Support

This project uses Corepack to ensure consistent package manager usage. Corepack is included by default with Node.js versions 16.9+ and 14.19+.

To enable Corepack, run:

corepack enable

This will ensure that the correct version of Yarn (1.22.21) is used when working with this project. For more information about Corepack, visit Yarn's Corepack documentation.

Usage

import React, { useState } from 'react';
import { View, Button, StyleSheet, Switch, Text } from 'react-native';
import { ImageAnnotator } from 'react-native-image-annotator';
import { GestureHandlerRootView } from 'react-native-gesture-handler';

// Example base64 image (this is a tiny placeholder - use your actual base64 string)
const SAMPLE_BASE64 =
  'iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAnElEQVR42u3RAQ0AAAjDMO5fNCCDkC5z0HSOmIUKEBABASIgAgJEQIAICBABERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgQAQEiIAAERAgAiIgJ1MAARZcZy0rAAAAAElFTkSuQmCC';

const App = () => {
  const [annotatedImage, setAnnotatedImage] = useState(null);
  const [useBase64, setUseBase64] = useState(false);
  const [showToolbar, setShowToolbar] = useState(true);
  const [toolbarPosition, setToolbarPosition] = useState('bottom');

  const handleSaveImage = (result, format) => {
    console.log('Saved image in format:', format);
    setAnnotatedImage(result);
  };

  // Choose between URL and base64 image source
  const imageSource = useBase64
    ? { base64: SAMPLE_BASE64 }
    : { uri: 'https://picsum.photos/600/400' };

  return (
    <GestureHandlerRootView style={styles.container}>
      <View style={styles.buttonContainer}>
        <Button
          title={useBase64 ? 'Switch to URL image' : 'Switch to Base64 image'}
          onPress={() => setUseBase64(!useBase64)}
        />

        <View style={styles.controlRow}>
          <Text>Show Toolbar: </Text>
          <Switch value={showToolbar} onValueChange={setShowToolbar} />
        </View>

        <View style={styles.controlRow}>
          <Text>Toolbar Position: </Text>
          <Button
            title={toolbarPosition === 'bottom' ? 'Bottom' : 'Top'}
            onPress={() =>
              setToolbarPosition(
                toolbarPosition === 'bottom' ? 'top' : 'bottom'
              )
            }
          />
        </View>
      </View>

      <ImageAnnotator
        source={imageSource}
        onSaveImage={handleSaveImage}
        defaultTool="pen"
        defaultColor="#FF0000"
        defaultStrokeWidth={4}
        enableZoom={true}
        showToolbar={showToolbar}
        toolbarPosition={toolbarPosition}
        imageStyle={{
          borderRadius: 10,
          borderWidth: 1,
          borderColor: '#ddd',
        }}
        textOptions={{
          fontSize: 20,
          fontWeight: 'bold',
        }}
      />
    </GestureHandlerRootView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  buttonContainer: {
    padding: 10,
  },
  controlRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginTop: 10,
  },
});

export default App;

Testing the Library

Option 1: Add to Your Existing React Native Project

The easiest way to test this library is to add it to your existing React Native project:

# Navigate to your React Native project
cd your-react-native-project

# Install the library and its dependencies
yarn add react-native-image-annotator react-native-gesture-handler react-native-reanimated react-native-svg react-native-view-shot

# For iOS, install pods
cd ios && pod install && cd ..

Then, add the component to one of your screens:

import { ImageAnnotator } from 'react-native-image-annotator';
import { GestureHandlerRootView } from 'react-native-gesture-handler';

function MyScreen() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <ImageAnnotator
        source={{ uri: 'https://picsum.photos/600/400' }}
        onSaveImage={(result, format) => console.log(result, format)}
        containerStyle={{ height: 400 }}
      />
    </GestureHandlerRootView>
  );
}

Option 2: Create a New Test Project

Automatic Setup (Recommended)

We provide a script that automatically creates a test React Native project with the library and example code already set up:

# Clone the repository
git clone https://github.com/kuldeep2022/react-native-image-annotator.git
cd react-native-image-annotator

# Make the script executable (if needed)
chmod +x create-test-app.sh

# Run the script (creates a project named "ImageAnnotatorTest" by default)
./create-test-app.sh

# Or specify a custom project name
./create-test-app.sh MyTestApp

The script will:

  1. Create a new React Native project
  2. Install all required dependencies
  3. Link the local library
  4. Configure babel.config.js for Reanimated
  5. Create an example App.js file
  6. Install pods for iOS (if on macOS)

After the script completes, you can run the test app:

cd ImageAnnotatorTest  # or your custom project name
npx react-native run-ios     # For iOS
npx react-native run-android # For Android

Manual Setup

Alternatively, you can manually create a test project:

# Create a new React Native project
npx react-native init ImageAnnotatorTest

# Navigate to the project
cd ImageAnnotatorTest

# Install the library and its dependencies
yarn add react-native-image-annotator react-native-gesture-handler react-native-reanimated react-native-svg react-native-view-shot

# Update babel.config.js to include the Reanimated plugin
# Add this line to the plugins array: "react-native-reanimated/plugin"

# For iOS, install pods
cd ios && pod install && cd ..

Then replace the content of App.js with the example code from our INTEGRATION.md file.

For detailed integration instructions, see the INTEGRATION.md guide.

The example app demonstrates:

  • Image selection
  • Tool selection (pen, line, rectangle, circle, arrow, text, eraser)
  • Color selection
  • Annotation with the selected tool and color
  • Exporting the annotated image in various formats (PNG, JPG, Base64)
  • Viewing the exported result

Example App

Props

| Prop | Type | Default | Description | | ------------------ | ------------------------------------------------- | ----------- | ----------------------------------------------------------- | | source | { uri: string } \| number \| { base64: string } | Required | The image source (URI, require, or base64 string) | | initialPaths | AnnotationPath[] | [] | Initial annotation paths | | containerStyle | object | {} | Style for the container | | imageStyle | object | {} | Custom style for the image | | toolbarPosition | 'bottom' \| 'top' | 'bottom' | Position of the toolbar | | defaultTool | AnnotationTool | 'pen' | Default selected tool | | defaultColor | string | '#FF0000' | Default color | | defaultStrokeWidth | number | 4 | Default stroke width | | onPathsChange | (paths: AnnotationPath[]) => void | - | Callback when paths change | | onSaveImage | (result: string, format: string) => void | - | Callback when image is saved | | enableZoom | boolean | true | Enable zoom and pan | | enableUndo | boolean | true | Enable undo functionality | | enableRedo | boolean | true | Enable redo functionality | | showToolbar | boolean | true | Show/hide the annotation toolbar without losing annotations | | textOptions | object | {} | Options for text annotations |

Types

AnnotationTool

type AnnotationTool =
  | 'pen'
  | 'line'
  | 'rectangle'
  | 'circle'
  | 'arrow'
  | 'text'
  | 'eraser';

ExportFormat

type ExportFormat = 'png' | 'jpg' | 'base64';

ExportOptions

type ExportOptions = {
  format: ExportFormat;
  quality?: number; // 0-1, default 1
  result?: 'file' | 'base64'; // How the result should be returned
  filename?: string; // Only used when result is 'file'
};

Advanced Usage

Custom Toolbar

You can create a custom toolbar by using the exported types and utility functions:

import React, { useState, useRef } from 'react';
import { View, Button } from 'react-native';
import { ImageAnnotator, captureView } from 'react-native-image-annotator';

const CustomToolbarExample = () => {
  const [tool, setTool] = useState('pen');
  const [color, setColor] = useState('#000000');
  const annotatorRef = useRef(null);

  const saveAsBase64 = async () => {
    try {
      const result = await captureView(annotatorRef, {
        format: 'base64',
        quality: 1,
      });
      console.log('Base64 image:', result);
    } catch (error) {
      console.error('Error saving image:', error);
    }
  };

  return (
    <View style={{ flex: 1 }}>
      <View style={{ flexDirection: 'row', padding: 10 }}>
        <Button title="Pen" onPress={() => setTool('pen')} />
        <Button title="Line" onPress={() => setTool('line')} />
        <Button title="Save as Base64" onPress={saveAsBase64} />
      </View>

      <ImageAnnotator
        ref={annotatorRef}
        source={{ uri: 'https://example.com/image.jpg' }}
        defaultTool={tool}
        defaultColor={color}
      />
    </View>
  );
};

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Acknowledgments

  • Thanks to all contributors who have helped improve this library
  • Inspired by the need for a flexible and powerful image annotation tool in React Native