{ Web Component Scaffold }

// scaffold custom elements with shadow dom and slots

Generate custom HTML Web Component class code with Shadow DOM, slots, lifecycle hooks, and attributes. No build tools required. Free browser-based tool.

Lowercase kebab-case, must contain a hyphen
One per line. Use "default" for the unnamed slot.
One per line β€” generates getters, setters, and attributeChangedCallback.
Will be declared in :host { } with placeholder values.
⚑

Ready to scaffold

Fill in the config and click Generate

HOW TO USE

  1. 01
    Name your element

    Enter a kebab-case name with at least one hyphen β€” this is a browser requirement for all custom elements.

  2. 02
    Configure options

    Set Shadow DOM mode, add slots, observed attributes, CSS custom properties, and select lifecycle hooks.

  3. 03
    Copy or download

    Click Generate, then copy the code to your project or download it as a .js file ready to use.

FEATURES

Shadow DOM Slots Observed Attrs Lifecycle Hooks CSS Vars TypeScript Custom Events

USE CASES

  • πŸ”§ Reusable UI components without frameworks
  • πŸ”§ Design system primitives (buttons, badges, cards)
  • πŸ”§ Micro-frontends and widget libraries
  • πŸ”§ Progressive enhancement of existing HTML

WHAT IS THIS?

Web Components are a set of browser APIs that let you create reusable custom HTML elements with encapsulated functionality and style. This generator scaffolds the boilerplate class code so you can start writing logic immediately β€” no build step or framework needed.

RELATED TOOLS

FREQUENTLY ASKED QUESTIONS

Why does a custom element name need a hyphen?

The HTML specification requires all custom element names to contain at least one hyphen (e.g. my-button). This avoids conflicts with future native HTML elements, which never contain hyphens. Names without a hyphen will be treated as unknown elements and fail to register.

What is Shadow DOM and when should I use "closed" mode?

Shadow DOM creates an encapsulated subtree attached to your element, isolating its styles and markup from the main document. "Open" mode allows external JavaScript to access the shadow root via element.shadowRoot. "Closed" mode prevents this access for stronger encapsulation, though it does not offer a true security boundary.

What are slots and how do they work?

Slots are placeholders inside a Shadow DOM template that let users of your component inject their own HTML. A default (unnamed) slot accepts any content placed inside the element. Named slots target specific children using the slot="name" attribute, giving you a flexible component API similar to React children or Vue slots.

What is attributeChangedCallback?

This lifecycle hook fires whenever one of the attributes listed in observedAttributes changes. It receives the attribute name, its old value, and its new value. The generator creates a switch statement for each observed attribute and pairs it with property getters/setters that map to getAttribute / setAttribute.

Do I need a build tool or bundler to use Web Components?

No. Web Components are a set of native browser APIs supported in all modern browsers without any compilation. You can use a <script type="module"> tag to load your component file directly. Build tools like Vite or Rollup are optional and useful for bundling, but are not required for basic usage.

Can I extend built-in elements like buttons or inputs?

Yes β€” this is called "Customized Built-In Elements." Set the Extends field to HTMLButtonElement and use it in HTML as <button is="my-button">. Note: Safari does not support customized built-ins natively; a polyfill such as @ungap/custom-elements is needed for full cross-browser support.

What is a Web Component Scaffold Generator?

A Web Component Scaffold Generator automates the creation of the boilerplate code required to build a standard-compliant HTML Web Component. Writing a custom element class from scratch involves remembering the correct method signatures, the observedAttributes getter syntax, proper Shadow DOM attachment, slot markup, and the nuances of property-attribute reflection. This tool handles all of that so you can jump straight to writing the logic that matters.

πŸ’‘ Looking for production-ready HTML templates and themes? MonsterONE offers unlimited downloads of UI kits, component libraries, and full website templates β€” an excellent companion to your custom components.

The Four Pillars of Web Components

The Web Components specification is made up of four distinct browser APIs that work together to create fully encapsulated, reusable elements.

Custom Elements β€” The CustomElementRegistry API lets you define new HTML tags using customElements.define('my-tag', MyClass). Your class must extend HTMLElement (or a built-in subclass) and can implement a set of standard lifecycle callbacks. This is the backbone of every Web Component.

Shadow DOM β€” Shadow DOM provides encapsulation by attaching a hidden subtree to an element. CSS defined inside a shadow root is scoped to that root by default and does not leak into the main document. This solves one of the oldest pain points in web development: style collisions between components. You can open the shadow root to external JavaScript (mode: 'open') or keep it sealed (mode: 'closed').

HTML Templates & Slots β€” The <template> element holds inert HTML that is not rendered until cloned into the DOM. <slot> elements act as placeholders inside a shadow root where the component's consumers can project their own content. A default slot accepts any children; named slots require the child to carry a matching slot="name" attribute.

ES Modules β€” While not exclusive to Web Components, ES Modules (type="module") are the standard way to package and import component files in the browser. They provide scoped execution, strict mode by default, and native dependency management without a bundler.

Lifecycle Callbacks in Detail

Web Components expose a predictable lifecycle that maps to key moments in an element's life inside the document:

constructor() β€” Called when the element is first created. Shadow DOM is attached and initial state is set up here. You must call super() as the first statement. Avoid reading or modifying attributes or children at this stage, as the element is not yet connected to the document.

connectedCallback() β€” Fires each time the element is inserted into a connected document. This is the right place to start fetching data, adding event listeners, or triggering a first render. It can fire more than once if the element is moved in the DOM.

disconnectedCallback() β€” Fires each time the element is removed from the document. Use this to clean up event listeners, cancel animations, clear timers, and release any resources to prevent memory leaks.

adoptedCallback() β€” Called when the element is moved to a different document β€” for example, via document.adoptNode(). This is rarely needed in practice but is useful when working with iframes or multi-document applications.

attributeChangedCallback(name, oldValue, newValue) β€” Invoked when any attribute listed in the static observedAttributes array is added, changed, or removed. The generated scaffold includes a switch statement for each attribute and pairs each one with a JavaScript property getter and setter, creating a clean public API.

Property–Attribute Reflection

A common best practice in Web Component design is to reflect important properties as attributes and vice versa. This means that setting element.disabled = true in JavaScript should be equivalent to writing <my-button disabled> in HTML. The generated code achieves this by implementing getters that call getAttribute and setters that call setAttribute or removeAttribute. This pattern ensures your component works consistently whether configured declaratively in HTML or programmatically in JavaScript.

CSS Custom Properties and the :host Selector

Shadow DOM encapsulation means external stylesheets cannot reach inside your component. The primary design API for theming a Web Component is CSS custom properties (variables). Because CSS variables inherit through the shadow boundary, a consumer can write my-card { --primary-color: coral; } and the component can read var(--primary-color) inside its shadow root styles.

The :host pseudo-class selector targets the custom element itself from within the shadow root. You can use it to set default display behavior (display: block), respond to host attributes (:host([disabled])), and establish layout that the consumer's CSS can override.

Custom Events for Component Communication

Web Components communicate with the outside world by dispatching native DOM events. The best practice is to dispatch a CustomEvent with a namespaced name (e.g. my-button:click) and pass relevant data in the detail property. Setting bubbles: true allows the event to propagate up the DOM tree, and composed: true lets it cross the shadow boundary so parents in the main document can listen for it. This generator optionally adds this pattern to the connectedCallback as a starting point.

Browser Support and Polyfills

All modern browsers β€” Chrome, Firefox, Safari, and Edge β€” support the core Web Components APIs natively as of 2020 and later. Autonomous Custom Elements (extending HTMLElement) work everywhere without polyfills. Customized Built-In Elements (extending HTMLButtonElement, etc.) are not supported in Safari and require the @ungap/custom-elements polyfill for consistent cross-browser behavior.

β˜•