Skip to main content

Capturing Photos and Videos with the Camera in React Native

ยท 4 min read
Full Stack Developer
Last updated on May 6, 2026

capturing a photo

Camera features power profile photos, social posts, chat attachments, video feeds, marketplace listings, delivery proof photos, and dating profiles. The modern React Native implementation needs camera permissions, microphone permissions for video, safe previews, media validation, and an upload pipeline.

Quick Answerโ€‹

Use expo-camera for camera capture in apps that already use Expo modules. Use expo-image-picker when the user only needs to select or capture media through the system picker. For video playback, prefer expo-video; the old Video component from expo-av is deprecated.

Useful Instamobile docs:

Install Camera Dependenciesโ€‹

npx expo install expo-camera expo-video

If you are adding Expo modules to an existing React Native app, make sure the project has Expo modules configured before installing Expo SDK packages.

For iOS, add clear permission strings to Info.plist or your app config:

  • NSCameraUsageDescription
  • NSMicrophoneUsageDescription
  • NSPhotoLibraryUsageDescription if the app also reads from the library.

Mega Bundle Sale is ON! Get ALL of our React Native codebases at 90% OFF discount ๐Ÿ”ฅ

Get the Mega Bundle

Basic Camera Screenโ€‹

Current expo-camera uses CameraView and permission hooks:

import React, { useRef, useState } from 'react';
import { Button, View } from 'react-native';
import {
CameraType,
CameraView,
useCameraPermissions,
useMicrophonePermissions,
} from 'expo-camera';

export function CameraScreen() {
const cameraRef = useRef<CameraView>(null);
const [cameraPermission, requestCameraPermission] = useCameraPermissions();
const [microphonePermission, requestMicrophonePermission] =
useMicrophonePermissions();
const [facing, setFacing] = useState<CameraType>('back');
const [mediaUri, setMediaUri] = useState<string | null>(null);

if (!cameraPermission?.granted) {
return (
<Button title="Allow camera" onPress={requestCameraPermission} />
);
}

async function takePhoto() {
const photo = await cameraRef.current?.takePictureAsync({
quality: 0.8,
skipProcessing: false,
});

if (photo?.uri) {
setMediaUri(photo.uri);
}
}

async function recordVideo() {
if (!microphonePermission?.granted) {
await requestMicrophonePermission();
}

const video = await cameraRef.current?.recordAsync({
maxDuration: 30,
});

if (video?.uri) {
setMediaUri(video.uri);
}
}

return (
<View style={{ flex: 1 }}>
<CameraView ref={cameraRef} style={{ flex: 1 }} facing={facing} />
<Button title="Take photo" onPress={takePhoto} />
<Button title="Record video" onPress={recordVideo} />
<Button
title="Flip"
onPress={() => setFacing(current => (current === 'back' ? 'front' : 'back'))}
/>
</View>
);
}

Keep production UI more defensive than a tutorial snippet: disable buttons while capture is active, handle onMountError, and show a preview before uploading.

Preview Video with expo-videoโ€‹

Use expo-video for playback:

import { useVideoPlayer, VideoView } from 'expo-video';

export function VideoPreview({ uri }: { uri: string }) {
const player = useVideoPlayer(uri, player => {
player.loop = true;
player.play();
});

return <VideoView player={player} style={{ width: '100%', height: 300 }} />;
}

Upload-Ready Media Checklistโ€‹

Before uploading media:

  • check file type;
  • check file size;
  • limit video duration;
  • generate a thumbnail for feeds;
  • compress or resize when needed;
  • store width, height, duration, and owner ID;
  • upload under user-scoped Firebase Storage paths;
  • clean up abandoned uploads.

FAQโ€‹

Should I use expo-camera or expo-image-picker?โ€‹

Use expo-camera for custom camera UI. Use expo-image-picker for simpler library selection or system capture flows.

Can I still use expo-av for video?โ€‹

The old Video component from expo-av is deprecated. Prefer expo-video for new video playback work.

Why does video capture need microphone permission?โ€‹

Most video capture records audio by default, so iOS and Android can require microphone permission even if your UI focuses on video.

Useful Referencesโ€‹

Looking for a custom mobile application?

Our team of expert mobile developers can help you build a custom mobile app that meets your specific needs.

Get in Touch

Conclusionโ€‹

Camera features are more than takePictureAsync. Production apps need clear permissions, capture state, previews, media validation, upload progress, and Storage rules. Build the capture flow together with the upload flow, not as a separate demo screen.