JavaScript Element customElementRegistry Property

Beginner
5 min read
Updated: Nov 2026
3 examples
Property

Definition

Element.customElementRegistry is a read-only property that returns the CustomElementRegistry associated with this element, or null if none has been set (MDN).

Read the notes below before you get or set this property. Prefer feature detection when support is limited.

Syntax

Use el.customElementRegistry. Start with this line.

JavaScript
element.customElementRegistry
CallWhat it does
element.customElementRegistryPrimary signature.

Built into the browser. Read or assign el.customElementRegistry — no import required.

Library declarations
JavaScript
element.customElementRegistry

Parameters

ParameterDescription
Feature detectRequired. Property is not Baseline yet

Return Value

Return ValueDescription
*CustomElementRegistry or null

JavaScript Examples

Example 1 — Feature-Detect and Read

Check support, then read customElementRegistry on a plain element.

JavaScript
if ("customElementRegistry" in Element.prototype) {
  const el = document.createElement("div");
  console.log(el.customElementRegistry);
  // often null, or the associated registry when set
} else {
  console.log("not supported");
}
Try It Yourself

How It Works

  1. Detect the property. Avoids errors where scoped registries are missing.
  2. Create a plain div. No scoped registry was passed at creation.
  3. Read the property. Often null until a registry is associated.
  4. Fallback. If unsupported, skip scoped-registry logic.

Example 2 — Scoped Registry in Shadow DOM

MDN shape: define on a scoped registry and confirm the upgraded element matches.

JavaScript
const myRegistry = new CustomElementRegistry();
myRegistry.define(
  "my-element",
  class extends HTMLElement {
    connectedCallback() {
      this.textContent = "Hello from scoped registry!";
    }
  }
);

const host = document.createElement("div");
document.body.appendChild(host);
const shadow = host.attachShadow({
  mode: "open",
  customElementRegistry: myRegistry
});
shadow.innerHTML = "<my-element></my-element>";

const el = shadow.querySelector("my-element");
console.log(el.customElementRegistry === myRegistry);  // true
Try It Yourself

How It Works

  1. Build a scoped registry. new CustomElementRegistry() is separate from customElements.
  2. Define a tag. my-element exists only in that registry.
  3. Pass the registry into shadow. Parsed children use those definitions.
  4. Compare with ===. The upgraded node’s property is that same registry object.

Example 3 — Scoped vs Global Registry

Show that a scoped association is not the same object as window.customElements.

JavaScript
const scoped = new CustomElementRegistry();
scoped.define("x-tag", class extends HTMLElement {});

const host = document.createElement("div");
document.body.appendChild(host);
const shadow = host.attachShadow({
  mode: "open",
  customElementRegistry: scoped
});
shadow.innerHTML = "<x-tag></x-tag>";

const el = shadow.querySelector("x-tag");
console.log(el.customElementRegistry === scoped);         // true
console.log(el.customElementRegistry === customElements); // false
Try It Yourself

How It Works

  1. Create a scoped registry. It is a different object from customElements.
  2. Attach and upgrade. The shadow tree uses the scoped definitions.
  3. Match the scoped object. === scoped is true.
  4. Reject the global. === customElements is false — that is the point of scoping.

Browser Support

Element.customElementRegistry has Limited availability (MDN: not Baseline). Tied to scoped custom element registries — supported in recent Chromium and Safari; Firefox support is incomplete.

✓ Limited availability

Element.customElementRegistry

Read-only CustomElementRegistry or null — set at creation for scoped definitions.

Limited Not Baseline
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
customElementRegistry Detect first

Bottom line: Gate with if ("customElementRegistry" in Element.prototype). Prefer progressive enhancement; do not require scoped registries for core UX until Baseline improves.

Frequently Asked Questions

The CustomElementRegistry associated with the element, or null if none has been set. That registry decides which custom element definitions are used when the element is upgraded.
No. MDN does not mark Element.customElementRegistry as Deprecated, Experimental, or Non-standard. It has Limited availability (not Baseline) — always feature-detect.
No. It is read-only. Once a CustomElementRegistry is set on the element, it cannot be changed.
When the element is created — for example Document.createElement() with a customElementRegistry option, or when parsed inside a context that already uses a scoped registry (such as a shadow root created with that option).
window.customElements is the global registry. Element.customElementRegistry can point at that global registry or at a scoped CustomElementRegistry used only in a subtree (often a shadow tree).
So different components can define the same custom tag name without colliding in the global customElements registry.

Next: elementTiming

Learn the Element Timing identifier used for performance observation.

elementTiming tutorial →

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.

11 people found this page helpful