Document.customElementRegistry is a read-only instance property that returns the CustomElementRegistry for this document, or null. Learn how it relates to window.customElements, why some created documents have a null registry, how ShadowRoot shares the same property name, and five examples with try-it labs.
01
Kind
Read-only
02
Returns
Registry | null
03
Alias
window.customElements
04
Also on
ShadowRoot
05
Support
Limited
06
Status
Not Baseline
Fundamentals
Introduction
Custom elements let you invent HTML tags like <my-card>. The browser keeps a registry of those tag names and their class definitions. Most tutorials use window.customElements (or just customElements) to call define(), get(), and whenDefined().
document.customElementRegistry is the Document’s way to reach that registry object. MDN: for documents associated with a Window (a normal page), it is the same global registry as window.customElements. Documents created with createHTMLDocument() often have null by default.
💡
Limited availability
MDN marks this property Limited availability (not Baseline). Always feature-detect ("customElementRegistry" in Document.prototype or a try/catch around reading it). Everyday custom elements via customElements.define() remain widely available.
registry.define("my-x", class extends HTMLElement {})
Fallback
Use window.customElements when property missing
MDN status
Limited availability (not Baseline)
Snapshot
🔍 At a Glance
Four facts about document.customElementRegistry.
Type
CustomElementRegistry | null
Or null
Access
read-only
No setter
Main page
=== customElements
Usually
Status
limited
Not Baseline
Compare
📋 Common CustomElementRegistry methods
Method
Purpose
define(name, constructor)
Register a custom element class
get(name)
Return the constructor, or undefined
whenDefined(name)
Promise that resolves when the name is defined
upgrade(root)
Upgrade custom elements in a subtree
getName(constructor)
Look up the registered name (where supported)
Hands-On
Examples Gallery
Examples follow MDN Document: customElementRegistry. Feature-detect in unsupported browsers. Use View Output or Try It Yourself for each case.
📚 Getting Started
Compare the main document registry with the global one (MDN).
Example 1 — Same as window.customElements (MDN)
On a Window-associated page document, both accessors refer to the same registry.
JavaScript
// Main document registry is the global one (when supported):
console.log(
document.customElementRegistry === window.customElements
); // true on Window-associated documents
get() avoids double-define errors if the lab runs more than once. Prefer unique names in real apps.
Example 5 — ShadowRoot.customElementRegistry (MDN)
The same property name exists on shadow roots for scoped registries.
JavaScript
const host = document.createElement("div");
const root = host.attachShadow({ mode: "open" });
console.log(
"ShadowRoot has customElementRegistry:",
"customElementRegistry" in root
);
console.log("shadow registry:", root.customElementRegistry);
// May be null or a scoped/global registry depending on browser & options
Document.customElementRegistry is marked Limited availability on MDN (not Baseline). Everyday window.customElements has much wider support. Logos use the shared browser-image-sprite.png sprite from this project.
✓ Limited availability · Not Baseline
Document.customElementRegistry
CustomElementRegistry or null — the registry associated with this document (often the same as window.customElements).
LimitedNot Baseline
Google ChromeSupporting recent Chromium — verify version
Check version
Microsoft EdgeFollow Chromium support
Check version
OperaFollow Chromium where available
Check version
Mozilla FirefoxMay require pref / lag behind — feature-detect
Limited
Apple SafariCheck current Safari — feature-detect
Limited
Internet ExplorerNo Custom Elements / no this property
No support
Document.customElementRegistryLimited
Bottom line: Feature-detect document.customElementRegistry. For basic custom elements, window.customElements.define() remains the portable choice. Check current MDN compatibility tables before shipping scoped-registry code.
Wrap Up
Conclusion
Document.customElementRegistry exposes the custom element registry for a document (or null). On normal pages it matches window.customElements; on some created documents it does not. Because support is limited, detect the property and keep customElements.define() as your everyday tool.
Feature-detect before reading document.customElementRegistry
Treat null as a real possibility on created documents
Use window.customElements for portable beginner examples
Check registry.get(name) before re-defining
Read MDN compatibility when using scoped registries
❌ Don’t
Assume every browser exposes the Document property yet
Call methods on a null registry
Confuse this Limited property with Baseline customElements
Assign to document.customElementRegistry
Skip unique tag names (must include a hyphen)
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about document.customElementRegistry
Registry or null — often the same as window.customElements.
5
Core concepts
🛠01
Returns
registry | null
API
✓02
Main page
=== customElements
MDN
🔒03
Access
read-only
DOM
⚠️04
Support
limited
Not Baseline
🎨05
Also on
ShadowRoot
Scoped
❓ Frequently Asked Questions
The CustomElementRegistry associated with this document, or null if one has not been set. On a normal page document it is usually the same object as window.customElements.
MDN does not mark Document.customElementRegistry as Deprecated, Experimental, or Non-standard. It is Limited availability (not Baseline) — support is incomplete across major browsers, so feature-detect before production use.
For documents associated with a Window (the main page), MDN says they are the same global registry. document.customElementRegistry is the Document-side accessor and can be null on some programmatically created documents.
MDN: documents created programmatically (for example via DOMImplementation.createHTMLDocument()) have a null custom element registry by default.
Yes. MDN notes the same customElementRegistry property is also available on ShadowRoot, which matters for scoped custom element registries.
Yes. Defining custom elements with customElements.define() remains the everyday API. Use document.customElementRegistry when you need the document's registry object or to handle null / scoped cases.
Did you know?
Scoped custom element registries exist so two libraries can both define <my-button> without colliding globally—each shadow tree can use its own registry. document.customElementRegistry is part of that newer story, which is why support is still catching up.