A quick update on ESX

Andrea Giammarchi
4 min readJan 19, 2023


Photo by Louis Reed on Unsplash

I’ve been exploring for the last few months a way to improve the current state of JSX and while I’ve found already a great way to speed it up, I’ve also came up with a TC39 proposal to rebrand the abandoned “standard” and adopt it in ECMAScript as part of the JS’ core.

This post would like to summarize where we are with ESX.

The proposal

If you have “infinite time” on your pockets please do read the whole TC39 thread. The TL;DR though, is that:

  • somebody really believe template literals were born to provide JSX like cases, kinda ignoring the state of the Web development in the last 10 years
  • somebody really like the proposal but had to amend it or rise valid concerns … and we’re currently at the third iteration of such proposal with all concerns basically solved

Asking me, one of the first implementer of a reactive HTML/SVG as template literal tag libraries that doesn’t trash the DOM, doesn’t suffer innerHTML issues, and it smoked in 2017 all others, “why not implementing this with templates” means only one answer: “because I’ve pushed this pattern for 5 years and nobody cares + others, including Google, also pushed this without nearly as much success as everyone expected”.

After this summary of my answer the proposal branched out and I’ve felt a bit disrespected and sad … and yet, I’ve worked on a 100% zero-tooling, template literals strings based proposal, namely @ungap/esx, which offers everything ESX has to offer through an API so cool one could even serialize it and revive it with components and without any issue: I’m super happy about the result, yet I am (was, keep reading) skeptical about results and/or performance.

Others kept suggesting improvements from a standardization point of view, and while I welcome all the hypothetical issues they are trying to solve, I want/need a product that showcases already ESX in all its glory.

The udomsay library

After a lot of refactoring around the dedicated Babel ESX transfomer, reflected through the template literal @ungap/esx module already mentioned, I’ve managed to also fully rewrite udomsay 🥳

The highlight of this library is:

  • it’s fully based on signals, a wonderful pattern that simplifies hooks mental overhead, explained at its core in this post
  • any signal library that can provide a way to understand what is a signal, create an effect, and retrieve the signal value, can be used, including (at this time) preact, solid-js, my tiny signal library, or usignal (currently not working 100% as expected, but that’s on usignal)
  • it works regardless of your choice: you went for Babel ESX transfomer? Good! You decided to use template literals? Great!

Let’s see a classic counter example via template literals, and imagine you don’t need to create the esx tag or use templates tags with the Babel ESX transform:

The performance

Well … I’d be damned, but I couldn’t believe not only udomsay with preact signals is faster than previous hinted JSX based attempt, which was already very fast in the game, but the template literal in that specific benchmark scores even better!

udomsay-tpl VS udomsay-esx

Considering that it needs zero tooling, but that arguably has definitively worse DX compared to JSX syntax, I am actually glad they pushed me that hard to find a solution that works seamlessly with template literal strings too 🥳

What’s next

I haven’t been full time on this project but I’ve worked on it almost 4 months and finally I can showcase results, write more examples, documentation, and improve all areas that need improvements, including providing out of the box more signals based libraries, while keeping the conversation with TC39 hopefully going on, as it’d be awesome to have all of this in core (imagine performance improvements all over the place) but also, everything is out and working, which is, I believe, a great starting point, as I’ve imagined ESX and iterated a few times to end up with 2 different yet same implementation that show strength, minimal code size (we’re under 3Kb here with signals included) and some fresh new way to deliver JSX like apps.

Most notably, I am still trying to figure out how to bring this to SSR + islands architecture, because so far I only have a very fast, clean, and simple SSR implementation that also just works both as template literal strings and as ESX transformed.

stay tuned” would be a lame end to this post so … “hack a way” and give it a try or contribute as you like, ’cause I am also after new challenges so from now on, when everything looks working fine and fast, there won’t be many other updates, also because the syntax is well established in the industry, and so is the signals pattern, or used libraries 👋



Andrea Giammarchi

Web, Mobile, IoT, and all JS things since 00's. Formerly JS engineer at @nokia, @facebook, @twitter.