# react-native-image-viewing: a modal gallery component with the gestures done

> react-native-image-viewing is a small TypeScript component for React Native that renders a full screen image gallery with pinch zoom, double tap zoom, swipe to close and optional header and footer slots. It saves a mobile team from rebuilding the gesture handling, at the cost of a package whose last published version is from 2022.

**jobtoday/react-native-image-viewing** — Tiny, purely TS, modal component for viewing images 🏙 

- Repository: https://github.com/jobtoday/react-native-image-viewing
- Website: https://exp.host/@antonkalinin/react-native-image-viewing
- Stars: 952 · Forks: 309
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/jobtoday-react-native-image-viewing

## A full screen gallery with the gestures already handled

The component does one job: it shows a set of images as a sliding gallery in a modal. The readme describes it as a React Native modal component for viewing images as a sliding gallery, and the repository description calls it a tiny, purely TypeScript modal component for viewing images.

What it saves you is gesture handling. The feature list names pinch zoom for both iOS and Android, double tap to zoom for both platforms, support for a swipe-to-close animation, custom header and footer components, and the use of `VirtualizedList` to optimise image loading and rendering.

That is the whole product. There is no theming system, no caching layer, no remote image pipeline and no gallery of your own content. It is a modal that takes an array of image sources and an index, and it gets out of the way.

The implementation is small enough to read. The repository has a `src/` directory, a `tsconfig.json` and a `package.json` whose build script is just `tsc`, so the published artefact is the compiled TypeScript with `main` pointing at `dist/index.js` and types at `dist/index.d.ts`. There are no runtime dependencies listed at all, only peer dependencies on `react` `>=16.11.0` and `react-native` `>=0.61.3`.

The author is Anton Kalinin, the licence is MIT, and there is an Expo example listed at expo.io under the same handle, so you can try the component without setting up a native project.

## VirtualizedList carries the rendering cost

The `VirtualizedList` mention is the most consequential line in the feature list and it is easy to skip past.

A gallery is the case where a naive implementation falls over. Each image is a full screen sized element, the user can swipe through hundreds of them, and rendering all of them at once means holding every decoded bitmap in memory. `VirtualizedList` renders a window around the current index and recycles the rest, so the memory cost tracks the screen rather than the album.

That also explains why the component exposes an index rather than a navigation model. You pass `imageIndex` as the current index to display and `images` as the array of sources, and the component owns the pager. The optional `keyExtractor` prop, typed as a function taking the image source and the index and returning a string, exists so you can supply stable identities for `VirtualizedList` when your sources do not carry them naturally.

Two callback props complete the loop back into your app. `onImageIndexChange` fires when the index changes, and `onLongPress` fires with the event and the image source, with `delayLongPress` controlling the delay in milliseconds before it is called and a default of `800`. So a long press can trigger a share sheet or a delete confirmation without you having to reimplement the press handling.

## The prop table is the real API documentation

The readme documents fifteen props, and the defaults are the interesting part.

Four are required: `images` typed as `ImageSource[]`, `imageIndex` as a number, `visible` as a boolean and `onRequestClose` as a function. The `ImageSource` type is given as `ImageURISource | ImageRequireSource`, which is the React Native union, so both remote URIs and `require`d local assets work.

The behaviour props each have a default you can turn off. `swipeToCloseEnabled` defaults to `true` and closes the modal on a swipe up or down. `doubleTapToZoomEnabled` defaults to `true`. `animationType` defaults to `fade` and accepts `none`, `fade` or `slide`. `presentationStyle` defaults to `fullScreen`, with the note that Android should use `overFullScreen` to hide the status bar, and accepts `fullScreen`, `pageSheet`, `formSheet` and `overFullScreen`. `backgroundColor` is a hex string, shown in the table as `#000000EE`.

The composition hooks are `HeaderComponent` and `FooterComponent`, each of which receives the current `imageIndex` as a prop. Passing the index rather than the whole gallery state is what lets a footer show a counter or a page control that stays in sync as the user swipes.

One line in the prop table deserves attention: the readme does not describe any accessibility props, and there is none in the list. If your application has an accessibility review process, that is a gap you will have to check yourself.

## Installing the package and rendering the first gallery

The package installs like any other React Native dependency.

```bash
yarn add react-native-image-viewing
```

or with npm.

```bash
npm install --save react-native-image-viewing
```

Because the peer dependencies are React and React Native themselves, there is no native module to link and no pod install step. The build script is plain `tsc`, so the package ships compiled JavaScript and type declarations.

Using it is a controlled component with a visible flag.

```jsx
import ImageView from "react-native-image-viewing";

const images = [
  {
    uri: "https://images.unsplash.com/photo-1571501679680-de32f1e7aad4",
  },
  {
    uri: "https://images.unsplash.com/photo-1573273787173-0eb81a833b34",
  },
  {
    uri: "https://images.unsplash.com/photo-1569569970363-df7b6160d111",
  },
];

const [visible, setIsVisible] = useState(false);

<ImageView
  images={images}
  imageIndex={0}
  visible={visible}
  onRequestClose={() => setIsVisible(false)}
/>
```

The component is controlled entirely by you. `visible` decides whether the modal is shown, `imageIndex` decides where it opens, and `onRequestClose` is where you set your state back to false. The readme links to a slice of the example app showing the same usage.

For contributing, the readme asks you to clone the repository, run `yarn` inside `react-native-image-viewing`, then go into the `example` folder and run `yarn & yarn start`, which starts the packager for Expo so changes in `/src/ImageViewing` show up in the example app.

## The release line is old, and the branch is newer

The version history needs reading carefully.

The published releases are v0.2.2 from 2022-04-18, v0.2.0 from 2020-05-24 and v0.1.8 from 2020-03-18. The last push to the default branch was on 2026-04-10. So the branch is receiving work, but the newest artefact on the registry is more than four years old.

That gap is the single most important fact for an adopter. An npm install of `react-native-image-viewing` gets you version 0.2.2, which was built against React Native 0.61 and TypeScript 3.7 era tooling. The peer dependency range in package.json is `react` `>=16.11.0` and `react-native` `>=0.61.3`, which is permissive enough to install, but permissive ranges say nothing about whether the component behaves correctly on a current React Native release.

The development dependencies tell a similar story. They pin `@types/react` at 16.9.13, `@types/react-native` at 0.60.23, `react` at 16.12.0, `react-native` at 0.61.5 and `typescript` at 3.7.2. So even the example app and the type definitions in the repository are from that era.

The MIT licence is the easy part. There is no copyleft obligation and no restriction on commercial use, and the component is small enough that vendoring it into your own codebase is a realistic option if the maintained version turns out not to fit.

## Where this component is the wrong tool

Four cases stand out.

First, a gallery that needs more than images. There is no video support, no caption or description field beyond what you pass through `HeaderComponent` and `FooterComponent`, and no thumbnail strip built in. Those are all things you can build on top, but they are your code.

Second, images that must load fast or work offline. The component renders `ImageSource` values and leaves loading to React Native's `Image`. There is no caching strategy, no prefetching of neighbours, and no progressive placeholder documented, so a gallery of large photographs on a slow connection is your problem to solve.

Third, a project with an accessibility or design system requirement. The prop table has no accessibility props, no theme tokens, and no styling API beyond `backgroundColor`. If your application has a design system, the header and footer you supply will carry that burden entirely.

Fourth, a project that needs an actively maintained dependency with a security response process. A package whose newest release is from 2022 gives you an audit question to answer, whatever the maintenance activity on the branch.

The comparison with writing your own modal is instructive. A hand written version in a React Native app means a `Modal`, a pager, and gesture handling for pinch, double tap and swipe, which is the part everybody gets wrong first. Using this component you get that behaviour on both platforms in a small dependency with no native linking. The alternative is not free code, it is a recurring maintenance line in your own repository, and that is a trade worth making for most apps.

## Conclusion

react-native-image-viewing suits a React Native app that needs a photo gallery modal and does not want to own pinch and double tap gesture handling, and it is the wrong tool for a project that needs image captions, video, offline caching or an actively maintained dependency. Before adopting it, check the peer dependency range, since package.json asks for `react` `>=16.11.0` and `react-native` `>=0.61.3`, and confirm the behaviour you need on your own React Native version, since the newest published release is v0.2.2 from 2022-04-18 while the last push to the default branch was on 2026-04-10.

## FAQ

### How do I install react-native-image-viewing?

Run `yarn add react-native-image-viewing` or `npm install --save react-native-image-viewing`. There is no native module to link, since the package declares only peer dependencies on `react` and `react-native`.

### What props does react-native-image-viewing require?

Four are required: `images` as an array of `ImageSource`, `imageIndex` as the current index, `visible` as a boolean and `onRequestClose` as a function. Optional props cover gesture toggles, animation type, presentation style, background colour and custom header and footer components.

### Does react-native-image-viewing support pinch and double tap zoom?

Yes, pinch zoom and double tap to zoom are both supported on iOS and Android. Double tap zoom can be turned off with `doubleTapToZoomEnabled` and swipe-to-close with `swipeToCloseEnabled`, both defaulting to true.

### Can I add a header or footer to the gallery?

The `HeaderComponent` and `FooterComponent` props accept a component or function that receives the current `imageIndex` as a prop, so a counter or page control stays in sync as the user swipes.

### Is react-native-image-viewing still maintained?

The default branch received a push on 2026-04-10, but the newest published release is v0.2.2 from 2022-04-18, so an npm install gives you a build from that release rather than the current branch.

## Sources

- [jobtoday/react-native-image-viewing on GitHub](https://github.com/jobtoday/react-native-image-viewing)
- [License: MIT](https://github.com/jobtoday/react-native-image-viewing/blob/master/LICENSE)
- [Project website](https://exp.host/@antonkalinin/react-native-image-viewing)
- [README](https://github.com/jobtoday/react-native-image-viewing/blob/master/README.md)
- [Releases](https://github.com/jobtoday/react-native-image-viewing/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/jobtoday-react-native-image-viewing
