Accessing a camera or microphone from a web application has traditionally meant writing JavaScript, requesting permissions, creating a media stream, and connecting that stream to an HTML element.
For many applications, that is more work than necessary.
Chrome 153 adds support for declarative camera and microphone controls through new HTML attributes on media elements. This allows developers to express some media requirements directly in HTML instead of building the entire flow in JavaScript. Chrome's release information for version 153 lists the new controls behavior for camera and microphone elements among its web platform changes.
This article explains how the new approach works, where it fits, how it differs from the existing getUserMedia() model, and what developers should consider before using it in a production application.
The Traditional Way to Access a Camera
Before looking at the newer HTML-based approach, it is useful to understand the traditional JavaScript workflow.
A typical camera application starts with:
const stream = await navigator.mediaDevices.getUserMedia({
video: true
});
The returned stream can then be connected to a video element:
const video = document.querySelector("#camera");
video.srcObject = stream;
The HTML might look like:
<video id="camera" autoplay playsinline></video>
There are several moving parts here:
User action
↓
Request permission
↓
getUserMedia()
↓
Receive MediaStream
↓
Assign stream
↓
Display camera
This model remains important for applications that need detailed control over media streams.
But not every application needs that level of control.
A Declarative Approach
The newer approach lets the browser handle more of the camera or microphone interaction based on HTML.
Instead of writing JavaScript for every part of the initial media interaction, the page can describe the intended media input directly in markup.
The idea is similar to other HTML features:
HTML
↓
Browser understands requirement
↓
Browser handles interaction
↓
User controls permission
This can make simple media workflows easier to build and maintain.
Why Declarative Media Controls Matter
Consider a simple application that needs to let a user select a camera for a video workflow.
With a JavaScript-heavy implementation, developers may need to:
Request permission.
Enumerate devices.
Select the desired device.
Create a media stream.
Handle permission failures.
Attach the stream to the UI.
Stop the stream when it is no longer needed.
For a sophisticated video application, this control is necessary.
For a simple browser feature, it can be excessive.
Declarative media capabilities aim to reduce some of that application-level plumbing.
Camera and Microphone Are Different From Normal HTML Inputs
A camera or microphone is a hardware device.
That means browser security remains important.
A web page cannot simply access a user's camera because an HTML element appears on the page.
The browser still controls access through its permission and security model.
This distinction is important:
HTML declaration
≠
Automatic hardware access without permission
The browser remains responsible for deciding whether access can be granted.
The Existing getUserMedia() API Still Matters
The new declarative capabilities do not make getUserMedia() obsolete.
If an application needs to manipulate a MediaStream, JavaScript is still the appropriate tool.
For example:
const stream = await navigator.mediaDevices.getUserMedia({
video: {
width: 1280,
height: 720
},
audio: true
});
You may need JavaScript when you want to:
Process video frames.
Apply constraints dynamically.
Record media.
Send media through WebRTC.
Select devices programmatically.
Analyze microphone input.
Build custom camera controls.
Combine multiple streams.
The declarative model is most useful when the browser can handle the interaction without application code needing to manage every detail.
Understanding Permissions
Camera and microphone access are sensitive browser capabilities.
A production application should never assume that permission will be granted.
Possible outcomes include:
Permission granted
Permission denied
Permission dismissed
No device available
Device already in use
Browser policy restriction
Your application should have a sensible fallback.
For example:
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: true
});
video.srcObject = stream;
} catch (error) {
console.error("Camera access failed:", error);
}
Even when using newer declarative features, the application should still provide a useful experience when hardware access is unavailable.
HTTPS Is Important
Camera and microphone access are security-sensitive.
Web applications should use a secure context when accessing media devices through browser APIs.
For production:
https://example.com
is the expected deployment model.
Do not design a production camera feature around insecure HTTP.
When testing locally, browsers provide special treatment for local development environments, but production deployment should use HTTPS.
A Simple Camera Application
Consider a basic video meeting page.
The user needs:
Camera preview
Microphone input
Start
Stop
A traditional implementation might contain:
<video id="preview" autoplay playsinline></video>
<button id="start">Start Camera</button>
<button id="stop">Stop Camera</button>
JavaScript then controls the stream:
const preview = document.querySelector("#preview");
let stream;
document.querySelector("#start").addEventListener("click", async () => {
stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
preview.srcObject = stream;
});
document.querySelector("#stop").addEventListener("click", () => {
if (!stream) {
return;
}
for (const track of stream.getTracks()) {
track.stop();
}
preview.srcObject = null;
});
This is still a good approach when the application needs explicit lifecycle control.
The newer declarative features are more interesting for simpler media interactions where that JavaScript lifecycle is unnecessary.
Why Lifecycle Management Still Matters
A camera stream consumes hardware resources.
Stopping the stream when it is no longer required is important.
For a MediaStream, this means stopping its tracks:
for (const track of stream.getTracks()) {
track.stop();
}
Otherwise, an application may leave a camera or microphone active longer than intended.
A good application should always define:
Start
↓
Use
↓
Stop
↓
Release device
This is particularly important for laptops and mobile devices where camera and microphone state is visible to the user.
Camera Indicators Are Part of the User Experience
Modern browsers typically provide visible indicators when camera or microphone hardware is being accessed.
Do not attempt to hide or work around these indicators.
Instead, design the UI so that the application state matches the browser state.
For example:
Camera:
[ ON ]
Microphone:
[ OFF ]
The user should be able to understand when hardware is active.
This is not just a security consideration.
It is a usability requirement.
Handling Missing Hardware
A production application should handle systems without cameras or microphones.
For example:
const devices = await navigator.mediaDevices.enumerateDevices();
const hasCamera = devices.some(
device => device.kind === "videoinput"
);
const hasMicrophone = devices.some(
device => device.kind === "audioinput"
);
if (!hasCamera) {
console.log("No camera detected.");
}
if (!hasMicrophone) {
console.log("No microphone detected.");
}
Do not assume that every desktop or mobile device has both devices.
This becomes particularly important for:
Desktop workstations
Virtual machines
Remote desktops
Kiosk systems
Automated browser environments
Privacy-focused devices
Permission and Device Selection Are Separate Problems
A user can grant camera permission while having multiple cameras.
For example:
Built-in camera
USB webcam
Virtual camera
The application may need to let the user select one.
JavaScript remains useful here.
You can enumerate available video inputs:
const devices = await navigator.mediaDevices.enumerateDevices();
const cameras = devices.filter(
device => device.kind === "videoinput"
);
for (const camera of cameras) {
console.log(camera.deviceId, camera.label);
}
The label information available to applications can depend on permission state.
This is another reason not to think of declarative media controls as a complete replacement for the Media Capture APIs.
When JavaScript Is Still the Better Choice
Use JavaScript when the application needs custom behavior.
Video Recording
For recording, you may need:
const recorder = new MediaRecorder(stream);
You then manage:
dataavailable
start
stop
pause
resume
WebRTC
Video conferencing applications typically need explicit stream management:
Camera
↓
MediaStream
↓
RTCPeerConnection
↓
Remote participant
This requires JavaScript.
Video Processing
Applications that analyze frames may use:
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
and process frames from a video stream.
Again, this is beyond what a declarative HTML feature is intended to replace.
A Useful Rule for Developers
A simple way to decide is:
Need simple browser-managed media interaction?
↓
Consider declarative HTML capabilities.
Need control over the MediaStream?
↓
Use JavaScript APIs.
This keeps the implementation proportional to the application's requirements.
Browser Compatibility Matters
Chrome 153 introduces these newer media-related HTML capabilities, but browser support should always be checked before using them in an application that targets multiple browser engines.
This is especially important for:
Public websites
Enterprise applications
Embedded webviews
Older managed devices
Cross-browser SaaS products
Do not assume that a feature available in the latest Chrome release is automatically available everywhere.
A good deployment strategy is:
Feature detection
↓
Supported
↓
Use new capability
Not supported
↓
Use fallback
For APIs that expose a JavaScript capability, feature detection can often be preferable to browser-version checks.
Testing Camera and Microphone Features
Testing hardware-dependent browser features requires more than a unit test.
A useful test matrix includes:
Test | Expected Result |
|---|---|
Camera available | Camera can be selected |
Microphone available | Microphone can be selected |
Permission granted | Media starts |
Permission denied | Clear fallback shown |
No camera | Application remains usable |
No microphone | Audio fallback shown |
Multiple cameras | Correct device can be selected |
Camera already in use | Error handled |
HTTPS deployment | Media access works |
Unsupported browser | Fallback works |
Also test on real hardware.
A camera feature that works perfectly with a virtual webcam may behave differently with a physical USB device.
Common Mistakes
Assuming Permission Is Guaranteed
Permission is controlled by the browser and user.
Always handle denial.
Leaving Streams Running
Stop tracks when the application no longer needs the camera or microphone.
Building Everything With JavaScript
If the browser can provide the required behavior declaratively, unnecessary JavaScript increases application complexity.
Assuming Declarative Features Replace getUserMedia()
They do not.
Applications that need direct stream control still need the Media Capture APIs.
Ignoring Cross-Browser Support
A Chrome-specific capability should not silently break the application for users on other browsers.
Testing Only on One Device
Camera and microphone behavior can vary significantly across operating systems, browsers, permissions, and hardware.
Hiding Hardware State From the User
The UI should clearly communicate whether camera and microphone functionality is active.
Best Practices
When building camera and microphone features:
Use HTTPS in production.
Request only the media permissions the application actually needs.
Provide a clear fallback when permission is denied.
Stop media tracks when they are no longer required.
Handle systems without cameras or microphones.
Use JavaScript when explicit
MediaStreamcontrol is required.Consider declarative media capabilities for simpler browser-managed interactions.
Test multiple cameras and microphones.
Verify behavior across supported browsers.
Avoid assuming browser version support without testing.
Make camera and microphone state visible to the user.
Keep hardware access proportional to the feature being implemented.
Declarative HTML vs JavaScript Media APIs
Requirement | Declarative HTML | JavaScript APIs |
|---|---|---|
Simple media interaction | Suitable | Suitable |
Direct | Limited | Yes |
Custom device selection | Limited | Yes |
Recording | No replacement | Yes |
WebRTC | No replacement | Yes |
Frame processing | No replacement | Yes |
Custom constraints | Limited | Yes |
Minimal application code | Advantage | More code required |
Complex media application | Usually insufficient | Appropriate |
The key is not choosing one approach for everything.
Use the simplest API that provides the control your application actually needs.
Why This Matters for Web Developers
Modern browser APIs increasingly move functionality from JavaScript into declarative HTML and browser-managed behavior.
This can have a meaningful effect on application architecture.
Instead of:
HTML
↓
Large JavaScript controller
↓
Browser API
↓
Hardware
some use cases can move closer to:
HTML
↓
Browser
↓
Hardware
That can reduce application code and make simple interactions easier to maintain.
But developers should not confuse reduced application code with reduced responsibility.
Permissions, security, browser compatibility, device availability, and lifecycle management still matter.
Advantages and Limitations
Advantages
Less JavaScript for supported use cases.
More declarative application structure.
Browser can manage more of the interaction.
Potentially simpler media-related UI.
Fits the broader direction of modern HTML capabilities.
Limitations
Chrome 153 support does not automatically mean universal browser support.
Complex media workflows still require JavaScript.
Permission handling remains necessary.
Hardware availability cannot be assumed.
Declarative controls do not replace WebRTC, MediaRecorder, or direct
MediaStreamprocessing.Production applications still need fallbacks and device testing.
Summary
Chrome 153 expands the options available to web developers for working with camera and microphone functionality through HTML-based capabilities.
The main benefit is simplicity. For straightforward media interactions, developers can let the browser handle more of the interaction instead of writing JavaScript for every step.
However, getUserMedia() and the broader Media Capture APIs remain important for applications that need direct control over streams, device selection, recording, WebRTC, or video processing.
The practical approach is to use declarative HTML when the browser can provide the behavior you need and JavaScript when the application requires deeper control.
For production applications, always consider permissions, HTTPS, hardware availability, lifecycle management, browser compatibility, and fallback behavior. The best implementation is not necessarily the one with the newest API; it is the one that provides the required media functionality with the least unnecessary complexity.

Join the conversation! Your thoughts help the community grow.