Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
captureRef
✓ import { captureRef } from 'react-native-view-shot'
✗ const captureRef = require('react-native-view-shot').captureRef
Primarily used with `useRef` to capture a specific component instance. CommonJS `require` is generally not recommended in modern React Native projects due to Metro's ESM preference.
ViewShot
✓ import ViewShot from 'react-native-view-shot'
✗ import { ViewShot } from 'react-native-view-shot'
ViewShot is a default export. Attempting to import it as a named export `{ ViewShot }` will result in an undefined module. It is used as a wrapper component for content intended for capture.
captureScreen
✓ import { captureScreen } from 'react-native-view-shot'
✗ import ViewShot, { captureScreen } from 'react-native-view-shot'
Captures the entire device screen without requiring a wrapper component. Note its functionality, particularly on iOS, was improved and fixed in v3.3.0.
CaptureOptions
✓ import type { CaptureOptions } from 'react-native-view-shot'
TypeScript type for defining capture parameters such as format, quality, width, height, and file name. Essential for type-safe configuration of capture operations.
Demonstrates how to use the `ViewShot` component with a `useRef` hook to capture a specific React Native view. The example sets capture options for PNG format and logs the resulting image URI, also showing an optional preview. Saving to the camera roll is commented out as it requires additional setup and permissions.
import React, { useRef, useState } from 'react';
import { Button, View, Text, Alert, Image, StyleSheet } from 'react-native';
import ViewShot from 'react-native-view-shot';
import { CameraRoll } from '@react-native-camera-roll/camera-roll'; // Peer dependency for saving
// Note: @react-native-camera-roll/camera-roll requires separate installation and linking,
// as well as appropriate permissions (e.g., WRITE_EXTERNAL_STORAGE on Android, NSPhotoLibraryUsageDescription on iOS).
const MyViewCapture = () => {
const viewShotRef = useRef<ViewShot>(null);
const [capturedUri, setCapturedUri] = useState<string | null>(null);
const captureView = async () => {
if (viewShotRef.current) {
try {
// Capture the view with specified options
const uri = await viewShotRef.current.capture();
setCapturedUri(uri);
console.log('Image captured to:', uri);
Alert.alert('Capture Success', `Image URI: ${uri}`);
// Optional: Save to camera roll (requires @react-native-camera-roll/camera-roll and permissions)
// try {
// const result = await CameraRoll.save(uri, { type: 'photo' });
// Alert.alert('Saved', `Image saved to camera roll: ${result}`);
// } catch (saveError) {
// console.error('Failed to save to camera roll:', saveError);
// Alert.alert('Save Error', `Failed to save image: ${saveError}`);
// }
} catch (error) {
console.error('Failed to capture view:', error);
Alert.alert('Capture Error', `Failed to capture view: ${error}`);
}
} else {
Alert.alert('Error', 'ViewShot ref is not available.');
}
};
return (
<View style={styles.container}>
<ViewShot ref={viewShotRef} options={{ format: 'png', quality: 0.9, result: 'data-uri' }} style={styles.captureTarget}>
<Text style={styles.title}>Hello ViewShot!</Text>
<Text style={styles.subtitle}>This is a component that will be captured as an image.</Text>
<Image
source={{ uri: 'https://via.placeholder.com/100/ADD8E6/000000?text=RN' }}
style={styles.image}
/>
</ViewShot>
{capturedUri && (
<View style={styles.previewContainer}>
<Text style={styles.previewText}>Captured Image Preview:</Text>
<Image source={{ uri: capturedUri }} style={styles.previewImage} resizeMode="contain" />
</View>
)}
<Button title="Capture View" onPress={captureView} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f0f0f0',
padding: 20,
},
captureTarget: {
backgroundColor: 'white',
padding: 20,
borderRadius: 10,
alignItems: 'center',
marginBottom: 30,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 10,
},
subtitle: {
fontSize: 16,
textAlign: 'center',
marginBottom: 15,
},
image: {
width: 100,
height: 100,
borderRadius: 5,
},
previewContainer: {
marginTop: 20,
alignItems: 'center',
marginBottom: 20,
},
previewText: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
previewImage: {
width: 250,
height: 250,
borderWidth: 1,
borderColor: '#ccc',
backgroundColor: '#e8e8e8',
},
});
export default MyViewCapture;
Errors
Common errors & fixes
TypeError: Cannot read property 'capture' of null
The `useRef` hook's current property is null when `capture()` is called, indicating that the `ViewShot` component has not yet mounted or the ref is not correctly attached.
fixEnsure `viewShotRef` is initialized with `useRef(null)` and passed as `ref={viewShotRef}` to the `ViewShot` component. Wrap the `capture()` call in a check `if (viewShotRef.current)` to ensure the component is mounted before attempting to capture. Invariant Violation: `ViewShot` has been imported by a default import (as `ViewShot`) but is a named export (as `ViewShot`).
`ViewShot` is exported as a default module, but the import statement is attempting to destructure it as a named export.
fixChange the import statement from `import { ViewShot } from 'react-native-view-shot'` to `import ViewShot from 'react-native-view-shot'`. Error: No permission to write to storage. Please check your app's permissions.
The React Native application lacks the necessary platform-specific permissions to save the captured image to the device's storage or photo library.
fixFor Android, add `<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />` to `AndroidManifest.xml`. For iOS, add `NSPhotoLibraryUsageDescription` to `Info.plist`. Additionally, request these permissions at runtime if targeting modern Android versions (API 23+) or iOS.
Error: RNViewShotModule.java:xx: error: cannot find symbol method getArguments() in ReadableNativeMap
This Android build error often occurs due to a mismatch between the `react-native-view-shot` version and your `react-native` version, indicating an incompatibility with native module API changes.
fixEnsure `react-native-view-shot` is updated to a version compatible with your current React Native installation. Try upgrading `react-native-view-shot` to its latest stable release, then perform a clean Android build by running `cd android && ./gradlew clean && cd ..` before rebuilding your app.
Audit
Dependencies
reactrequiredRequired for all React Native applications.
react-nativerequiredCore React Native framework.