A lightweight, zero-dependency library to robustly detect the primary rear camera on mobile devices (📱 iOS & Android).
Dual-camera, triple-camera, and quad-camera phones expose multiple lenses (ultra-wide, telephoto, macro, infrared) to the browser. This often leads to web applications selecting the wrong or suboptimal camera.
The Proctored Exam Problem: I went through this exact issue while appearing for a certification exam. The exam's web app selected my phone's macro lens, making my ID and face blurry and unrecognizable. This frustrating experience led me to build a better, reusable, and fully open-source utility to solve this problem once and for all.
Whether you're building a barcode scanner, a proctored exam interface, or just a standard photo capture app, this library safely filters and returns the main/wide camera that is best suited for the job. 🎯
- Modern Device Support: Explicitly penalizes ultra-wide, telephoto, and macro lenses which are terrible for general purposes like barcode scanning or exam proctoring.
- Cross-Platform: Handles iOS ("Back Camera") and Android ("camera 0") quirks seamlessly.
- Framework Agnostic: Works perfectly in Vanilla JS/TS, with dedicated hooks available for React and Next.js.
- Caching: Utility to persist the optimal device ID, speeding up subsequent application loads.
- Zero Dependencies: Tiny bundle size to keep your application fast.
npm install detect-primary-cameraimport { getBestRearCamera, getAndSetBestRearCamera, FACING_MODE } from 'detect-primary-camera';
// Example 1: Get the best camera directly
const cameraId = await getBestRearCamera();
if (cameraId) {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
deviceId: { exact: cameraId }
}
});
}
// Example 2: Detect the best camera and cache the result for the next time
const cachedCameraId = await getAndSetBestRearCamera();For React applications, a dedicated hook is provided to handle resolution state and cleanup automatically.
import { usePrimaryCamera } from 'detect-primary-camera/react';
const CameraComponent = () => {
// Automatically uses cached IDs and handles loading/error states cleanly!
const { cameraId, loading, error } = usePrimaryCamera();
if (loading) return <div>Detecting camera...</div>;
if (error) return <div>Error: {error.message}</div>;
return <video autoPlay playsInline muted id={cameraId} />;
};We welcome contributions from the community! Whether it's adding a new feature, fixing a bug, or improving documentation, your help is greatly appreciated.
Please see the CONTRIBUTING.md file for more information on how to get started, set up your development environment, and submit a Pull Request.
MIT © Sumit Sahoo
Please refer to the LICENSE file for the complete license details.