Embracing standards is better than chasing frameworks

The DOM Component Manifesto

by Joe Honton, Read Write Tools

It seems like every time a developer discovers a good coding pattern, they want to turn it into a framework. Good for them. They've found something that works and want to share it with others. But I've found something that works for me, and you probably have too. So we don't need their framework, because it solves their problem, not ours.

Instead, what we need is simply a consistent way to produce good results.

So, for consistency, I've chosen to follow a standard pattern for all of the DOM components I've built in order to achieve those good results. While it's tempting to turn this pattern into a framework, I've intentionally resisted that urge. That turned out to be a good decision.

Yes, each DOM component has the same initialization pattern, and the same reliance on event-based communication, and many of the same function names. But that's where the pattern ends and the unique aspects of the component begins. Instead of fighting a framework, writing code whose only purpose is to get around some unaccounted-for limitation, developers should be given the freedom to adapt my pattern, or your pattern, in any way that makes sense.

So for me frameworks are out, and patterns are in. But which pattern?

The answer is all around us. It is simply to embrace the languages and protocols and open standards that have been developed and freely given to us, laid before us like gleaming treasure.

My philosophy for DOM components is to embrace the standards developed by the World Wide Web Consortium (W3C), Ecma International, and the Internet Engineering Task Force (IETF). These are the deliberative bodies that have worked so hard to give us a way to markup, style, script, and deliver a great web experience across a diverse set of hardware devices.

My philosophy embraces isolation, separation, modularization, configuration, and best practices. It's a five-part DOM Components Manifesto.


Isolation — DOM component's raison d'être. This is where shadow DOM fits in. It establishes a firewall between the host document and the component instance: one can't affect the other. Plus, an all important corollary to this is that my component can't cause your component to fail.

Isolation also means that each instance of a defined component gets its own namespace. Thus, element identifiers and CSS classnames can be simple and to-the-point, without prefixes or instance qualifiers.

An identifier like #xyzFrame001 could be shortened to just #frame. Even better, a CSS selector for anchor elements, like a.specialLink {...} might be reduced to just a {...}, completely eliminating the need for classnames in many cases.

Most importantly, isolation eliminates a wide range of hard-to-track-down bugs that promiscuous CSS seems to propagate with such ease.


Separation — as in separation of concerns. This is one of the most important software development mantras of the past two decades. It's helped us to achieve the level of success we now have. The former use of all-in-one languages has declined over the years, while the use of separate languages for markup, styling and scripting has risen. Sadly, some brand-new frameworks seem to have forgotten this golden rule.

In order to get the benefit of great tooling, like syntax highlighting, linting, inspecting, profiling, and compliance checking, the code we write should place each language in its own file.

The hidden bonus to this approach is caching. HTML templates are loaded once and cached by the browser; CSS declarations are loaded once and cached by the browser; JavaScript modules are loaded once and cached by the browser. Automatically, without any effort on our part.


Modularization — the holy grail. JavaScript has finally grown up and given us a good way to keep variables out of global scope. Every major browser now supports ESNext modules, so now is the time to embrace the simplicity and safety of modules.

Significantly this means: no transpilation or shims; no manifest or packaging overhead; and no bundlers or splitters or loaders. It means we can simply write our scripts and deploy them directly to the server. We can rediscover the fun of interpreted JavaScript.

And because browsers load scripts only when needed, we don't have to do anything special to gain the benefits of just-in-time, on-demand loading.


Customization — usage in alternate settings. Components should be designed to accommodate distinctly different values. And components should allow consumers to apply their own decorative branding to its visual interface.

DOM standards give us three ways to expose this customization to our component consumers: with slotted elements, with HTML attributes, and with CSS variables. These are native to the HTML and CSS languages, so they use the same syntax and follow the same idiomatic expressions as everything we've already learned. Unlike props, they look and feel like the real thing, because they are.


Best practices — guidelines and guardrails that make everything better. Remember, our collective success is the result of hard-fought battles. Best practices are simply a distillation of all the strategies and safety rules that helped us to win those battles. Here's what works for DOM components:

  • Use a modern HTTP/2 server to eliminate latency and to move component files from server to browser in one continuous session.
  • Migrate away from legacy transpiler/bundler/splitter/loader life-cycles. Adopt the newer ESNext approach to asynchronous, modular, cacheable delivery.
  • Come to terms with the reality that browser scripting is based on an object model. Use classes and object instances in your scripts — after all, the entire DOM is proof that object oriented programming works.
  • Stop chasing undefined errors: replace anonymous objects with declared classes that have well-defined shapes and proper constructor initialization.
  • Use events instead of callbacks. Remember that the biggest breakthrough of the 1980s was event driven programming. It's what enables all our mouse and windows behavior. It's the original non-blocking coding pattern.

For a more in-depth exploration see The 7 Facets of DOM Components and The Trilingual Pattern.

That's my manifesto. Five clear ideas that solve all of my DOM component problems. No more semiannual overhauls to upgrade to the latest breaking-change framework. No more chasing after shiny new things. All standards based. All future proofed.

Read Write Tools icon

Smart tech

READ WRITE TOOLS

Read Write Hub icon

Distraction-free writing

RWDOC

BLUEPHRASE icon

Rediscover HTML

BLUE PHRASE

Read Write Serve icon

Served with pure HTTP/2

RWSERVE

Embracing standards is better than chasing frameworks

🔗 🔎