# Camera Upload (/docs/components/camera-upload)



<ComponentPreview name="camera-upload" />

## Installation [#installation]

<Tabs items="[&#x22;Command&#x22;, &#x22;Manual&#x22;]">
  <Tab value="Command">
    <CodeBlockTabs defaultValue="npm">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="npm">
          npm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="pnpm">
          pnpm
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="yarn">
          yarn
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="bun">
          bun
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="npm">
        ```bash
        npx shadcn@latest add @uploadcn/camera-upload
        ```
      </CodeBlockTab>

      <CodeBlockTab value="pnpm">
        ```bash
        pnpm dlx shadcn@latest add @uploadcn/camera-upload
        ```
      </CodeBlockTab>

      <CodeBlockTab value="yarn">
        ```bash
        yarn dlx shadcn@latest add @uploadcn/camera-upload
        ```
      </CodeBlockTab>

      <CodeBlockTab value="bun">
        ```bash
        bun x shadcn@latest add @uploadcn/camera-upload
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Tab>

  <Tab value="Manual">
    Install [Upload](/docs/components/upload), then copy:

    <ComponentSource name="camera-upload" />

    <ComponentSource name="use-camera" />
  </Tab>
</Tabs>

## Usage [#usage]

```tsx
import { CameraUpload } from "@/components/camera-upload"
```

```tsx
<CameraUpload facingMode="user" maxFiles={5} />
```

`CameraCapture` is exported too, drop it inside any `<Upload>` to add a viewfinder. The [`useCamera`](#usecamera) hook releases the camera on unmount.

## useCamera [#usecamera]

The hook behind the viewfinder. It's installed with the component.

```tsx
const { videoRef, status, start, stop, flip, capture } = useCamera()

<video ref={videoRef} muted playsInline />
<button onClick={() => start()}>Open camera</button>
<button onClick={async () => uploader.add([await capture()])}>Snap</button>
```

`status` is `idle`, `starting`, `ready`, `denied`, `unavailable` or `error`.

## Props [#props]

<TypeTable
  type="{
  adapter: {
    type: &#x22;UploadAdapter&#x22;,
    default: 's3Adapter({ endpoint: &#x22;/api/upload&#x22; })',
    description: &#x22;Where files go.&#x22;,
  },
  uploader: {
    type: &#x22;Uploader&#x22;,
    description: &#x22;An uploader from `useUploader`, instead of options.&#x22;,
  },
  maxFiles: { type: &#x22;number&#x22;, default: &#x22;10&#x22; },
  facingMode: { type: '&#x22;user&#x22; | &#x22;environment&#x22;', default: '&#x22;environment&#x22;' },
  onSuccess: { type: &#x22;(item) => void&#x22; },
  className: { type: &#x22;string&#x22; },
}"
/>
