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.