Web Components: Building Reusable Elements Without a Framework

Web Components let you build genuinely reusable, framework-agnostic custom HTML elements using only browser-native APIs — no React, Vue, or Svelte required.

class UserCard extends HTMLElement {
    connectedCallback() {
        const name = this.getAttribute('name');
        const shadow = this.attachShadow({ mode: 'open' }); // encapsulated styles

        shadow.innerHTML = <code>
            <style>
                .card { border: 1px solid #ccc; padding: 1rem; border-radius: 4px; }
            </style>
            <div class="card">
                <strong>${name}</strong>
            </div>
        </code>;
    }
}

customElements.define('user-card', UserCard);
<user-card name="Alice"></user-card>

The Shadow DOM is the key piece — styles defined inside it can’t leak out, and outside styles can’t leak in, giving true CSS encapsulation that a plain <div>-based component can never fully achieve, regardless of naming conventions.