
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
react-camera-component
Advanced tools
A reusable React component for capturing images and videos from the camera.
A lightweight, headless React camera component for capturing images and recording videos. Built with TypeScript and designed for maximum flexibility.
npm install react-camera-component
import { CameraComponent } from "react-camera-component";
function App() {
const handleCapture = (media) => {
console.log("Captured:", media);
};
return (
<div style={{ width: "100%", height: "100vh" }}>
<CameraComponent onCapture={handleCapture} />
</div>
);
}
| Prop | Type | Default | Description |
|---|---|---|---|
autoPlayOnStart | boolean | true | Start camera stream automatically on mount |
facingMode | "user" | "environment" | "user" | Initial camera facing mode |
maxVideoDuration | number | 60000 | Maximum video recording duration (ms) |
imageFormat | "image/png" | "image/jpeg" | "image/webp" | "image/png" | Format for captured images |
imageQuality | number | 1 | Image quality between 0 and 1 |
displayStream | boolean | true | Show/hide video stream |
captureAudio | boolean | false | Enable audio capture for videos |
containerClassName | string | undefined | CSS class for container div |
frameRate | number | 30 | Video frame rate |
width | number | 1280 | Ideal video width |
height | number | 720 | Ideal video height |
onCapture | (media: CapturedMedia) => void | undefined | Callback when media is captured |
onStreamStart | (dimensions: Dimensions) => void | undefined | Callback when stream starts |
onError | (error: Error) => void | undefined | Error handler callback |
Access camera methods using a ref:
import { useRef } from "react";
import {
CameraComponent,
CameraComponentHandles,
} from "react-camera-component";
function App() {
const cameraRef = useRef<CameraComponentHandles>(null);
return (
<>
<CameraComponent ref={cameraRef} autoPlayOnStart={false} />
<button onClick={() => cameraRef.current?.startStream()}>
Start Camera
</button>
<button onClick={() => cameraRef.current?.captureImage()}>
Take Photo
</button>
<button onClick={() => cameraRef.current?.toggleRecording()}>
Record Video
</button>
</>
);
}
startStream(facingMode?: "user" | "environment"): Promise<void> - Start camera streamstopStream(): void - Stop camera streamcaptureImage(): void - Capture a photostartRecording(): void - Start video recordingstopRecording(): void - Stop video recordingtoggleRecording(): void - Toggle recording stateswitchCamera(): void - Switch between front/rear camerasisStreaming: boolean - Current streaming stateisRecording: boolean - Current recording statevideoElement: HTMLVideoElement | null - Access to video elementinterface CapturedMedia {
type: "image" | "video";
url: string; // Blob URL for preview/download
timestamp: number; // Capture timestamp (Date.now())
blob: Blob; // Raw media data
}
interface Dimensions {
width: number;
height: number;
}
import { useRef, useState } from "react";
import {
CameraComponent,
CameraComponentHandles,
CapturedMedia,
} from "react-camera-component";
function CustomCamera() {
const cameraRef = useRef<CameraComponentHandles>(null);
const [media, setMedia] = useState<CapturedMedia[]>([]);
const handleCapture = (captured: CapturedMedia) => {
setMedia((prev) => [...prev, captured]);
};
return (
<div>
<CameraComponent
ref={cameraRef}
onCapture={handleCapture}
captureAudio={true}
/>
<div className="controls">
<button onClick={() => cameraRef.current?.captureImage()}>
📷 Photo
</button>
<button onClick={() => cameraRef.current?.toggleRecording()}>
🎥 {cameraRef.current?.isRecording ? "Stop" : "Record"}
</button>
<button onClick={() => cameraRef.current?.switchCamera()}>
🔄 Flip
</button>
</div>
<div className="gallery">
{media.map((item, i) => (
<img key={i} src={item.url} alt={`Capture ${i}`} />
))}
</div>
</div>
);
}
const handleCapture = async (media: CapturedMedia) => {
const formData = new FormData();
const filename = `${media.type}-${media.timestamp}.${
media.type === "image" ? "png" : "webm"
}`;
formData.append("file", media.blob, filename);
await fetch("/api/upload", {
method: "POST",
body: formData,
});
};
<CameraComponent onCapture={handleCapture} />;
<CameraComponent
imageFormat="image/jpeg"
imageQuality={0.95}
width={1920}
height={1080}
onCapture={handleCapture}
/>
<CameraComponent
facingMode="environment"
captureAudio={true}
maxVideoDuration={120000}
onCapture={handleCapture}
/>
function ControlledCamera() {
const cameraRef = useRef<CameraComponentHandles>(null);
const [isActive, setIsActive] = useState(false);
const toggleCamera = async () => {
if (isActive) {
cameraRef.current?.stopStream();
} else {
await cameraRef.current?.startStream();
}
setIsActive(!isActive);
};
return (
<>
<CameraComponent ref={cameraRef} autoPlayOnStart={false} />
<button onClick={toggleCamera}>
{isActive ? "Stop" : "Start"} Camera
</button>
</>
);
}
const handleError = (error: Error) => {
switch (error.name) {
case "NotAllowedError":
alert("Camera permission denied");
break;
case "NotFoundError":
alert("No camera found");
break;
case "NotReadableError":
alert("Camera is already in use");
break;
default:
console.error("Camera error:", error);
}
};
<CameraComponent onError={handleError} />;
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| getUserMedia | 53+ | 49+ | 11+ | 79+ |
| MediaRecorder | 47+ | 25+ | 14.1+ | 79+ |
Requirements:
useEffect(() => {
return () => {
media.forEach((item) => URL.revokeObjectURL(item.url));
};
}, [media]);
const handleCapture = (media: CapturedMedia) => {
setMediaList((prev) => [...prev, media].slice(-10)); // Keep last 10
};
The component renders a simple container with a video element. Style it however you like:
.container {
position: relative;
width: 100%;
height: 100%;
background: #000;
}
.stream {
width: 100%;
height: 100%;
object-fit: cover;
}
Or use inline styles:
<CameraComponent
containerClassName="my-camera"
style={{ borderRadius: "12px" }}
/>
Camera won't start
Poor video quality
width and height propsRecording fails
MediaRecorder browser supportcaptureAudio is true)mimeType if neededContributions welcome! Please open an issue or submit a PR.
MIT
Made with ❤️
FAQs
A reusable React component for capturing images and videos from the camera.
The npm package react-camera-component receives a total of 0 weekly downloads. As such, react-camera-component popularity was classified as not popular.
We found that react-camera-component demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.