I often find myself in situations making dynamic web pages that should have a minimal footprint or very ad-hoc conceptual pages. For instance this contract generator (Norwegian link) we use for generating employment or client contracts at my company. Or if we just want to enhance a webpage with some additional dynamic content, or progressively add features. We shouldn’t need to bring out all the bells and whistles, build steps and tools by default. There has to be an actual need and benefit. Adding build steps and tools means added maintenance. Also trying to keep the number of bytes reasonably low, adding frameworks or libraries doesn’t make sense.

This is a long-winded way of saying I regularly use the DOM API manually. And honestly, I don’t mind it. The DOM API has come a long way. For instance, did you know you now can use array functions on NodeLists? Might seem like a small win, but things like these make the DOM API more ergonomic. But still, the DOM is very imperative, which doesn’t quite fit for the type of features mentioned above, or with my style of programming for that matter. However, with the power of modern APIs and JavaScript, we can fix that with little effort and some code! Let’s see how we can create a React-like abstraction with a few lines of modern JavaScript. Throughout this example, I will use features that are regarded as new, which is in the language specification and supported by all major modern browsers.

Central to this technique is meta programming and JavaScript Proxies. I won’t go too deep in this post. If you want to learn more I recommend checking out this repository I made with numerous examples, videos, and articles.

The DOM

First, let us see how the DOM works, and how you can create new elements, set attributes, add children and output them on the page. It mostly consists of a combination of 5 API points: createElement() , setAttribute() , appendChild() , classList and textContent .

Imagine that we have a list of names I want to project as an HTML list to my users. We can output that by creating an unordered list with list items and outputting this to the body.

This is very verbose, imperative and tedious. Of course, we can abstract some of it and make it a bit more flexible.

Much better, but imagine doing a simple AJAX call that returns an object of 10 fields and you have to manually create all the fields. Or dynamic forms with an arbitrary number of fields. Or whatever that is just a bit more complex than this example.

What if we write something like this instead:

Or even

This would ease our way of creating DOM elements significantly, but it will also allow us to easier read what is happening, better allow for creating our components (roughly similar to React) and make it easier to declaratively update element trees.

But before we can do that, we need to understand a very powerful API in JavaScript; The proxy.

The JavaScript Proxy

We could have created our abstraction by making helper functions.

But this would require us to write something like:

Which is fine. But we can do better.