htmx is a erlang

htmx is a erlang

htmx, a disciple of hypermedia, available only in hardcover do not look for alternatives, has been manifesting itself into existence recently (recently: after 10 years of work1) and has finally reached critical mass2.

let’s look into it.

universal server

joe always said his favorite erlang program was the universal server: a process capable of receiving a message to become another server.

universal server pattern

This is a simple example, but you can imagine such patterns being useful for distributed online upgrades, self-healing/self-patching systems, etc. Basically, when the ‘replace yourself with the body of a message’ request is one of many inputs to the active process3 you can create arbitrarily complex execution hierarchies, W^X be darned.

running it

Basically the total_server:test/0 launches universal_server/0 which accepts a function as a message, then the server, instead of recursing on itself, it runs the received serialized function, then the replaced universal server receives all messages sent to the original server process.

oh thanks for reminding me!

There’s a section of the nicely readable htmx docs saying: where an element specifies a load trigger along with a delay, and replaces itself with the response.

See what they did there? replaces itself with the response 🤔

Instead of just sending a request and receiving data, you send a request and receive a “data as code” result with embedded actions (where actions are limited to the surface of features you currently have enabled or disabled as expected).

If you want to run updates via polling, your page can have an initial fragment for “fetch messages after 1 second then replace this div with the response” automatically triggered request, and the response can also return the same automatic trigger logic where it continues to fetch after the next 1s again too, all until your server stops returning new “fetch and replace after 1s” fragments to the caller:

Basically, instead of receiving a JSON update like:

where you would also need to implement your own custom parser/mini-VM to execute actions based on the reply format, the htmx framework auto-parses results for all htmx-active tags combining maximum flexibility with minimal busywork overhead (plus, additional controlling metadata can be included in response headers as well as html attributes).

takeaway: htmx allows dynamic content replacement, where the content can also issue commands to the current page, including but not limited to also further requesting more remote content to fetch and replace.

You could, if you were weird, pseudo-fork-bomb your site by requesting a fragment which renders two more fragments which continues requesting “fetch -> return 2 more self-fetching fragments” for each instance of the fetch until something breaks; but you can also probably think up more creative uses for APIs capable of returning content capable of using the APIs which caused the original content to be fetched in the first place.

but wut bout muh sekuruty

obviously having any pattern where you consume data then blindly execute based on the result has an attack surface, but security problems are mitigated by two things:

  • there is a big ole phat hx-disable attribute to stop automatic parsing and execution of any children of an element (if you are doing weird things like allowing poorly-sanitized user-generated-content in a page)
  • you’re (hopefully) not fetching results from random servers; htmx is a single-site, single-organization usage pattern and your site is very likely https/tls-end-to-end verified so wobbly nubbins can’t slip in unauthorized.

smol brain security arguments

there’s an entire genre of online down finger 👇 “developer influencers” who dilute the developer noosphere intelligence center of mass towards marketing drivel, but they can’t help but make online weirdo jerks out of themselves:



i think htmx has a bright future in the new-ish genre of “backend-creates-frontend” platforms like:

Basically backend-creates-frontend systems say “hey python, gimme a page with a thing and another thing, and these things can have buttons, and clicking the buttons trigger these python functions, and the result of the functions get populated in the front-end again…” — perfect match for htmx.

Currently BCF systems tend to auto-generate React® front-ends from python specs you write, but python-htmx<->python-htmx seems a much cleaner route.


the recent growing popularity of htmx in all walks of life from cereal flavors to car insurance rates to nuclear security protocols once again is surfacing a problem we haven’t solved: post-cloud-native developers don’t understand basic things anymore.

Every cloud-pilled, react-vue-braindead, click-to-deploy developer actually thinks web views require 7 minutes to “compile for production,” then when live require 5-15 second “skeleton loaders” on entry is just a fact of life nobody can question or ever improve on modern 5 GHz machines with 5 Gbps network connections. Developers, at the median, have been getting less capable and more focused on made up silo/cult/trendy dead-end fads for 10 years and the entire world suffers daily.

do you know why AI chat apps are eating google’s lunch? Because clicking on any google link feels like a slog when every page is slow and bloated and takes 5-15 seconds to do the TLS handshake4, render the laggy SPA async user-hostile stuttering content into view, then load in potentially a dozen ads if you land on the thousands of micro-targeted high-ranking scam sites. Asking a chat bot with infinite knowledge and known latency plus knowing it has zero javascript spyware injection is why google search is dead. Google allowed too many scams and slow sites to rank as the first pages of results to the point where now in 2023 probably 80% of programming search results are just scams or hacks or explots or ad farms. The entire discovery infrastructure of the Internet is broken until AI …. reverses entropy.

reject modernity. embrace html injection again, as is the One True Way to develop, as the gods of YUI and jQuery intended. just splat things into innerHTML whenever you feel like it. we have vanquished the olden uncivilized days of document.write, but we went too far. now we must destroy the shadow dom. shadow, you have no power here, be gone! stop with the “loaders” — here’s a fun game: every time you click on a link, hold your breath until the result loads (not becomes visible and waits for more stuff but actually renders the full page of content). every search engine: click link -> bounce to the spyware search engine link tracker -> bounce to site -> [VISIBLE PAUSE DURING TLS HANDSHAKE] -> the site has an async SPA loader -> wait 3-5-15+ more seconds -> get content (plus 74 ads if you don’t have an adblock installed).

content is god. javascript is abomination. htmx is space pope keeping the many angled ones at bay.

yeeeeeeeeeeeeeee haw.

  1. which is better than what i did, where i spent 10,000 hours creating the world’s most efficient in-memory database compatible as a memcache and redis replacement, but then i didn’t tell enough people so the code is amazing but actively abandoned until it receives the breath of life again: /

  2. 2033: “The HTMX Story” by Christopher Nolan premieres to a record breaking $2 billion opening weekend. (actually, sorry, due to climate change and AI we actually have less than 3 years left in total, but it’s a nice thought)

  3. also, just for good erlang hygiene: you basically never want to run bare processes like this. You want to run everything wrapped in a gen_server or similar to prevent rookie mistakes like having your processes crash because they are attached to the wrong parent hierarchy, etc.

  4. nothing makes you hate TLS as much as trying to use the internet from the under side of the world with long latency and overburdened cables everywhere.