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 🙏

© 2025 – Pkg Stats / Ryan Hefner

react-native-nitro-view-shot

v0.1.0

Published

react native view capture library built with Nitro Modules. Faster than bridge-based solutions with synchronous capture support.

Readme

react-native-nitro-view-shot

React Native view capture library built with Nitro Modules. Faster than traditional bridge-based solutions with synchronous capture support and zero serialization overhead.

Discord Version npm monthly License

Features

  • Synchronous capture API - Direct JSI calls without bridge serialization overhead
  • Multiple output formats - Support for PNG, JPG, and WebP (WebP not supported on iOS)
  • Flexible output options - File path or base64 string encoding
  • Automatic mount-time capture - Capture views as soon as they're laid out
  • Efficient file management - Automatic asynchronous cleanup of old captures
  • Lean native implementation - Direct native rendering without extra view wrappers
  • Familiar API - Similar to react-native-view-shot but optimized with Nitro Modules

Requirements

  • React Native v0.76.0 or higher
  • Node 18.0.0 or higher

[!IMPORTANT]
To support Nitro Views you need React Native v0.78.0 or higher.

Installation

bun add react-native-nitro-view-shot react-native-nitro-modules

Usage

Capture on mount

import NitroViewShot from 'react-native-nitro-view-shot'

export function MountCaptureExample() {
  return (
    <NitroViewShot
      options={{ fileName: 'welcome-card' }}
      captureMode="mount"
      onCapture={(path) => console.log('Captured to:', path)}
    >
      <View>{/* ...content... */}</View>
    </NitroViewShot>
  )
}

Manual capture via ref

import NitroViewShot, { type NitroViewShotRef } from 'react-native-nitro-view-shot'

const Example = () => {
  const shotRef = useRef<NitroViewShotRef>(null)

  return (
    <>
      <NitroViewShot
        ref={shotRef}
        options={{ fileName: 'profile-card', output: 'base64' }}
        onCapture={(result) => console.log('Got capture:', result)}
      >
        <View>{/* ... */}</View>
      </NitroViewShot>
      <Button
        title="Capture"
        onPress={() => {
          shotRef.current?.captureAsync({ fileName: 'profile-card', output: 'base64' })
        }}
      />
    </>
  )
}

Capture an arbitrary ref

import { captureRef } from 'react-native-nitro-view-shot'

const viewRef = useRef<View>(null)

const onPress = () => {
  const path = captureRef(viewRef, { fileName: 'inline-card' })
  console.log(path)
}

// In your render:
<View ref={viewRef} collapsable={false}>
  {/* Your content */}
</View>

API

Component

| Prop | Type | Description | | --- | --- | --- | | options | ViewShotOptions | Default options for captures. | | captureMode? | 'mount' \| 'none' | mount captures once layout is available; none requires manual trigger. | | onCapture? | (result: string) => void | Called after each capture (async or sync). |

Ref methods (NitroViewShotRef)

| Method | Signature | Description | | --- | --- | --- | | capture | (options?: ViewShotOptions) => string | Synchronous capture; returns result immediately. | | captureAsync | (options?: ViewShotOptions) => Promise<string> | Promise-based capture for async flows. |

Top-level helpers

| Function | Signature | Description | | --- | --- | --- | | captureRef | (ref, options: ViewShotOptions) => string | Synchronous capture of an arbitrary ref. | | captureRefAsync | (ref, options: ViewShotOptions) => Promise<string> | Promise-based capture of an arbitrary ref. |

ViewShotOptions

| Option | Type | Default | Description | | --- | --- | --- | --- | | fileName | string | — | Required. Filename; extension inferred from format if missing. | | format | 'png' \| 'jpg' \| 'webp' | png | Image format (iOS does not support webp). | | quality | number | 1.0 | 0.01.0, used for JPG/WEBP. | | output | 'file' \| 'base64' | file | Where to deliver the capture. |

Why NitroViewShot instead of react-native-view-shot?

React Native already has react-native-view-shot. NitroViewShot keeps the familiar API shape but leans on Nitro modules/JSI for a faster, more predictable experience:

  • Synchronous capture option: capture can return immediately because there is no legacy bridge hop; react-native-view-shot only exposes promise-based calls.
  • Capture as soon as views mount: captureMode: 'mount' fires after layout without writing your own onLayout/setTimeout plumbing to avoid zero-size captures.
  • Lean native path: Uses UIGraphicsImageRenderer on iOS and direct Canvas drawing on Android with no extra view wrappers beyond the component itself.

Notes

  • Files are written to a react-native-nitro-view-shot cache folder inside the platform temp directory; old captures are automatically deleted asynchronously to keep storage clean.
  • Mount captures wait for a non-zero layout before running to avoid invalid-size errors.
  • File deletion happens asynchronously in the background, ensuring fast capture performance without blocking operations.

Troubleshooting

Capture fails

Add collapsable={false} to the View you want to capture. React native optimizes away views without children, which can cause capture failures. This prop prevents that optimization.

<View collapsable={false}>
    {/* Your content */}
</View>

License

MIT © Patrick Kabwe

Credits

Bootstrapped with create-nitro-module.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

💬 For quick support, join our Discord channel