1 min read

Building a zero-dependency web component from scratch

Why reach for a library when the platform already has everything you need?

The first time I read the Custom Elements spec I closed the tab immediately. It felt like ceremony for something that should be simple. Six months later I came back, and something clicked.

The key insight

A custom element is just a class. You register it, the browser instantiates it when it sees your tag, and connectedCallback fires when it lands in the DOM.

class ReadingTime extends HTMLElement {
  connectedCallback() {
    const words = this.closest('article')
      ?.textContent.split(/\s+/).length ?? 0;
    this.textContent = ${Math.ceil(words / 200)} min read;
  }
}

customElements.define('reading-time', ReadingTime);

That's it. Drop anywhere near an article and it self-populates.

Why this matters

The platform ships features you never reach for because you assume they aren't there yet.

Once you internalize that, a lot of framework code starts looking like work you're doing for the browser, not with it.