react-instant-camera
v1.0.1
Published
A React instant camera component
Readme
react-instant-camera
A modern, highly customizable React library for capturing photos and recording videos directly from the browser camera.
It provides a ready-to-use <ReactCam> component with an imperative API, as well as a headless useCamera hook for completely custom UI implementations. Built with TypeScript and React 19+.
Features
- 📸 Capture Photos: Take high-quality screenshots from the camera feed.
- ⏺️ Record Video: Record video streams using the native
MediaRecorderAPI. - ⚙️ Headless Hook: Use
useCameraif you want to build your own custom video element and UI. - 🔌 Component Wrapper: Use
<ReactCam>for a plug-and-play component with built-in preview and CSS filter support. - 🔄 Camera Switching: Built-in device enumeration to easily switch between front/back cameras or external webcams.
- 🎨 Customizable: Apply CSS filters directly to the stream (e.g., grayscale, blur).
Installation
npm install react-camQuick Start
Using the <ReactCam> Component
The easiest way to get started. The component handles rendering the <video> element and image previews, while exposing imperative camera methods via a React ref.
import { useRef, useState } from 'react';
import { ReactCam, ReactCamHandle } from 'react-cam';
import 'react-cam/style.css'; // Optional minimal styles
export default function App() {
const camRef = useRef<ReactCamHandle>(null);
const [photo, setPhoto] = useState<string | null>(null);
return (
<div>
<ReactCam
ref={camRef}
width={640}
height={480}
showPreview={true}
onImageCapture={(dataUrl) => setPhoto(dataUrl)}
/>
<div style={{ marginTop: 10, display: 'flex', gap: 10 }}>
<button onClick={() => camRef.current?.startCamera()}>Start Camera</button>
<button onClick={() => camRef.current?.capturePhoto()}>Capture Photo</button>
<button onClick={() => camRef.current?.retake()}>Retake</button>
<button onClick={() => camRef.current?.stopCamera()}>Stop Camera</button>
</div>
{photo && (
<div>
<h3>Captured Photo:</h3>
<img src={photo} alt="Captured" width={320} />
</div>
)}
</div>
);
}Using the useCamera Hook (Headless)
If you need complete control over the DOM layout, use the hook directly.
import { useCamera } from 'react-cam';
export default function CustomCamera() {
const cam = useCamera({
width: 1280,
height: 720,
onImageCapture: (dataUrl) => console.log('Captured:', dataUrl),
});
return (
<div>
<video ref={cam.videoRef} autoPlay playsInline muted />
<button onClick={cam.startCamera}>Start</button>
<button onClick={cam.capturePhoto}>Capture</button>
</div>
);
}API Reference
<ReactCam> Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| width | number | undefined | The ideal width for the camera stream. |
| height | number | undefined | The ideal height for the camera stream. |
| captureFit | 'cover' \| 'contain' | 'cover' | How the captured image is cropped to fit the stream aspect ratio. |
| deviceId | string | undefined | Specific device ID to request via getUserMedia. |
| fileName | string | 'capture.png' | Default filename used when saveOnClick or saveVideoOnStop triggers a download. |
| saveOnClick | boolean | false | If true, capturing a photo automatically triggers a download. |
| saveVideoOnStop | boolean | false | If true, stopping a recording automatically triggers a video download. |
| cssFilter | string | undefined | CSS filter string applied to the live video (e.g., 'grayscale(1)'). |
| showPreview | boolean | false | If true, <ReactCam> renders the captured image over the video stream. |
| showError | boolean | false | If true, <ReactCam> displays an error message if camera access fails. |
| errorMessage | string | 'Camera access was denied.' | The text to display when showError is true. |
| className | string | undefined | Additional CSS class for the root wrapper. |
Event Callbacks
| Callback | Signature | Description |
|----------|-----------|-------------|
| onImageCapture | (dataUrl: string) => void | Fired when a photo is captured. |
| onVideoRecorded | (event: VideoRecordedEvent) => void | Fired when a video recording stops and the blob is ready. |
| onRecordingChange | (isRecording: boolean) => void | Fired when video recording starts or stops. |
| onError | (err: Error) => void | Fired when camera access or enumeration fails. |
| onCamerasEnumerated| (event: CamerasEnumeratedEvent) => void | Fired when the list of available cameras is retrieved. |
Component Ref Handle (ReactCamHandle)
When passing a ref to <ReactCam>, you get access to these imperative methods:
startCamera(): Promise<void>— Requests permissions and starts the camera stream.stopCamera(): void— Stops the camera stream and turns off the hardware.capturePhoto(): void— Captures a frame from the live video.retake(): void— Clears the current capture and resumes the live video.startRecording(): void— Starts recording a video stream.stopRecording(): void— Stops recording and emits the video blob.
Browser Support
Requires modern browser features including navigator.mediaDevices.getUserMedia and MediaRecorder. For local development, you must use localhost or https:// as browsers block camera access on insecure origins.
License
MIT
Author
Faizal Hussain ([email protected])
