<x-toc>

A table of contents that follows the reader through the headings of an article.

Add a section

Events appear here.

Web components in ClojureScript started as an experiment born from frustration with a client stack of re-frame, React and many supporting libraries. Web components promise encapsulation and smaller bundles, but their API is complex and they leave rendering to you.

What is a web component

A web component is a custom HTML element. Once it is registered, the browser treats it like a native element.

It rests on three standards: custom elements, shadow DOM for private styling, and templates for internal structure. A bento grid built from custom tags shows how they fit together.

What does an implementation have to cover

A component has to handle identity, inputs, rendering, lifecycle, encapsulation, slots, outputs, styling, accessibility and form behaviour.

Each of these is a responsibility for the author of the component. None of them comes for free.

Writing a Web Component in CLJS

The approach follows the design choices of BareDOM, so it is opinionated. A decorative animated component, x-gaussian-blur, shows what a web component can do.

Let's start writing a Web Component in Clojurescript

The tutorial builds x-icon, a small component that wraps an SVG and exposes theming options.

Step 1: start with data

The model file defines the tag name, the observed attributes, and the public property, event and method APIs. Parsers fall back to defaults on bad input, and a normalise function turns raw attributes into a clean view model.

The DOM file then sets up the shadow root, runs a read, check and apply render pipeline, and wires the lifecycle callbacks.

Web components are not that simple

Forms and buttons add complexity, but the process stays the same. Shared code in BareDOM is reused across components.

What do you get for it?

The icon component adds about 2 KB to a bundle.

It depends on no framework, so it works in plain JavaScript and in Angular, React, Solid, Svelte and Vue.

What isn't covered here

Server-side state, efficient re-rendering and debugging are left for a follow-up post.

Source code

BareDOM holds more than 100 web components. The source and a demo are on GitHub.

Inside a scrolling panel

The scroll root is the nearest scrolling ancestor of the article. Here it is the panel, not the page.

What is a web component

A custom HTML element that the browser treats like a native one once it is registered.

It rests on custom elements, shadow DOM and templates.

Writing a Web Component in CLJS

The approach follows the design choices of BareDOM.

A model file holds the data. A DOM file holds the effects.

What do you get for it?

About 2 KB per component, and no framework to depend on.

It works in plain JavaScript and in every major framework.

What isn't covered here

Server-side state, re-rendering and debugging come in a follow-up post.