HomeGuidesReferenceLearn

Reference version

ArchiveExpo SnackDiscord and ForumsNewsletter

Expo Camera iconExpo Camera

GitHub

npm

A React component that renders a preview for the device's front or back camera.


expo-camera provides a React component that renders a preview of the device's front or back camera. The camera's parameters such as zoom, auto focus, white balance and flash mode are adjustable. Using Camera, you can take photos and record videos that are saved to the app's cache. The component is also capable of detecting faces and bar codes appearing in the preview. Run the example on your device to see all these features working together.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb
Android devices can use one of two available Camera APIs: you can opt-in to using Camera2 with the useCamera2Api prop.

Installation

Terminal
npx expo install expo-camera

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

Configuration in app.json/app.config.js

You can configure expo-camera using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.

Example app.json with config plugin

app.json
{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera."
        }
      ]
    ]
  }
}

Configurable properties

NameDefaultDescription
cameraPermission"Allow $(PRODUCT_NAME) to access your camera"Only for:
iOS

A string to set the NSCameraUsageDescription permission message.

microphonePermission"Allow $(PRODUCT_NAME) to access your microphone"Only for:
iOS

A string to set the NSMicrophoneUsageDescription permission message.

Are you using this library in a bare React Native app?

Learn how to configure the native projects in the installation instructions in the expo-camera repository.

Usage

Only one Camera preview can be active at any given time. If you have multiple screens in your app, you should unmount Camera components whenever a screen is unfocused.
Basic Camera usage
import { Camera, CameraType } from 'expo-camera';
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

export default function App() {
  const [type, setType] = useState(CameraType.back);
  const [permission, requestPermission] = Camera.useCameraPermissions();

  if (!permission) {
    // Camera permissions are still loading
    return <View />;
  }

  if (!permission.granted) {
    // Camera permissions are not granted yet
    return (
      <View style={styles.container}>
        <Text style={{ textAlign: 'center' }}>We need your permission to show the camera</Text>
        <Button onPress={requestPermission} title="grant permission" />
      </View>
    );
  }

  function toggleCameraType() {
    setType(current => (current === CameraType.back ? CameraType.front : CameraType.back));
  }

  return (
    <View style={styles.container}>
      <Camera style={styles.camera} type={type}>
        <View style={styles.buttonContainer}>
          <TouchableOpacity style={styles.button} onPress={toggleCameraType}>
            <Text style={styles.text}>Flip Camera</Text>
          </TouchableOpacity>
        </View>
      </Camera>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  camera: {
    flex: 1,
  },
  buttonContainer: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: 'transparent',
    margin: 64,
  },
  button: {
    flex: 1,
    alignSelf: 'flex-end',
    alignItems: 'center',
  },
  text: {
    fontSize: 24,
    fontWeight: 'bold',
    color: 'white',
  },
});

Web support

Most browsers support a version of web camera functionality, you can check out the web camera browser support here. Image URIs are always returned as base64 strings because local file system paths are unavailable in the browser.

Chrome iframe usage

When using Chrome versions 64+, if you try to use a web camera in a cross-origin iframe nothing will render. To add support for cameras in your iframe simply add the attribute allow="microphone; camera;" to the iframe element:

<iframe src="..." allow="microphone; camera;">
  <!-- <Camera /> -->
</iframe>

API

import { Camera } from 'expo-camera';

Component

Camera

Type: React.Component<CameraProps>

Props

barCodeScannerSettings

Optional • Type: BarCodeSettings

Settings exposed by BarCodeScanner module. Supported settings: barCodeTypes.

Example

<Camera
  barCodeScannerSettings={{
    barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
  }}
/>

faceDetectorSettings

Optional • Type: object

A settings object passed directly to an underlying module providing face detection features. See DetectionOptions in FaceDetector documentation for details.

flashMode

Optional • Type: number | FlashMode • Default: FlashMode.off

Camera flash mode. Use one of FlashMode.<value>. When FlashMode.on, the flash on your device will turn on when taking a picture, when FlashMode.off, it won't. Setting to FlashMode.auto will fire flash if required, FlashMode.torch turns on flash during the preview.

focusDepth

Optional • Type: number • Default: 0

Distance to plane of the sharpest focus. A value between 0 and 1 where: 0 - infinity focus, 1 - focus as close as possible. For Android this is available only for some devices and when useCamera2Api is set to true.

onBarCodeScanned

Optional • Type: (scanningResult: BarCodeScanningResult) => void

Callback that is invoked when a bar code has been successfully scanned. The callback is provided with an object of the BarCodeScanningResult shape, where the type refers to the bar code type that was scanned and the data is the information encoded in the bar code (in this case of QR codes, this is often a URL). See BarCodeScanner.Constants.BarCodeType for supported values.

onCameraReady

Optional • Type: () => void

Callback invoked when camera preview has been set.

onFacesDetected

Optional • Type: (faces: FaceDetectionResult) => void

Callback invoked with results of face detection on the preview. See DetectionResult in FaceDetector documentation for more details.

onMountError

Optional • Type: (event: CameraMountError) => void

Callback invoked when camera preview could not been started.

onResponsiveOrientationChanged

Optional • Type: (event: ResponsiveOrientationChanged) => void

Callback invoked when responsive orientation changes. Only applicable if responsiveOrientationWhenOrientationLocked is true

pictureSize

Optional • Type: string

A string representing the size of pictures takePictureAsync will take. Available sizes can be fetched with getAvailablePictureSizesAsync.

Only for:
Web

poster

Optional • Type: string

A URL for an image to be shown while the camera is loading.

Only for:
Android

ratio

Optional • Type: string • Default: 4:3

A string representing aspect ratio of the preview, eg. 4:3, 16:9, 1:1. To check if a ratio is supported by the device use getSupportedRatiosAsync.

Only for:
iOS

responsiveOrientationWhenOrientationLocked

Optional • Type: boolean

Whether to allow responsive orientation of the camera when the screen orientation is locked (i.e. when set to true landscape photos will be taken if the device is turned that way, even if the app or device orientation is locked to portrait)

type

Optional • Type: number | CameraType • Default: CameraType.back

Camera facing. Use one of CameraType. When CameraType.front, use the front-facing camera. When CameraType.back, use the back-facing camera.

Only for:
Android

useCamera2Api

Optional • Type: boolean

Whether to use Android's Camera2 API. See Note at the top of this page.

Only for:
iOS

videoStabilizationMode

Optional • Type: VideoStabilization

The video stabilization mode used for a video recording. Use one of VideoStabilization.<value>. You can read more about each stabilization type in Apple Documentation.

whiteBalance

Optional • Type: number | WhiteBalance • Default: WhiteBalance.auto

Camera white balance. Use one of WhiteBalance.<value>. If a device does not support any of these values previous one is used.

zoom

Optional • Type: number • Default: 0

A value between 0 and 1 being a percentage of device's max zoom. 0 - not zoomed, 1 - maximum zoom.

Inherited Props

  • ViewProps

Static Methods

Only for:
Web

getAvailableCameraTypesAsync()

Returns a list of camera types ['front', 'back']. This is useful for desktop browsers which only have front-facing cameras.

Returns

  • Promise<CameraType[]>

Only for:
iOS

getAvailableVideoCodecsAsync()

Queries the device for the available video codecs that can be used in video recording.

Returns

  • Promise<VideoCodec[]>

A promise that resolves to a list of strings that represents available codecs.

Only for:
Web

isAvailableAsync()

Check whether the current device has a camera. This is useful for web and simulators cases. This isn't influenced by the Permissions API (all platforms), or HTTP usage (in the browser). You will still need to check if the native permission has been accepted.

Returns

  • Promise<boolean>

Component Methods

getAvailablePictureSizesAsync(ratio)

NameTypeDescription
ratio
(optional)
string

A string representing aspect ratio of sizes to be returned.


Get picture sizes that are supported by the device for given ratio.

Returns

  • Promise<string[]>

Returns a Promise that resolves to an array of strings representing picture sizes that can be passed to pictureSize prop. The list varies across Android devices but is the same for every iOS.

Only for:
Android

getSupportedRatiosAsync()

Get aspect ratios that are supported by the device and can be passed via ratio prop.

Returns

  • Promise<string[]>

Returns a Promise that resolves to an array of strings representing ratios, eg. ['4:3', '1:1'].

pausePreview()

Pauses the camera preview. It is not recommended to use takePictureAsync when preview is paused.

Returns

  • void

Only for:
Android
iOS

recordAsync(options)

NameTypeDescription
options
(optional)
CameraRecordingOptions

A map of CameraRecordingOptions type.


Starts recording a video that will be saved to cache directory. Videos are rotated to match device's orientation. Flipping camera during a recording results in stopping it.

Returns

  • Promise<{ uri: string }>

Returns a Promise that resolves to an object containing video file uri property and a codec property on iOS. The Promise is returned if stopRecording was invoked, one of maxDuration and maxFileSize is reached or camera preview is stopped.

resumePreview()

Resumes the camera preview.

Returns

  • void

stopRecording()

Stops recording if any is in progress.

Returns

  • void

takePictureAsync(options)

NameTypeDescription
options
(optional)
CameraPictureOptions

An object in form of CameraPictureOptions type.


Takes a picture and saves it to app's cache directory. Photos are rotated to match device's orientation (if options.skipProcessing flag is not enabled) and scaled to match the preview. Anyway on Android it is essential to set ratio prop to get a picture with correct dimensions.

Note: Make sure to wait for the onCameraReady callback before calling this method.

Returns

  • Promise<CameraCapturedPicture>

Returns a Promise that resolves to CameraCapturedPicture object, where uri is a URI to the local image file on iOS, Android, and a base64 string on web (usable as the source for an Image element). The width and height properties specify the dimensions of the image. base64 is included if the base64 option was truthy, and is a string containing the JPEG data of the image in Base64--prepend that with 'data:image/jpg;base64,' to get a data URI, which you can use as the source for an Image element for example. exif is included if the exif option was truthy, and is an object containing EXIF data for the image--the names of its properties are EXIF tags and their values are the values for those tags.

On native platforms, the local image URI is temporary. Use FileSystem.copyAsync to make a permanent copy of the image.

Hooks

useCameraPermissions(options)

NameTypeDescription
options
(optional)
PermissionHookOptions<object>-

Returns

  • [null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

useMicrophonePermissions(options)

NameTypeDescription
options
(optional)
PermissionHookOptions<object>-

Returns

  • [null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

Methods

Camera.getCameraPermissionsAsync()

Checks user's permissions for accessing camera.

Returns

  • Promise<PermissionResponse>

A promise that resolves to an object of type PermissionResponse.

Camera.getMicrophonePermissionsAsync()

Checks user's permissions for accessing microphone.

Returns

  • Promise<PermissionResponse>

A promise that resolves to an object of type PermissionResponse.

Deprecated. Use getCameraPermissionsAsync or getMicrophonePermissionsAsync instead. Checks user's permissions for accessing camera.

Camera.getPermissionsAsync()

Returns

  • Promise<PermissionResponse>

Camera.requestCameraPermissionsAsync()

Asks the user to grant permissions for accessing camera. On iOS this will require apps to specify an NSCameraUsageDescription entry in the Info.plist.

Returns

  • Promise<PermissionResponse>

A promise that resolves to an object of type PermissionResponse.

Camera.requestMicrophonePermissionsAsync()

Asks the user to grant permissions for accessing the microphone. On iOS this will require apps to specify an NSMicrophoneUsageDescription entry in the Info.plist.

Returns

  • Promise<PermissionResponse>

A promise that resolves to an object of type PermissionResponse.

Deprecated. Use requestCameraPermissionsAsync or requestMicrophonePermissionsAsync instead.

Camera.requestPermissionsAsync()

Asks the user to grant permissions for accessing camera. On iOS this will require apps to specify both NSCameraUsageDescription and NSMicrophoneUsageDescription entries in the Info.plist.

Returns

  • Promise<PermissionResponse>

A promise that resolves to an object of type PermissionResponse.

Interfaces

PermissionResponse

An object obtained by permissions get and request functions.

PermissionResponse Properties

NameTypeDescription
canAskAgainboolean

Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission.

expiresPermissionExpiration

Determines time when the permission expires.

grantedboolean

A convenience boolean that indicates if the permission is granted.

statusPermissionStatus

Determines the status of the permission.


Types

BarCodeBounds

NameTypeDescription
originBarCodePoint

The origin point of the bounding box.

sizeBarCodeSize

The size of the bounding box.

BarCodePoint

Type: Point

These coordinates are represented in the coordinate space of the camera source (e.g. when you are using the camera view, these values are adjusted to the dimensions of the view).

BarCodeScanningResult

NameTypeDescription
boundsBarCodeBounds

The BarCodeBounds object. bounds in some case will be representing an empty rectangle. Moreover, bounds doesn't have to bound the whole barcode. For some types, they will represent the area used by the scanner.

cornerPointsBarCodePoint[]

Corner points of the bounding box. cornerPoints is not always available and may be empty. On iOS, for code39 and pdf417 you don't get this value.

datastring

The information encoded in the bar code.

typestring

The barcode type.

BarCodeSettings

NameTypeDescription
barCodeTypesstring[]-
interval
(optional)
number-

BarCodeSize

NameTypeDescription
heightnumber

The height value.

widthnumber

The width value.

CameraCapturedPicture

NameTypeDescription
base64
(optional)
string

A Base64 representation of the image.

exif
(optional)
Partial<MediaTrackSettings> | any

On Android and iOS this object may include various fields based on the device and operating system. On web, it is a partial representation of the MediaTrackSettings dictionary.

heightnumber

Captured image height.

uristring

On web, the value of uri is the same as base64 because file system URLs are not supported in the browser.

widthnumber

Captured image width.

CameraMountError

NameTypeDescription
messagestring-

CameraPictureOptions

NameTypeDescription
additionalExif
(optional)
undefinedOnly for:
Android
iOS

Additional EXIF data to be included for the image. Only useful when exif option is set to true.

base64
(optional)
boolean

Whether to also include the image data in Base64 format.

exif
(optional)
boolean

Whether to also include the EXIF data for the image.

imageType
(optional)
ImageType-
isImageMirror
(optional)
boolean-
onPictureSaved
(optional)
(picture: CameraCapturedPicture) => void-
quality
(optional)
number

Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.

scale
(optional)
number-
skipProcessing
(optional)
boolean

If set to true, camera skips orientation adjustment and returns an image straight from the device's camera. If enabled, quality option is discarded (processing pipeline is skipped as a whole). Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation in the Image component (at the time of writing, it does not respect EXIF orientation of the images).

Note: Enabling skipProcessing would cause orientation uncertainty. Image component does not respect EXIF stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°). Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide correctly oriented images by default. To always obtain correctly oriented image disable skipProcessing option.

CameraRecordingOptions

NameTypeDescription
codec
(optional)
VideoCodecOnly for:
iOS

This option specifies what codec to use when recording the video. See VideoCodec for the possible values.

maxDuration
(optional)
number

Maximum video duration in seconds.

maxFileSize
(optional)
number

Maximum video file size in bytes.

mirror
(optional)
booleanOnly for:
iOS

If true, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default, but you can reverse that back by setting this to true. On Android, this is handled in the user's device settings.

mute
(optional)
boolean

If present, video will be recorded with no sound.

quality
(optional)
number | string

Specify the quality of recorded video. Use one of VideoQuality.<value>. Possible values: for 16:9 resolution 2160p, 1080p, 720p, 480p : Android only and for 4:3 4:3 (the size is 640x480). If the chosen quality is not available for a device, the highest available is chosen.

videoBitrate
(optional)
numberOnly for:
Android

Only works if useCamera2Api is set to true. This option specifies a desired video bitrate. For example, 5*1000*1000 would be 5Mbps.

FaceDetectionResult

NameTypeDescription
facesobject[]

Array of objects representing results of face detection. See FaceFeature in FaceDetector documentation for more details.

PermissionExpiration

Literal Type: multiple types

Permission expiration time. Currently, all permissions are granted permanently.

Acceptable values are: 'never' | number

PermissionHookOptions

Literal Type: multiple types

Acceptable values are: PermissionHookBehavior | Options

Point

NameTypeDescription
xnumber-
ynumber-

ResponsiveOrientationChanged

NameTypeDescription
orientationCameraOrientation-

Enums

AutoFocus

AutoFocus Values

Only for:
Web

auto

AutoFocus.auto = "auto"

off

AutoFocus.off = "off"

on

AutoFocus.on = "on"
Only for:
Web

singleShot

AutoFocus.singleShot = "singleShot"

CameraOrientation

CameraOrientation Values

portrait

CameraOrientation.portrait = 1

portraitUpsideDown

CameraOrientation.portraitUpsideDown = 2

landscapeLeft

CameraOrientation.landscapeLeft = 3

landscapeRight

CameraOrientation.landscapeRight = 4

CameraType

CameraType Values

back

CameraType.back = "back"

front

CameraType.front = "front"

FlashMode

FlashMode Values

auto

FlashMode.auto = "auto"

off

FlashMode.off = "off"

on

FlashMode.on = "on"

torch

FlashMode.torch = "torch"

ImageType

ImageType Values

jpg

ImageType.jpg = "jpg"

png

ImageType.png = "png"

PermissionStatus

PermissionStatus Values

DENIED

PermissionStatus.DENIED = "denied"

User has denied the permission.

GRANTED

PermissionStatus.GRANTED = "granted"

User has granted the permission.

UNDETERMINED

PermissionStatus.UNDETERMINED = "undetermined"

User hasn't granted or denied the permission yet.

Only for:
iOS

VideoCodec

This option specifies what codec to use when recording a video.

VideoCodec Values

AppleProRes4444

VideoCodec.AppleProRes4444 = "ap4h"

AppleProRes422

VideoCodec.AppleProRes422 = "apcn"

H264

VideoCodec.H264 = "avc1"

HEVC

VideoCodec.HEVC = "hvc1"

JPEG

VideoCodec.JPEG = "jpeg"

VideoQuality

VideoQuality Values

1080p

VideoQuality.1080p = "1080p"

2160p

VideoQuality.2160p = "2160p"

4:3

VideoQuality.4:3 = "4:3"

480p

VideoQuality.480p = "480p"

720p

VideoQuality.720p = "720p"
Only for:
iOS

VideoStabilization

This option specifies the stabilization mode to use when recording a video.

VideoStabilization Values

auto

VideoStabilization.auto = "auto"

cinematic

VideoStabilization.cinematic = "cinematic"

off

VideoStabilization.off = "off"

standard

VideoStabilization.standard = "standard"

WhiteBalance

WhiteBalance Values

auto

WhiteBalance.auto = "auto"
Only for:
Android
iOS

cloudy

WhiteBalance.cloudy = "cloudy"
Only for:
Web

continuous

WhiteBalance.continuous = "continuous"
Only for:
Android
iOS

fluorescent

WhiteBalance.fluorescent = "fluorescent"
Only for:
Android
iOS

incandescent

WhiteBalance.incandescent = "incandescent"
Only for:
Web

manual

WhiteBalance.manual = "manual"
Only for:
Android
iOS

shadow

WhiteBalance.shadow = "shadow"
Only for:
Android
iOS

sunny

WhiteBalance.sunny = "sunny"

Permissions

Android

This package automatically adds the CAMERA permission to your app. If you want to record videos with audio, you have to include the RECORD_AUDIO in your app.json inside the expo.android.permissions array.

Android PermissionDescription

CAMERA

Required to be able to access the camera device.

RECORD_AUDIO

Allows an application to record audio.

iOS

The following usage description keys are used by this library:

Info.plist KeyDescription

NSCameraUsageDescription

A message that tells the user why the app is requesting access to the device’s camera.

NSMicrophoneUsageDescription

A message that tells the user why the app is requesting access to the device’s microphone.