A React component that renders a preview for the device's front or back camera.
GitHub
npm
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.
-
npx expo install expo-camera
If you are installing this in an existing React Native app (bare workflow), start by installing expo
in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.
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.
{
"expo": {
"plugins": [
[
"expo-camera",
{
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
"recordAudioAndroid": true
}
]
]
}
}
Name | Default | Description |
---|---|---|
cameraPermission | "Allow $(PRODUCT_NAME) to access your camera" | Only for: iOS A string to set the |
microphonePermission | "Allow $(PRODUCT_NAME) to access your microphone" | Only for: iOS A string to set the |
recordAudioAndroid | true | Only for: Android A boolean that determines whether to enable the |
Learn how to configure the native projects in the installation instructions in the expo-camera
repository.
Only one Camera preview can be active at any given time. If you have multiple screens in your app, you should unmountCamera
components whenever a screen is unfocused.
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',
},
});
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.
iframe
usageWhen 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>
import { CameraView } from 'expo-camera';
CameraView
Type: React.Component<CameraProps>
active
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
Optional • Type: boolean
• Default: true
A boolean that determines whether the camera shutter animation should be enabled.
barcodeScannerSettings
Optional • Type: BarcodeSettings
Example
<CameraView
barcodeScannerSettings={{
barcodeTypes: ["qr"],
}}
/>
facing
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
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
Optional • Type: boolean
• Default: false
A boolean that determines whether the camera should mirror the image when using the front camera.
onBarcodeScanned
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.
for supported values.
onMountError
Optional • Type: (event: CameraMountError) => void
Callback invoked when camera preview could not start.
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
.
Setting this prop will cause the ratio
prop to be ignored as the aspect ratio is determined by the selected size.
poster
Optional • Type: string
A URL for an image to be shown while the camera is loading.
ratio
Optional • Type: CameraRatio
• Default: 1:1
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
.
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)
videoQuality
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
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
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.
getAvailableVideoCodecsAsync()
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()
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.
Promise<boolean>
launchScanner(options)
Name | Type |
---|---|
options (optional) | ScanningOptions |
Presents a modal view controller that uses the DataScannerViewController
available on iOS 16+.
Promise<void>
onModernBarcodeScanned(listener)
Name | Type | Description |
---|---|---|
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.
EventSubscription
getAvailablePictureSizesAsync()
Get picture sizes that are supported by the device.
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.
pausePreview()
Pauses the camera preview. It is not recommended to use takePictureAsync
when preview is paused.
Promise<void>
recordAsync(options)
Name | Type | Description |
---|---|---|
options (optional) | CameraRecordingOptions | A map of |
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.
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.
takePictureAsync(options)
Name | Type | Description |
---|---|---|
options (optional) | CameraPictureOptions | An object in form of |
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.
Promise<undefined | CameraCapturedPicture>
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 iOS, this will take a picture of the last frame that is currently on screen, on Android, this will throw an error.
useCameraPermissions(options)
Name | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
Check or request permissions to access the camera.
This uses both requestCameraPermissionsAsync
and getCameraPermissionsAsync
to interact with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [status, requestPermission] = useCameraPermissions();
useMicrophonePermissions(options)
Name | Type |
---|---|
options (optional) | PermissionHookOptions<object> |
Check or request permissions to access the microphone.
This uses both requestMicrophonePermissionsAsync
and getMicrophonePermissionsAsync
to interact with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [status, requestPermission] = Camera.useMicrophonePermissions();
Camera.scanFromURLAsync(url, barcodeTypes)
Name | Type | Description |
---|---|---|
url | string | URL to get the image from. |
barcodeTypes (optional) | BarcodeType[] | An array of bar code types. Defaults to all supported bar code types on the platform.
|
Scan bar codes from the image at the given URL.
A possibly empty array of objects 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.
PermissionResponse
An object obtained by permissions get and request functions.
PermissionResponse Properties
Name | Type | Description |
---|---|---|
canAskAgain | boolean | 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. |
expires | PermissionExpiration | Determines time when the permission expires. |
granted | boolean | A convenience boolean that indicates if the permission is granted. |
status | PermissionStatus | Determines the status of the permission. |
BarcodeBounds
Name | Type | Description |
---|---|---|
origin | BarcodePoint | The origin point of the bounding box. |
size | BarcodeSize | 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
Name | Type | Description |
---|---|---|
bounds | BarcodeBounds | The BarcodeBounds object.
|
cornerPoints | BarcodePoint[] | Corner points of the bounding box.
|
data | string | The parsed information encoded in the barcode. |
type | string | The barcode type. |
BarcodeSettings
Name | Type | Description |
---|---|---|
barcodeTypes | BarcodeType[] | - |
BarcodeSize
Name | Type | Description |
---|---|---|
height | number | The height value. |
width | number | The width value. |
BarcodeType
Literal Type: string
The available barcode types that can be scanned.
Acceptable values are: 'aztec'
| 'ean13'
| 'ean8'
| 'qr'
| 'pdf417'
| 'upc_e'
| 'datamatrix'
| 'code39'
| 'code93'
| 'itf14'
| 'codabar'
| 'code128'
| 'upc_a'
CameraCapturedPicture
Name | Type | Description |
---|---|---|
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 |
height | number | Captured image height. |
uri | string | On web, the value of |
width | number | Captured image width. |
CameraMountError
Name | Type | Description |
---|---|---|
message | string | - |
CameraOrientation
Literal Type: string
Acceptable values are: 'portrait'
| 'portraitUpsideDown'
| 'landscapeLeft'
| 'landscapeRight'
CameraPictureOptions
Name | Type | Description |
---|---|---|
additionalExif (optional) | Record<string, any> | Only for: Android iOS Additional EXIF data to be included for the image. Only useful when |
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 | - |
mirror (optional) | boolean |
Only for: iOS Android When set to Default: false |
onPictureSaved (optional) | (picture: CameraCapturedPicture) => void | A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured. The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it is not your case, this callback lets you skip waiting for it to be saved. |
quality (optional) | number | Specify the compression quality from |
scale (optional) | number | - |
skipProcessing (optional) | boolean | If set to
|
CameraRecordingOptions
Name | Type | Description |
---|---|---|
codec (optional) | VideoCodec | Only for: iOS This option specifies what codec to use when recording the video. See |
maxDuration (optional) | number | Maximum video duration in seconds. |
maxFileSize (optional) | number | Maximum video file size in bytes. |
mirror (optional) | boolean |
If |
FocusMode
Literal Type: string
This option specifies the mode of focus on the device.
on
- Indicates that the device should autofocus once and then lock the focus.off
- Indicates that the device should automatically focus when needed.Acceptable values are: 'on'
| 'off'
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
Name | Type | Description |
---|---|---|
x | number | - |
y | number | - |
ResponsiveOrientationChanged
Name | Type | Description |
---|---|---|
orientation | CameraOrientation | - |
ScanningOptions
Name | Type | Description |
---|---|---|
barcodeTypes | BarcodeType[] | The type of codes to scan for. |
isGuidanceEnabled (optional) | boolean | Guidance text, such as “Slow Down,” appears over the live video. Default: true |
isHighlightingEnabled (optional) | boolean | Indicates whether the scanner displays highlights around recognized items. Default: false |
isPinchToZoomEnabled (optional) | boolean | Indicates whether people can use a two-finger pinch-to-zoom gesture. Default: true |
ScanningResult
Type: Omit<BarcodeScanningResult, 'bounds'>
Subscription
A subscription object that allows to conveniently remove an event listener from the emitter.
Name | Type | Description |
---|---|---|
remove | () => void | Removes an event listener for which the subscription has been created. After calling this function, the listener will no longer receive any events from the emitter. |
VideoCodec
Literal Type: string
This option specifies what codec to use when recording a video.
Acceptable values are: 'avc1'
| 'hvc1'
| 'jpeg'
| 'apcn'
| 'ap4h'
VideoStabilization
Literal Type: string
This option specifies the stabilization mode to use when recording a video.
Acceptable values are: 'off'
| 'standard'
| 'cinematic'
| 'auto'
PermissionStatus
PermissionStatus Values
UNDETERMINED
PermissionStatus.UNDETERMINED = "undetermined"
User hasn't granted or denied the permission yet.
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 Permission | Description |
---|---|
Required to be able to access the camera device. | |
Allows an application to record audio. |
The following usage description keys are used by this library:
Info.plist Key | Description |
---|---|
A message that tells the user why the app is requesting access to the device’s camera. | |
A message that tells the user why the app is requesting access to the device’s microphone. |