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.

Ship faster with All Access. Get the React Native templates, admin panels, updates, and launch bonuses that help you build faster.

Explore All Access

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.