Skip to main content

Recipes

Common configurations, copy-paste ready. All assume permission is already resolved (see Getting started).

Photo-only camera (no panorama)

<Camera enablePanoramaMode={false} onCapture={onCapture} />

Panorama-only (no single photo)

<Camera enablePhotoMode={false} onCapture={onCapture} />

AR-only capture

Hides the AR toggle (nothing to switch to) and the lens chooser (AR is 1×-only):

<Camera captureSources="ar" onCapture={onCapture} />

Non-AR (vision-camera) only

Hides the AR toggle; keeps the 0.5×/1× chooser:

<Camera captureSources="non-ar" onCapture={onCapture} />

Save outputs to a specific directory

import { Paths } from 'expo-file-system'; // or your path util

<Camera
outputDir={`${Paths.document.uri}/captures`}
onCapture={(r) => console.log('saved at', r.uri)}
/>

Header with a back button

<Camera
headerTitle="Scan shelf"
headerGuidance="Hold and pan across the shelf."
headerBackLabel="Cancel"
onHeaderBack={() => navigation.goBack()}
/>

Capture history + tap-to-preview

const [thumbnails, setThumbnails] = useState<CaptureThumbnailItem[]>([]);

<Camera
thumbnails={thumbnails}
thumbnailsMin={3}
thumbnailsMax={12}
onCapture={(r) =>
setThumbnails((t) => [
...t,
{ id: String(Date.now()), uri: r.uri, width: r.width, height: r.height },
])
}
/>

Post-stitch preview with actions

const [preview, setPreview] = useState<CameraCaptureResult | null>(null);

<Camera
onCapture={setPreview}
capturePreview={preview ? { imageUri: preview.uri, title: 'Review' } : undefined}
capturePreviewActions={[
{ label: 'Retake', onPress: () => setPreview(null) },
{ label: 'Use photo', onPress: () => { save(preview!); setPreview(null); } },
]}
onCapturePreviewClose={() => setPreview(null)}
/>

Controlled flash mirrored from app state

const [flash, setFlash] = useState<'on' | 'off'>('off');

<Camera flash={flash} onFlashChange={setFlash} />

Handling errors by class

<Camera
onError={(err) => {
switch (err.code) {
case 'CAMERA_PERMISSION_DENIED':
return promptForSettings();
case 'STITCH_NEED_MORE_IMGS':
return toast('Pan a bit more next time.');
case 'STITCH_OOM':
return toast('Ran low on memory — try a shorter pan.');
default:
return report(err);
}
}}
/>

Friendly recoverable-stitch alerts (userFacingStitchError)

Instead of hand-writing copy for each STITCH_* code, let the SDK supply vetted, action-guiding text. userFacingStitchError(code) returns { title, message } for a recoverable stitch failure (pan more slowly / pivot in place / shorten the sweep) and null for anything non-recoverable — so one branch handles the friendly path and falls through to your generic error UI for the rest.

import { Camera, userFacingStitchError } from 'react-native-image-stitcher';
import { Alert } from 'react-native';

<Camera
onError={(err) => {
const friendly = userFacingStitchError(err.code);
if (friendly) {
Alert.alert(friendly.title, friendly.message);
} else {
report(err); // permission denied, device unavailable, etc.
}
}}
/>;

See Capture result & errors for the full code→copy table.