Hyperscript Tagged Markup (HTM): JSX alternative using standard tagged templates, with compiler support.

・1 min read

This is an interesting library by @_developit , creator of Preact.

developit / htm

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.

HTM (Hyperscript Tagged Markup) npm

hyperscript tagged markup demo

htm is JSX-like syntax in plain JavaScript - no transpiler necessary.

Develop with React/Preact directly in the browser, then compile htm away for production.

It uses standard JavaScript Tagged Templates and works in all modern browsers.

htm by the numbers:

🐣 < 700 bytes when used directly in the browser

βš›οΈ < 500 bytes when used with Preact (thanks gzip 🌈)

πŸ… 0 bytes when compiled using babel-plugin-htm

Syntax: like JSX but also lit

The syntax you write when using HTM is as close as possible to JSX:

  • Spread props: <div ...${props}>
  • Self-closing tags: <div />
  • Components: <${Foo}> (where Foo is a component reference)
  • Boolean attributes: <div draggable />

Improvements over JSX

htm actually takes the JSX-style syntax a couple steps further!

Here's some ergonomic features you get for free that aren't present in JSX:

  • No transpiler necessary
  • HTML's optional quotes: <div class=foo>
  • Component…

Compared with JSX:

  • No transpiler necessary
  • HTML's optional quotes:
  • Component end-tags: <${Footer}>footer content<//>
  • Syntax highlighting and language support via the lit-html VSCode extension and vim-jsx-pretty plugin.
  • As of 2.0.0, htm is stable, well-tested and ready for production use.

DISCUSS (28)
 

It seems like the biggest win here is not having to use a transpiler, though I feel like most projects would already have Babel in there. Other than that, not sure if this buys the developer anything that JSX doesn't since the syntax is still somewhere in between HTML and JSX. However, cool and interesting approach!

 

You still need babel if you want to compile it for production, to get rid of the extra bytes.

To me, the benefit of actually using it in existing Preact/React code is that it is actually much closer to HTML. Being able to use class instead of className is nice :)

 

What I meant is that either way you are taking a bunch of markup syntax and translating it to React.createElement() calls. Whether you import a library function and do that work there or let a Babel plugin do the work, it's up to you. The latter is a bit cleaner IMO but it requires a transpile step. If you're doing that anyway then may as well use JSX.

Yes exactly, in most build setups using HTM will be compiled just like JSX is.

After thinking about it a bit more, these are my reasons why to use HTM over JSX:

  • it's less magic, as you can see that it's a Tagged Template
  • because of less magic, it's also more beginner friendly
  • it's closer to HTML, without JSX limitations like class/className

And the biggest reason: no build step! I mean, look at the example... it's a 3.7KB js dependency and you can build preact apps!

To me, this is a taste of the future. A future where build tools won't be necessary anymore. Until then, we still need to transpile, code-split, optimize etc. using build/bundle tools like webpack.

 

Yeah. In most cases these days, the transpiler is a given. However, I could imagine a lot of circumstances where evaluating without transpiration is much more convenient. Enough so to possibly drop the need for jsx altogether.

Had these two things come along at the same time, good chance we don't bother with the rigmarole of jsx.

 

If Babel isn't necessary, I wonder what would happen under the hood if you bundled a new project with Parcel.

 

No transpiler necessary

This is it for me. That is the benefit. I believe that is one of the reasons Vue got so many beginners excited about frontend. You could start learning about the framework without introducing any of the noice of modern tooling.

I learned about React a couple of years ago, when I first heard the term "transpiler" it made want to skip it (and I did). It took me a year and half (and working with node) to gather the confidence to finally tackle this "transpiler" thing (A.K.A. babel and his friend webpack) Even after learning how to use it I hated it.

 

Try LitElement, and you'll get templating AND component model using built-in features.

dev.to/bennypowers/lets-build-web-...

 

Thanks for the link. Now I'm interested.

Do you know if lit-html works with JSDOM? I would to make test like this one during development.

I've had some peripheral issues like javascript module support with jsdom

But barring those kinds of problems (which are, to be clear, problems with node-based tools not able to run browser-standard JavaScript), you should be golden.

You might consider karma, or puppeteer or Cypress for browser testing, since those tools will actually run your cove in the environment you are targeting.

open-wc.org/recommendations/testin...

 

I see this opinion all around and don't get it at all.
One of the best features of Vue for me is single-file-components, which of course necessitate a bundler.
The "full build" option that allows templating at runtime seems like cruft that I would rather development time wasn't spent oh.

 

To me is more about the learning phase (from a beginner perspective). You can play around with Vue even if you don't know anything about bundlers. If the learning experience is pleasant then people will be encourage to dig deeper. Eventually they will get to the "advance" stuff, but hopefully they get there with enough confidence in their knowledge and see it as "just another step".

I guess this can help adoption when someone is really just using notepad and a browser.
But for me the best way to "try a framework" was always
git clone framework-start-example test or pnpx framework-cli init test
followed by cd test && pnpm i && pnpm run dev with hot reloading and stuff.

notepad and a browser.

That's my jam. Replace notepad with Sublime text and you basically described my development environment when I started learning. It would be awesome if I could work just using those two.

Now that I think about it, it is sad that CLI tools and boilerplate code is the "new normal" when you create client side javascript.

Anyway, when trying anything javascript related my favorite way is using codepen (the notepad of javascript online editors).

I don't find it sad at all. It's a huge relief for me.
How do you feel about codesandbox.io?

 

So long as the file extensions don't become .htm ;)

 
 

From what I'd gather:

htm is looking to act as a convenient alternative to jsx to fit the workflow of folks in react/preact land. lit-html is more of a whole new thing that is technically similar, but not coming from the same place in terms of developer experience.

One other difference in practical terms

htm:

As of 2.0.0, htm is stable, well-tested and ready for production use.

lit-html:

lit-html is currently in development. It's on the fast track to a 1.0 release, so we encourage you to use it and give us your feedback, but there are things that haven't been finalized yet and you can expect some changes.

 

lit-html has an RC release and is expecting a 1.0 release in January.

Another potential perk of lit-html is it's backed by a team of developers at Google and is well tested by being used in Polymer/LitElement.

 

As of 2.0.0, htm is stable

Semantic versioning, javascript community edition :)

 
 

And is made to build web components platform compliant, not abstractions.

Good point. You won't have the same kinds of issues with event listeners and losing references to DOM

 

I'm torn.

On the one side it works without pre-compilation, on the other hand nobody deploys stuff without pre-compliation these days anyway.

On the one hand it has the shorter end-tag syntax, on the other hand most components have short names anyway.

<Text>Hello</Text>
h`<${Text}>Hello<//>`

<VeryLongComponentName>Hello</VeryLongComponentName>
h`<${VeryLongComponentName}>Hello<//>`

<List><Item>1</Item><Item>2</Item><Item>3</Item><Item>4</Item<Item>5</Item></List>
h`<${List}><${Item}>1<//><${Item}>2<//><${Item}>3<//<${Item}>4<//><${Item}>5<//><//>`

I think, the end-tags are a bit harder to read and with many short components it leads to more typing.

But I think this is a small price to pay for getting rid of tanspiling in PoCs or such.

 

Also check out Bel, Yo-Yo, and nanohtml packages on npm. All make use of tagged template literals instead of jsx

 

This looks interesting. I do like the Component end-tags. :)

 

interesting. didnt know about template functions, that's pretty cool!

 

I can suggest another helper library which allows easy to use React without JSX.
github.com/sultan99/react-on-lambda

Classic DEV Post from Sep 24 '18

Who's looking for open source contributors? (September 24 edition)

Find something to work on or promote your project here. Please shamelessly pro...

A Canadian software developer who thinks he’s funny.