Skip to content
Frameworks Article

Web Components Finally Learn Progressive Enhancement

A 2.9kB library named Elena bets your design system belongs to the platform, not the framework.

Priya Nair
Priya Nair
AI & Developer Experience Writer · Aug 1, 2026 · 5 min read
Web Components Finally Learn Progressive Enhancement

Web components have spent a decade losing the framework wars while quietly winning the standards war. Custom elements ship in every browser, big design systems use them under the hood, and yet the day-to-day experience — flash of unstyled content, layout shifts, shadow DOM fighting your global styles, server rendering as an afterthought — has kept plenty of teams on React components they know they'll rewrite in five years anyway.

"Progressive Web Components," a pattern named by design systems architect Ariel Salminen and embodied in his new Elena library, is the most coherent attempt yet to fix that experience. The core claim is simple: a component should be two layers, not one. A base layer of HTML and CSS that renders immediately, before any JavaScript arrives. An enhancement layer of JavaScript that adds reactivity, event handling, and richer templating once it does. If the script never loads — ad blockers, flaky mobile networks, an RSS reader that strips scripts — the component still shows up and mostly works.

If that sounds familiar, it should. This is progressive enhancement, the oldest good idea on the web, finally applied to the component model with enough rigor to be reusable.

The pattern is older than the name

Salminen didn't invent this from nothing, and it's worth being clear-eyed about the lineage. Jeremy Keith and Zach Leatherman were championing "HTML web components" — custom elements that wrap server-rendered light-DOM markup instead of generating everything client-side — back in late 2023. Enhance built a whole framework around HTML-first components. What Salminen adds is taxonomy and tooling: he splits the space into composite components (wrap and enhance HTML composed inside them), primitive components (self-contained, rendering their own light-DOM markup), and declarative components (using Declarative Shadow DOM when you genuinely need style isolation without giving up server rendering).

That taxonomy matters because the platform only recently made all three legs stand. Declarative Shadow DOM didn't reach cross-browser baseline until Firefox picked it up in early 2024. React 19 — the last major holdout — shipped full custom element support at the end of 2024, killing the most durable excuse for avoiding web components in mixed codebases. Progressive Web Components isn't a new capability; it's the first pattern language written for a platform that finally works.

What Elena actually is

Elena is a 2.9kB (minified and compressed), zero-dependency, MIT-licensed base class for building components this way, published as @elenajs/core with companion SSR, CLI, and bundler packages. The API is deliberately boring:

import { Elena } from "@elenajs/core";

class Stack extends Elena(HTMLElement) {
  static tagName = "my-stack";
  static props = ["direction"];
  direction = "column";
}
Stack.define();

Props and state changes trigger batched re-renders; the full custom element lifecycle, templates, slots, and both light and shadow DOM are supported. Because the base layer is just HTML and CSS, "SSR support" mostly means not needing any — your server, whether it's Rails, Next.js, or a static site generator, emits markup and Elena hydrates on top. That's a genuinely different posture from Lit, where server rendering runs through @lit-labs/ssr and still carries the render-from-JavaScript mindset, or Stencil, which brings a compiler to the party.

Dan Q's take — that Elena's appeal is what it doesn't do — is the right frame. It doesn't impose a templating DSL, a build step, or a client runtime tax on your users. For design system teams serving React, Vue, and legacy server-rendered apps from one component library, that's the actual pitch: one implementation, no per-framework wrapper packages, no hydration ceremony.

The honest caveats

The Lobsters discussion around the announcement surfaced the real objections, and they're worth taking seriously.

First, the confusion at the heart of the branding: progressive enhancement here does not mean your interactive components work without JavaScript. A client-rendered list still needs a script to render. What the pattern buys you is that server-rendered markup displays instantly — no FOUC, no layout shift, no blank custom element waiting for definition. That's valuable, but it's a narrower promise than "works without JS," and you have to architect for it: the server has to emit real markup, which means your CMS or backend templates now share responsibility for component structure.

Second, light-DOM-first means giving up style encapsulation as the default. That's the correct trade for a design system that wants to inherit brand styles and play nicely with global CSS — it's precisely why shadow DOM has been a recurring accessibility and theming headache — but if you're shipping third-party embeds into hostile pages, you still want the declarative shadow DOM variant, and now you're managing two mental models.

Third, Elena itself is weeks-old software at version 1.0.1 with a small community. Commenters flagged template-literal interpolation as an XSS foot-gun and side-eyed the need for a scaffolding CLI at all. Fair hits. Nobody should bet a Fortune 500 design system on the library today.

Adopt the pattern, watch the library

Here's the judgment call: Progressive Web Components the pattern is production-ready right now, because its failure mode is plain HTML — the least risky failure mode on the web. If you maintain a design system consumed by more than one framework, your next component should be a custom element that wraps server-rendered markup and enhances it. You can do that today with zero libraries, and Keith, Leatherman, and Enhance have three years of prior art showing how.

Elena the library is a well-designed reference implementation that earns a spot in a side project, not yet your dependency tree. At 2.9kB it's cheap to trial, and if it accumulates the community and hardening it needs, it slots into the niche Lit never quite filled: the boring, standards-shaped base class for teams who think the platform, not the framework, should own their components.

The deeper signal is that this got traction at all. Ten years of web components discourse was about whether they could replace frameworks. This wave isn't trying to. It's about components that outlive frameworks — and after watching teams rewrite the same button through three framework migrations, that's the version of the pitch that finally lands.

Sources & further reading

  1. Progressive Web Components — arielsalminen.com
  2. Elena — Progressive Web Components — elenajs.com
  3. arielsalminen/elena — github.com
  4. ElenaJS (Progressive Web Components) — danq.me
  5. Progressive Web Components discussion — lobste.rs
Priya Nair
Written by
Priya Nair · AI & Developer Experience Writer

Priya covers AI frameworks, developer productivity tooling, and the startup ecosystem across South and Southeast Asia, bringing a researcher's rigour and a practitioner's empathy to every story. She is deeply sceptical of benchmarks and asks hard questions so her readers don't have to.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading