Reference version

Expo Camera iconExpo Camera

GitHub

npm

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

Android (device only)
iOS (device only)
Web
Bundled version:
~16.1.6

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, torch, and flash mode are adjustable. Using CameraView, you can take photos and record videos that are saved to the app's cache. The component is also capable of detecting bar codes appearing in the preview. Run the example on your device to see all these features working together.

Installation

Terminal
- npx expo install expo-camera

If you are installing this in an existing React Native app, make sure to install expo in your project.

Configuration in app config

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",
          "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
          "recordAudioAndroid": true
        }
      ]
    ]
  }
}

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.

recordAudioAndroidtrue
Only for: 
Android

A boolean that determines whether to enable the RECORD_AUDIO permission on Android.

Are you using this library in an existing React Native app?

If you're not using Continuous Native Generation (CNG) (you're using native android and ios projects manually), then you need to configure following permissions in your native projects:

Android

  • expo-camera automatically adds android.permission.CAMERA permission to your project's android/app/src/main/AndroidManifest.xml. If you want to record videos with audio, include RECORD_AUDIO permission:

    <!-- Added permission -->
    <uses-permission android:name="android.permission.CAMERA" />
    
    <!-- Only add when recording videos with audio -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    
  • Then, adjust the android/build.gradle file to add new maven block after all other repositories as show below:

    allprojects {
      repositories {
          // * Your other repositories here *
          // * Add a new maven block after other repositories / blocks *
          maven {
              // expo-camera bundles a custom com.google.android:cameraview
              url "$rootDir/../node_modules/expo-camera/android/maven"
          }
      }
    }
    

iOS

  • Add NSCameraUsageDescription and NSMicrophoneUsageDescription keys to your project's ios/[app]/Info.plist:

    <key>NSCameraUsageDescription</key>
    <string>Allow $(PRODUCT_NAME) to access your camera</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Allow $(PRODUCT_NAME) to access your microphone</string>
    

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 { CameraView, CameraType, useCameraPermissions } from 'expo-camera';
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

export default function App() {
  const [facing, setFacing] = useState<CameraType>('back');
  const [permission, requestPermission] = 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={styles.message}>We need your permission to show the camera</Text>
        <Button onPress={requestPermission} title="grant permission" />
      </View>
    );
  }

  function toggleCameraFacing() {
    setFacing(current => (current === 'back' ? 'front' : 'back'));
  }

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

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  message: {
    textAlign: 'center',
    paddingBottom: 10,
  },
  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',
  },
});

Advanced usage

Camera app example

A complete example that shows how to take a picture and display it. Written in TypeScript.

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;">
  <!-- <CameraView /> -->
</iframe>

API

import { CameraView } from 'expo-camera';

Component

CameraView

Android
iOS
Web

Type: React.Component<CameraViewProps>

CameraViewProps

active

iOS
Optional • Type: boolean • Default: true

A boolean that determines whether the camera should be active. Useful in situations where the camera may not have unmounted but you still want to stop the camera session.

animateShutter

Android
iOS
Web
Optional • Type: boolean • Default: true

A boolean that determines whether the camera shutter animation should be enabled.

autofocus

iOS
Optional • Type: FocusMode • Default: off

Indicates the focus mode to use.

barcodeScannerSettings

Android
iOS
Web
Optional • Type: BarcodeSettings

Example

<CameraView
  barcodeScannerSettings={{
    barcodeTypes: ["qr"],
  }}
/>

enableTorch

Android
iOS
Web
Optional • Type: boolean • Default: false

A boolean to enable or disable the torch.

facing

Android
iOS
Web
Optional • Type: CameraType • Default: 'back'

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

flash

Android
iOS
Web
Optional • Type: FlashMode • Default: 'off'

Camera flash mode. Use one of FlashMode values. When on, the flash on your device will turn on when taking a picture. When off, it won't. Setting it to auto will fire flash if required.

mirror

Android
iOS
Web
Optional • Type: boolean • Default: false

A boolean that determines whether the camera should mirror the image when using the front camera.

mode

Android
iOS
Web
Optional • Type: CameraMode • Default: 'picture'

Used to select image or video output.

mute

Android
iOS
Web
Optional • Type: boolean • Default: false

If present, video will be recorded with no sound.

onAvailableLensesChanged

iOS
Optional • Type: (event: AvailableLenses) => void

Callback invoked when the cameras available lenses change.

event: AvailableLenses

result object that contains a lenses property containing an array of available lenses.

onBarcodeScanned

Android
iOS
Web
Optional • Type: (scanningResult: BarcodeScanningResult) => void

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

onCameraReady

Android
iOS
Web
Optional • Type: () => void

Callback invoked when camera preview has been set.

onMountError

Android
iOS
Web
Optional • Type: (event: CameraMountError) => void

Callback invoked when camera preview could not start.

event: CameraMountError

Error object that contains a message.

onResponsiveOrientationChanged

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

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

event: ResponsiveOrientationChanged

result object that contains updated orientation of camera

pictureSize

Android
iOS
Web
Optional • Type: string

A string representing the size of pictures takePictureAsync will take. Available sizes can be fetched with getAvailablePictureSizesAsync. Setting this prop will cause the ratio prop to be ignored as the aspect ratio is determined by the selected size.

poster

Web
Optional • Type: string

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

ratio

Android
Optional • Type: CameraRatio

A string representing the aspect ratio of the preview. For example, 4:3 and 16:9. Note: Setting the aspect ratio here will change the scaleType of the camera preview from FILL to FIT. Also, when using 1:1, devices only support certain sizes. If you specify an unsupported size, the closest supported ratio will be used.

responsiveOrientationWhenOrientationLocked

iOS
Optional • Type: boolean

Whether to allow responsive orientation of the camera when the screen orientation is locked (that is, 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).

selectedLens

iOS
Optional • Type: string • Default: 'builtInWideAngleCamera'

Available lenses are emitted to the onAvailableLensesChanged callback whenever the currently selected camera changes or by calling getAvailableLensesAsync. You can read more about the available lenses in the Apple documentation.

videoBitrate

Android
iOS
Web
Optional • Type: number

The bitrate of the video recording in bits per second. Note: On iOS, you must specify the video codec when calling recordAsync to use this option.

Example

10_000_000

videoQuality

Android
iOS
Web
Optional • Type: VideoQuality

Specify the quality of the recorded video. Use one of VideoQuality 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.

videoStabilizationMode

iOS
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.

zoom

Android
iOS
Web
Optional • Type: number • Default: 0

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

Inherited Props

Static Methods

dismissScanner()

iOS

Dismiss the scanner presented by launchScanner.

On Android, the scanner is dismissed automatically when a barcode is scanned.
Returns:
Promise<void>

getAvailableVideoCodecsAsync()

iOS

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

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

isAvailableAsync()

Web

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>

launchScanner(options)

Android
iOS
ParameterType
options(optional)ScanningOptions

On Android, we will use the Google code scanner. On iOS, presents a modal view controller that uses the DataScannerViewController available on iOS 16+.

Returns:
Promise<void>

onModernBarcodeScanned(listener)

Android
iOS
ParameterTypeDescription
listener(event: ScanningResult) => void

Invoked with the ScanningResult when a bar code has been successfully scanned.


Invokes the listener function when a bar code has been successfully scanned. The callback is provided with an object of the ScanningResult 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 BarcodeType for supported values.

Returns:
EventSubscription

Component Methods

getAvailableLensesAsync()

iOS

Returns the available lenses for the currently selected camera.

Returns:
Promise<string[]>

Returns a Promise that resolves to an array of strings representing the lens type that can be passed to selectedLens prop.

getAvailablePictureSizesAsync()

Android
iOS
Web

Get picture sizes that are supported by the device.

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.

getSupportedFeatures()

Android
iOS
Web

Returns an object with the supported features of the camera on the current device.

Returns:
{ isModernBarcodeScannerAvailable: boolean, toggleRecordingAsyncAvailable: boolean }

pausePreview()

Android
iOS
Web

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

Returns:
Promise<void>

recordAsync(options)

Android
iOS
ParameterTypeDescription
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<undefined | { 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()

Android
iOS
Web

Resumes the camera preview.

Returns:
Promise<void>

stopRecording()

Android
iOS

Stops recording if any is in progress.

Returns:
void

takePictureAsync(options)

Android
iOS
Web
ParameterTypeDescription
optionsCameraPictureOptions & { pictureRef: true }

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.

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

Returns a Promise that resolves to CameraCapturedPicture object, where uri is a URI to the local image file on Android, iOS, 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 it 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.

Note: Avoid calling this method while the preview is paused. On Android, this will throw an error. On iOS, this will take a picture of the last frame that is currently on screen.

takePictureAsync(options)

Android
iOS
Web
ParameterTypeDescription
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.

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

Returns a Promise that resolves to CameraCapturedPicture object, where uri is a URI to the local image file on Android, iOS, 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 it 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.

Note: Avoid calling this method while the preview is paused. On Android, this will throw an error. On iOS, this will take a picture of the last frame that is currently on screen.

toggleRecordingAsync()

Android
iOS
Web

Pauses or resumes the video recording. Only has an effect if there is an active recording. On iOS, this method only supported on iOS 18.

Returns:
Promise<undefined | void>

Example

const { toggleRecordingAsyncAvailable } = getSupportedFeatures()

return (
 {toggleRecordingAsyncAvailable && (
   <Button title="Toggle Recording" onPress={toggleRecordingAsync} />
 )}
)

Hooks

useCameraPermissions(options)

Android
iOS
Web
ParameterType
options(optional)PermissionHookOptions<object>

Check or request permissions to access the camera. This uses both requestCameraPermissionsAsync and getCameraPermissionsAsync to interact with the permissions.

Returns:
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

Example

const [status, requestPermission] = useCameraPermissions();

useMicrophonePermissions(options)

Android
iOS
Web
ParameterType
options(optional)PermissionHookOptions<object>

Check or request permissions to access the microphone. This uses both requestMicrophonePermissionsAsync and getMicrophonePermissionsAsync to interact with the permissions.

Returns:
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

Example

const [status, requestPermission] = Camera.useMicrophonePermissions();

Classes

CameraNativeModule

Android
iOS
Web

Type: Class extends _default<CameraEvents>

CameraNativeModule Properties

dismissScanner