All work
Open Source

HMPL.js

Contributing to a template language whose entire premise is fetching HTML and rendering it safely.

Ongoing
Maintained
Solo
Open Source Contributor
HMPL.js, Lightweight Server-Oriented Template Language

The problem

The default way to make a page dynamic is now to ship a large JavaScript bundle, fetch JSON, and rebuild the DOM on the client. For a great many applications that is an enormous amount of machinery in service of "load this fragment and put it here".

HMPL takes the older position: let the server send HTML, and give the client just enough to place it. The interesting engineering is in what "just enough" is allowed to cost.

The constraint

It is not your codebase

Contributing to someone else's library is a different discipline from building your own. The design philosophy is already set, the API surface is already promised to people using it, and the maintainers have opinions you were not in the room for.

HMPL's promise is that it stays small. That makes every addition a negotiation, a feature that would be obviously worth it in an application may be obviously wrong here, because the bundle size is not a metric the project tracks, it is the reason the project exists.

And the premise carries a permanent security question: the whole point is fetching markup from a server and putting it into a live page. Do that carelessly and you have not written a template language, you have written an XSS vector.

What I built

  1. 01

    Server-oriented by design

    The server owns the markup; the client places it. Rendering logic that would otherwise be duplicated on both sides, and drift between them, only ever exists in one of them.

  2. 02

    Safe rendering is the default, not a setting

    Fetched HTML is treated as untrusted at the boundary rather than sanitised by whoever remembers to. A safety feature that has to be switched on is a safety feature most projects ship without.

  3. 03

    Bundle size is the feature

    Every addition is weighed against the number the project is judged on. Working inside that means proposing things in the smallest form that still solves the problem, and accepting no as a reasonable answer more often than you would on your own code.

  4. 04

    Types ship with it

    TypeScript definitions travel with the package, so consumers get the API surface in their editor instead of in a documentation tab.

Open channel

Got something
like this to build?

Happy to talk through how any of this was put together, or what it would take to do something similar.