
Hyperscript Tagged Markup: JSX alternative using standard tagged templates - truth_seeker
https://github.com/developit/htm
======
stevebmark
The nice thing about React, vs others like Vue and Angular, is that we've
learned not to write code in strings. You'd think this would be a fundamental
law of software engineering, but we keep seeing things like

    
    
        v-bind:id="'list-' + id"
    

or

    
    
        <button [style.color]="isSpecial ? 'red' : 'green'">
    

or this.

Writing code, not strings, means you can do everything to it that you can do
to code. You can type check code. You can lint it. You can optimize it,
compile it, validate it, syntax highlight it, format it with tools like
Prettier, tree shake it...

That's why I like JSX, it's Javascript all the way down. Everything is code.
It's a very well designed and thought out DSL.

~~~
magicalist
> _Writing code, not strings, means you can do everything to it that you can
> do to code._

These are tagged templates, not strings. They work as code at runtime, and it
already has support to optimize it, compile it, etc. _This_ is JS all the way
down. And spankalee mentioned below they're adding typescript support to type
check the very similar lit-html, so that's coming too.

> _That 's why I like JSX, it's Javascript all the way down. Everything is
> code. It's a very well designed and thought out DSL._

It's also kind of a weird to highlight all this for a DSL that actually has to
be parsed from a string to get it to be Javascript. Everything else you're
talking about is tooling that had to be built special for it, not the language
itself.

Why not just say "I like the style of jsx embedding and existing tools better"
:)

~~~
domenicd
+1. It's all strings (of source code) in the end. It's just a matter of how
well the tools support those strings.

There exists a medium-sized ecosystem of tools which supports static checks on
strings inside angle brackets, a la JSX. There is a smaller-but-growing
ecosystem of tools that supports static checks on strings inside backticks, a
la HTM/lit-html/etc. There's no fundamental difference here.

~~~
dmitriid
The fundamental difference is what you have in the end. With JSX you have
function calls (JSX is a very thin DSL after all).

With tagged literals you end up with runtime string parsing and concatenation.

~~~
magicalist
> _The fundamental difference is what you have in the end. With JSX you have
> function calls_

Check out the output of the Babel plugin mentioned in the readme

> _/ / input:_

> _html` <div id="foo">hello ${you}</div>`_

> _/ / output:_

> _React.createElement( "div", { id: "foo" }, "hello ", you) options_

[https://www.npmjs.com/package/babel-plugin-
htm](https://www.npmjs.com/package/babel-plugin-htm)

~~~
dmitriid
It's (marginally) better than having it at runtime. Poor man's macros. Much
like JSX in a sense, though JSX is a much thinner abstraction IMO.

------
mattbierner
I’ve written tooling to support lit-html and styled-components in editors.
Template strings are sort of nice to write but complete pain to support in
editors. They are just like a macro language, so you end up with stuff like:
`<${tag}>...<${tag}${slash}>` which is not possible in jsx. Even just
detecting syntax errors is a pain

Obviously if deciding between making life easy for editor implementers or
making life easier for coders, the coders win, but if something is
unnecessarily difficult to build good tooling for, that’s a sign of poor
design in my book. And coders will ultimately suffer too because their tooling
will suck and because their code will make use of all the crazy flexibility
the library allows.

~~~
spankalee
Thanks for all your work on the lit-html plugin!

I think though that the concern here is a little misplaced given the
constraints that HTM and lit-html work under - which is that the template
strings themselves, without the values, have to be well-formed because they're
passed to the HTML parser without values.

In HTM, `<${tag}>...<${tag}${slash}>` is not possible to interpret as a
possibly self-closing tag because self-closing tags are expanded before values
are written into VDOM.

In lit-html `<${tag}>` is not allowed at all. So we know what the tag name
will be, and what attributes and properties are bound. The same amount of
type-checking is possible as with JSX.

------
mbostock
This is lovely for using React or Preact in Observable!

[https://beta.observablehq.com/@mbostock/hello-
htm](https://beta.observablehq.com/@mbostock/hello-htm)

We have our own lit-html-inspired html tagged template literals that render
directly to DOM, but it’s nice to see HTM’s improved support for function
attributes (e.g., onclick), spread attributes, etc.

~~~
spankalee
I love that work!

Eventually we'll get some great parts of this approach standardized, starting
with Template Instantiation, and we'll finally have a great way to create and
update lots of DOM from data right in the platform.

A future d3 based on that would be very awesome too :)

------
mhd
I remember when everyone suggested their own way of s-expressions (basically)
to avoid having to write superfluous end-tags and other XML/HTML tchotchkes,
now we're getting multiple ways to get all the markup boilerplate into our
programming language.

Sometimes it's weird how tastes change. Same thing happened with the nigh
universal hacker-ish dislike of "bondage and discipline" languages, now it's
enforced formatting wherever you look.

~~~
BigJono
There's so much money in web apps now that your average team is flooded with
mediocre devs. These joints need "bondage and discipline" languages and
frameworks to be productive. It's better business value to have your 50 work-
a-day devs productive than your 2 rockstars.

------
leowoo91
Can we go back to Jinja now?

~~~
mrweasel
Maybe it's just me being an old man at this point but I still dislike doing
templating in JavaScript. It's not natural. I want Jinja2 and server side
rendering. If you absolutely must do JavaScript you should keep it separate of
your HTML and other stuff... again maybe I'm just getting old.

Honestly I don't find neither JSX, or this new alternative particularly
readable.

~~~
allover
You can use Jinja-style templates client-side too if you want (see nunchucks).

But client-side rendering and server-side rendering have different use-cases.
It doesn't come down to just which is 'particularly readable'.

> If you absolutely must do JavaScript you should keep it separate of your
> HTML and other stuff

Why? This argument has been lost. _If_ you're writing a rich client-side UI
that makes sense to be "component-oriented", there is literally zero value in
splitting each component into HTML and JS, it is a completely arbitrary
'separation by technology'.

------
lucideer
> _Improvements over JSX_

With the exception of html comments, these are invariably antifeatures.
Optional quotes/closing tags save zero to negligible typing time in exchange
for added complexity for tooling and reduced readibility in many
circumstances.

I can understand why these features were added to HTML5 (backward
compatibility is of more benefit than prescriptivism) but I would never have
thought anyone would argue that having these features in HTML1 was a good idea
in retrospect!?

Adding them to a new syntax that isn't burdened with backward compat
requirements seems daft.

------
sddfd
How is this different from lit-html?

[https://github.com/Polymer/lit-html](https://github.com/Polymer/lit-html)

~~~
domenicd
HTM is React-compatible, and has all the React semantics: e.g. you can
interpolate attributes (with ...${foo} instead of React's ...foo) and tag
names (with <${foo}> instead of React's capitalization-dependent <Foo>).

In other words, HTM is a drop-in replacement for JSX that avoids the need for
a compiler by using the corresponding language features. (At the cost of a few
extra ${}s.)

lit-html and its ilk render directly to the DOM. They give similar developer
ergonomics to React/JSX, but don't integrate with that ecosystem. They aren't
a drop-in replacement for a JSX compiler within your React app; they're more
of a competitor to the entire React paradigm.

Also of note is that, as a drop-in replacement, HTM is properties-first, like
React/JSX. lit-html has you use different syntax for properties and for
attributes.

Both are cool!

~~~
johnhenry
I wouldn't describe it as a "drop-in replacement". It's very similar in the
way that it allows one to use html syntax within javascript, and I appreciate
the fact that it doesn't require and extra compilation step. But it does
appear to be lacking what I see as the main draw of %eact -- the ability to
compose and remix components. (Correct me if I'm wrong?)

Edit: Composability does appear to be a feature. I agree with your
description.

------
dixie_land
TIL [https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Refe...](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates)

I'm not a JavaScript developer so this is news to me, very neat feature!

~~~
simlevesque
Here's a list of tagged template literals:

[https://github.com/declandewet/common-
tags](https://github.com/declandewet/common-tags)

~~~
reificator
Which brings up a question: Is it possible to have multiple tags on a given
string? Composing smaller helpers would be nice, but I don't see how the
syntax would work.

~~~
simlevesque
You'd just need to create a meta tagged litteral function. tagged litteral can
accept parameters.

------
qwerty456127
IMHO the name choice (htm) is really bad.

~~~
ricardobeat
We've arrived at the point where the majority of developers have never seen a
.htm file!

------
bcherny
This is a neat syntax, but it doesn’t seem at all typesafe (typesafety was the
main benefit of JSX over the various string templates that came before it).

~~~
ricardobeat
> typesafety was the main benefit of JSX

Do you have a source for that?

~~~
bcherny
My opinion, not a fact.

Before JSX came out, there were tons of templating systems that let you embed
HTMLish things in JS: Handlebars, Mustache, EJS, Pug, Angular templates.

JSX’s big innovation was taking the way XHP promoted HTML to first class
syntax and applying it to JS. The big difference between that and the template
systems that came before it is JSX is statically analyzable (by your type
checker, or by other tools), which means you can scale it to FB scale.

~~~
ricardobeat
What I was thinking is that you're backdating your impressions. JSX came out
in 2013, when TypeScript was at it's infancy, and also predates flow; support
for JSX in the TS compiler was only added in late 2015.

You're right that when it came out it's main innovation was separation of
concerns and composability, but types or static analysis were not part of the
value proposition at the time.

~~~
bcherny
You know, I think that’s a really fair way to look at it. I would be
surprised, though, if down the line type safety wasn’t a design goal. It did
come from the same company that built XHP around 2010, and the same dude that
built the first React prototypes in OCaml. I can ask around after the holidays
and see if anyone remembers :)

------
drivingmenuts
So,I guess mixing presentation and logic is OK now? 'Cos as a PHP programmer I
used to get shat on all the time for that and I'd like a chance to, you know,
unload on someone else for a change.

NM, I'll just go back to my cave now.

~~~
stevebmark
Good thing "logic" isn't a concern and separating view code from view code
doesn't make sense ;)

