---
title: Multi-Camera
description: Using multiple Camera Devices in a single Camera Session
---

import { Tab, Tabs } from 'fumadocs-ui/components/tabs'

A [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession) allows attaching multiple connections to stream from multiple [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice)s at the same time (e.g. Picture-in-Picture mode via front + back Camera) - if the system supports it.

### Creating a Multi-Camera Session

To create a multi-camera [`CameraSession`](/api/react-native-vision-camera/hybrid-objects/CameraSession), use [`createCameraSession(true)`](/api/react-native-vision-camera/hybrid-objects/CameraFactory#createcamerasession). Make sure [`supportsMultiCamSessions`](/api/react-native-vision-camera/hybrid-objects/CameraFactory#supportsmulticamsessions) is `true`:

```ts
if (VisionCamera.supportsMultiCamSessions) {
  const session = await VisionCamera.createCameraSession(true)
}
```

### Getting Multi-Cam capable CameraDevices

Due to hardware constraints, not every [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice) can be paired with every other [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice), therefore VisionCamera exposes a list of supported device combinations via [`supportedMultiCamDeviceCombinations`](/api/react-native-vision-camera/hybrid-objects/CameraDeviceFactory#supportedmulticamdevicecombinations) upfront:

A combination contains one or more logical [`CameraDevice`](/api/react-native-vision-camera/hybrid-objects/CameraDevice)s. On iOS, a combination can contain a single virtual Camera, such as a Dual- or Triple-Camera, because that one Camera is backed by multiple physical Cameras. Pass the returned Cameras directly to [`configure(...)`](/api/react-native-vision-camera/hybrid-objects/CameraSession#configure), and use [`physicalDevices`](/api/react-native-vision-camera/hybrid-objects/CameraDevice#physicaldevices) only for inspection. If you need multiple independent previews, choose a combination with at least two Cameras.

```ts
const deviceFactory = await VisionCamera.createDeviceFactory()
const frontAndBackCombination =
  deviceFactory.supportedMultiCamDeviceCombinations.find((devices) => {
    return (
      devices.some((d) => d.position === 'front') &&
      devices.some((d) => d.position === 'back')
    )
  })
if (frontAndBackCombination == null)
  return

const frontDevice = frontAndBackCombination.find((d) => d.position === 'front')
const backDevice = frontAndBackCombination.find((d) => d.position === 'back')
```

### Using multiple Connections

Then, knowing `frontDevice` and `backDevice` can be used simultaneously in a Multi-Cam session, create the outputs and build the [`CameraSessionConnection`](/api/react-native-vision-camera/interfaces/CameraSessionConnection)s:

```ts
const frontPreviewOutput = VisionCamera.createPreviewOutput()
const frontPhotoOutput = VisionCamera.createPhotoOutput({})
const backPreviewOutput = VisionCamera.createPreviewOutput()
const backPhotoOutput = VisionCamera.createPhotoOutput({})

const [frontController, backController] = await session.configure([
  // Front Camera
  {
    input: frontDevice,
    outputs: [
      { output: frontPreviewOutput, mirrorMode: 'on' },
      { output: frontPhotoOutput, mirrorMode: 'off' },
    ],
    constraints: []
  },
  // Back Camera
  {
    input: backDevice,
    outputs: [
      { output: backPreviewOutput, mirrorMode: 'off' },
      { output: backPhotoOutput, mirrorMode: 'off' },
    ],
    constraints: []
  }
])
await session.start()
```

Each returned [`CameraController`](/api/react-native-vision-camera/hybrid-objects/CameraController) correlates to the connection at that index - e.g. `frontController` allows zooming/exposure/focus the `frontDevice`, and vice-versa.

### Picture-in-Picture Multi-Previews

Then, ensure you display both `frontPreviewOutput` and `backPreviewOutput` in separate [`<NativePreviewView />`](/api/react-native-vision-camera/views/NativePreviewView) views:

```tsx
function App() {
  const frontPreviewOutput = ...
  const backPreviewOutput = ...

  return (
    <View style={StyleSheet.absoluteFill}>
      <NativePreviewView
        style={{ flex: 1 }}
        previewOutput={frontPreviewOutput}
      />
      <NativePreviewView
        style={{ flex: 1 }}
        previewOutput={backPreviewOutput}
      />
    </View>
  )
}
```
