JavaScript Navigator mediaDevices Property

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline
Secure context

What You’ll Learn

navigator.mediaDevices returns a MediaDevices object for cameras, microphones, and screen sharing. Learn getUserMedia, enumerateDevices, secure context rules, five examples, and try-it labs.

01

Kind

Read-only property

02

Returns

MediaDevices

03

Baseline

Widely available

04

Context

Secure (HTTPS)

05

Key API

getUserMedia()

06

List

enumerateDevices()

Introduction

Video calls, camera filters, and voice notes all start the same way: ask the browser for a live media stream from a camera or microphone.

navigator.mediaDevices is the modern entry point. MDN describes it as a singleton MediaDevices object — you usually call methods on it directly, such as navigator.mediaDevices.getUserMedia(). It belongs to the Media Capture and Streams API and pairs closely with WebRTC.

💡
Permission + HTTPS

Browsers only expose this API in a secure context. Live capture also needs the user’s permission. Always feature-detect, handle denial, and stop tracks when you are done.

Understanding the mediaDevices Property

Think of it as the browser’s “media hardware front desk”: list devices, request a stream, and react when hardware is plugged in or removed.

  • Value — the MediaDevices singleton.
  • getUserMedia(constraints) — returns a Promise for a MediaStream.
  • enumerateDevices() — lists audio/video input and output devices.
  • devicechange — event when devices are added or removed.
  • Also — related helpers like getDisplayMedia() for screen sharing (support varies).
  • Baseline — Widely available (MDN, since about September 2017); secure context required.

📝 Syntax

General form of the property:

JavaScript
navigator.mediaDevices

Value

  • A MediaDevices object (usually used via its methods, not by reading fields).

Common patterns

JavaScript
// Feature detect + secure context:
if (navigator.mediaDevices && window.isSecureContext) {
  // ready to call getUserMedia / enumerateDevices
}

// Typical camera + mic request:
navigator.mediaDevices
  .getUserMedia({ video: true, audio: true })
  .then(function (stream) {
    // video.srcObject = stream;
  })
  .catch(function (err) {
    console.error(err.name, err.message);
  });

⚡ Quick Reference

GoalCode
Get the API objectnavigator.mediaDevices
Feature detectBoolean(navigator.mediaDevices)
Secure context?window.isSecureContext
Request camera/micnavigator.mediaDevices.getUserMedia(constraints)
List devicesnavigator.mediaDevices.enumerateDevices()
Status (MDN)Baseline Widely available · Secure context

🔍 At a Glance

Four facts to remember about navigator.mediaDevices.

Returns
MediaDevices

API entry

Baseline
widely

Since ~Sep 2017

Context
HTTPS

Secure required

Star method
getUserMedia

Live MediaStream

📋 mediaDevices vs legacy getUserMedia

navigator.mediaDevicesLegacy navigator.getUserMedia
StylePromise-based modern APICallback-based (deprecated path)
EntrymediaDevices.getUserMedia()navigator.getUserMedia / prefixed variants
ExtrasenumerateDevices, devicechange, display captureCapture only (limited)
Use today?Yes — preferredNo — migrate away

Examples Gallery

Examples follow MDN MediaDevices patterns. Prefer Try It Yourself on HTTPS or localhost. Camera/mic demos need user permission.

📚 Getting Started

Detect the API and list connected devices safely.

Example 1 — Feature + Secure Context Check

Confirm mediaDevices exists and the page is in a secure context.

JavaScript
const lines = [
  "secure: " + window.isSecureContext,
  "mediaDevices: " + Boolean(navigator.mediaDevices)
];
if (!window.isSecureContext) {
  lines.push("Serve over HTTPS (or localhost) to use mediaDevices");
} else if (!navigator.mediaDevices) {
  lines.push("Secure, but MediaDevices API not exposed");
} else {
  lines.push("Ready for getUserMedia / enumerateDevices");
}
console.log(lines.join("\n"));
Try It Yourself

How It Works

On plain HTTP (non-localhost) mediaDevices is often missing even in modern browsers.

Example 2 — Enumerate Devices

List audio/video inputs and outputs. Labels may be blank until permission is granted.

JavaScript
navigator.mediaDevices.enumerateDevices()
  .then(function (devices) {
    console.log("count: " + devices.length);
    devices.slice(0, 5).forEach(function (d) {
      console.log(
        d.kind + " | " +
        (d.label || "(no label yet)") + " | " +
        d.deviceId.slice(0, 8) + "…"
      );
    });
  });
Try It Yourself

How It Works

Each entry has kind, label, deviceId, and groupId. Empty labels protect privacy before consent.

📈 Practical Patterns

Live capture, device changes, and a reusable readiness helper.

Example 3 — getUserMedia (Camera + Mic)

Request a live stream. The browser shows a permission prompt when needed.

JavaScript
async function startPreview() {
  if (!navigator.mediaDevices) {
    return "MediaDevices API not available.";
  }
  const stream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
  });
  const tracks = stream.getTracks().map(function (t) {
    return t.kind + ":" + t.label;
  });
  // Important: stop tracks when you no longer need them
  stream.getTracks().forEach(function (t) { t.stop(); });
  return "got stream → " + tracks.join(", ");
}

startPreview()
  .then(function (msg) { console.log(msg); })
  .catch(function (err) {
    console.log(err.name + ": " + err.message);
  });
Try It Yourself

How It Works

On success you get a MediaStream. Attach it with video.srcObject = stream in a real UI, and always stop() tracks when finished.

Example 4 — Listen for devicechange

Refresh your device list when the user plugs in a headset or webcam.

JavaScript
if (!navigator.mediaDevices) {
  console.log("MediaDevices API missing");
} else {
  navigator.mediaDevices.addEventListener("devicechange", function () {
    console.log("devicechange — re-run enumerateDevices()");
  });
  console.log("Listening for devicechange…");
  // Plug/unplug a USB mic to see the event in Try It Yourself
}
Try It Yourself

How It Works

Use the event to update camera/mic dropdowns without forcing a full page reload.

Example 5 — MediaDevices Readiness Helper

Summarize secure context, API presence, and method availability in one object.

JavaScript
function mediaDevicesStatus() {
  const md = navigator.mediaDevices;
  return {
    secure: window.isSecureContext,
    available: Boolean(md),
    getUserMedia: Boolean(md && md.getUserMedia),
    enumerateDevices: Boolean(md && md.enumerateDevices),
    getDisplayMedia: Boolean(md && md.getDisplayMedia)
  };
}

console.log(JSON.stringify(mediaDevicesStatus(), null, 2));
Try It Yourself

How It Works

Gate your UI: show “HTTPS required” vs “Allow camera” vs “Screen share not supported” based on these flags.

🚀 Common Use Cases

  • Video calls — capture local camera/mic for WebRTC peer connections.
  • Photo / AR filters — pipe getUserMedia into a <video> or canvas.
  • Voice notes — record mic audio with MediaRecorder.
  • Device pickers — build camera/mic dropdowns from enumerateDevices.
  • Screen sharing — where supported, getDisplayMedia for tabs or screens.

🧠 How navigator.mediaDevices Works

1

Secure page loads

HTTPS / localhost exposes navigator.mediaDevices.

HTTPS
2

You request a stream

getUserMedia prompts for camera/mic permission.

Permission
3

Browser returns MediaStream

Live tracks you can show, record, or send via WebRTC.

Stream
4

Stop tracks when done

Turn off the camera LED and free hardware.

📝 Notes

  • Baseline Widely available (MDN, since about September 2017).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Secure context required (HTTPS / localhost).
  • Some related methods (e.g. display capture) have varying support — feature-detect each.
  • Related: mediaSession, mediaCapabilities, JavaScript hub.

Universal Browser Support

navigator.mediaDevices is Baseline Widely available (MDN: since about September 2017) but requires a secure context. Related helpers like getDisplayMedia may vary — feature-detect them separately.

Baseline · Secure context

Navigator.mediaDevices

Entry point for camera, microphone, device lists, and related capture APIs on HTTPS pages.

Universal Widely available
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
mediaDevices Excellent

Bottom line: Use HTTPS, feature-detect mediaDevices, request permission with getUserMedia, and always stop tracks when finished.

Conclusion

navigator.mediaDevices is the modern gateway to cameras, microphones, and related capture APIs. Serve over HTTPS, call getUserMedia with clear constraints, list devices with enumerateDevices, and stop tracks when you are done.

Continue with mediaSession, mediaCapabilities, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Serve pages over HTTPS (or use localhost)
  • Feature-detect before calling getUserMedia
  • Handle NotAllowedError and NotFoundError
  • Stop all tracks when the preview closes
  • Re-enumerate after devicechange

❌ Don’t

  • Use legacy callback navigator.getUserMedia
  • Assume device labels exist before permission
  • Leave the camera running in the background
  • Request audio+video if you only need one
  • Ignore secure-context failures on HTTP

Key Takeaways

Knowledge Unlocked

Five things to remember about mediaDevices

Baseline MediaDevices entry — secure context, getUserMedia, enumerateDevices.

5
Core concepts
🔒 02

Context

HTTPS

Secure
🎤 03

Capture

getUserMedia

Stream
📋 04

List

enumerateDevices

Devices
05

Status

Baseline

Wide

❓ Frequently Asked Questions

It is a read-only Navigator property that returns a MediaDevices object — the entry point for cameras, microphones, and related media input/output APIs such as getUserMedia() and enumerateDevices().
No. MDN marks it Baseline Widely available (since about September 2017). It is not Deprecated, Experimental, or Non-standard. Some related methods have varying support.
Yes in supporting browsers: mediaDevices is available only in secure contexts (HTTPS or localhost).
navigator.mediaDevices.getUserMedia(constraints) asks the user for permission and returns a MediaStream with live audio and/or video tracks — the foundation of video calls, filters, and recording.
Before permission is granted, enumerateDevices() often returns devices with empty label strings for privacy. After the user allows camera/mic access, labels usually appear.
No. It is read-only. You use methods on the MediaDevices object; you do not assign a new value to navigator.mediaDevices.
Did you know?

MDN notes you usually do not “read” mediaDevices for data — you call its members directly, like navigator.mediaDevices.getUserMedia(). The property is just the doorway to the MediaDevices singleton.

Explore mediaSession Next

Learn how to show now-playing info and handle media keys.

mediaSession →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful