A purely functional approach to UI composition with ES6/TypeScript

Update 2019: Take a deeper look at this and related projects in this ongoing blog series: Of umbrellas, transducers, reactive streams & mushrooms…

The ease of turning nouns into verbs is an almost unmatched feature of the English language and it’s a central tenet of what follows: The idea of turning the composition and continuous (re)creation of a user interface into a verb, an action, a process, a function.

Among UI & UX enthusiasts there never seems to be a short supply of “next generation frameworks”, promising more efficiency, simplicity and happiness in all your component and templating needs, so please don’t be surprised to read about yet another one of those. Please also don’t be too quick with that browser back button of yours — you might regret it later… :)

Speaking of templating (at least how it’s done 95% of the time): It’s actually the first point I’d like to address and seriously question why the vast majority of designers & developers still thinks this is a Great Idea™. Frameworks like React, Angular, Vue etc. have taken over our little world by storm and as much as I applaud the many innovations they have brought to the table, and as much as they differ internally, they all embrace HTML in the most literal way.

At first glance this is of course completely natural. HTML is the only way to make a browser show us what we want to build and I still have no quarrel with that after 23 years working with it. However, being a markup language, it doesn’t really play that nice (nor was it ever meant to) with the other standard ingredient used to build modern UI’s — JavaScript. So the (obvious) solution the big players all have decided on, was to conjure up new file formats, allowing frontend developers to sprinkle snippets of HTML-ish looking markup all over their source files and then in turn require an impressive array of tooling, engineering, documentation, education, project specific component libraries, editor support projects, parsers, compilers, source map generators, scaffolding helpers, each with endless dependencies and totaling millions of man-years of effort. And that all to magically transform this frankensteinish marriage of reactified, angularized, vue-ed, marked-up JavaScript back into… JavaScript. And all that because we seemingly cannot give up on using HTML to define our UIs. And all that because our framework uses a slightly different approach than the “other” and hence requires a similar duplication of effort. And all that because even though JavaScript is the most popular and widely used programming language of the past 10 years, we still can’t bring ourselves to give up on the overall still same old idea of PHP-era templating engines and fail to see our UIs for what they really are:

In CS speak: Derived views of pure data

Seriously, this is nothing new and it’s the essence of the MV* design pattern flavors almost all modern UI frameworks are based upon. I do believe however that somewhere along the “V”(iew) parts of these patterns we collectively took the wrong turn (more like missed it in our excitement of a brighter future) and forgot about data being just data, meaning in a Turing-complete language like JavaScript, it should be easily possible to create those derived views without having to resort to HTML magic injection pills. Not just that, but also maybe do so much more elegantly and powerfully, merely by using the host language to its full extent. Also remember, none of the mentioned frameworks actually cares about HTML as a runtime format. Each one manipulates the browser DOM via JavaScript commands, commands which were pre-compiled from their HTML-ish template snippets. Therefore the presence of HTML syntax almost purely exists for authoring & code generation purposes and is there for a perceived convenience and shallow transition curves from previous approaches. MVC was about the separation of concerns. Gang of Four. Enterprise patterns for Dummies. Separation of concerns in software design shouldn’t necessarily mean separation of technologies, as is the case for us now. What if we give HTML the same treatment or role as was proposed for JavaScript a while back:

HTML is (just) an UI assembly language

JavaScript has come a long way to become what it is today and many of the more recent additions to the language have (ad)dressed its largest open wound and reduced it to a mere, occasional sore spot, i.e. working with data. And this is true both in terms of data structures & data flow. ES6 spread operator, iterators, generators, maps, sets, template literals — for the purposes of this article only some of them are relevant (hint: it’s not template literals!) and I’ve often wondered why the following approach has not become more common. But first some more prior art: