
Alternatives to JSX - bloomca
https://blog.bloomca.me/2019/02/23/alternatives-to-jsx.html
======
hn_throwaway_99
Wow, after reading this, I'd be surprised if anyone could come away with the
conclusion "Yeah, that's better than JSX."

I think the general distaste for JMX is that it "feels" backwards initially:
it mixes in HTML snippets within code, while many people are used to template
files, which are mainly markup with small bits of "presentational" code
injected.

But once you realize and really understand that JSX is just shorthand for
javascript calls (and the article does a good job of explaining this), you
hopefully eventually reach an "Aha!" moment of thinking of JSX in terms of
underlying component creation. That's what happened to me, anyway,.

~~~
genezeta
I've always thought the "HTML in JS" was in fact a strawman argument set up to
deviate the attention from the fact that it is indeed a different syntax for
function calls (and class instantiation). And it is actually that the thing
that I dislike about JSX. I think it's a _bad syntax_ for function calls/class
instantiation.

I do like hyperscript better than JSX... precisely because it's _not_ a syntax
for function calls. Because it's just a function.

~~~
WorldMaker
It's not entirely a strawman, because there are legitimate concerns about
separation of concerns that the "HTML in JS" argument worries about.
Especially in the web world which still knows the legacy against fights of
business logic in templates going back to "bad old PHP days", etc.

There are good reasons to be skeptical about JSX simply because of the worry
about how much business logic may accidentally be embedded directly into
views. For JSX, the answer is typically to solve that in other areas of
workflow and patterns of habit. But the war between "as dumb as possible a
templating language" and "just let me use my real language for templates" will
probably wage on in the web space forever.

~~~
tracker1
Maybe it's best not to think of React as a View but a Component... You can
create Components that are simple Views and render what they are given, you
can also create smarter Components that are more in line with Controllers.

As a loop: Store -> State -> Reducer -> Component -> Action -> Dispatch ->
Store ...

Or if you want something closer to MVC, you could use MobX or similar.

~~~
WorldMaker
I've been sold on JSX for a while, personally, and pretty much have that
architecture in my apps I'm working on.

I just also remember being an idealistic Django-loving youth that wanted the
dumbest possible template engine to avoid teenage PHP drama, so I definitely
sympathize with folks whose gut reaction is upset with JSX for crossing the
streams (again), and thought to make sure it was clear that it isn't a straw
man argument to many. (Even if it is also, as in my case, an argument that can
be won in favor of JSX. Though also in my case one of the big factors winning
that argument was TSX [Typescript type checking of JSX views] versus many of
the alternatives and their [lack of] static checking/analysis.)

------
bennypowers
Why JSXBelPack when you can

    
    
      import { html, render } from 'https://unpkg.com/lit-html';
    
      const benefitTpl = ({name, desc}) => html`
        <dt>${name}</dt>
        <dd>${desc}</dd>
      `;
      
      render(html`
        <lit-rocks>
          <dl>${benefits.map(benefitTpl)}</dl>
        </lit-rocks>`, document.body)
    
    

And updates are fast without any VDOM overhead.

~~~
tracker1
Is this doing a full re-render on each change? Having not seen the state
management piece... but could be nice for progressive enhancement modules in a
server-rendered app. I've done similar in JS.

~~~
zemptime
Nope! It doesn't visit each node like vdom. VDOM visits every virtual node.
lit-html looks at only the expressions. That's where a lot of the
speed/performance comes from

------
dazhbog
I used to be really sceptical about JSX, 1 extra transp. step, anorthodox use
of xml in JS, etc.

Having been using it for the past 3-4 years I think its an above agerage
elegant solution when it comes to templating solutions.

------
cdaringe
Pug is a worthy mention. [https://github.com/pugjs/babel-plugin-transform-
react-pug/bl...](https://github.com/pugjs/babel-plugin-transform-react-
pug/blob/master/README.md) wasn't mentioned

------
cygned
What really bugs me about JSX is the complexity it introduces to the build
pipeline - which might be fine for senior developers, but I regularly see
junior developers struggle with configuration and errors.

~~~
nicoburns
You get a ton of other benefits from buying into a webpack-style build system
though:

\- Modules \- TypeScript \- Newer JavaScript syntax \- SASS compilation \-
Code splitting

etc.

For me, it's hard to imagine a medium/large sized JS project without using
some kind of module system. And once you've setup the build system for that,
you might as well use all of the other features that it enables.

~~~
vorpalhex
You can get modules now in many browsers, as well as the latest JS syntax,
without needing any build step.

Code splitting/vendoring has changed with HTTP2, and will continue to change
as HTTP3 comes along.

SASS compilation, and if you choose to use TypeScript, will require a build
step, but at least the SASS side of that is very easy and straight forward by
itself.

~~~
tracker1
You're still missing a few of the finer points of stage 0-3 optiosn for babel.
Also, that bloats out to a lot of requests with full round-trip time, and no
real good server solutions for bundling via HTTP2/3 push yet.

------
nojvek
We use virtual jade at work. It works with most virtual doms that use some
form of h(name, attrs, children) calls.

We have webpack hot reloading so we can work on UI without any page refreshes.

It’s been very productive. I love the brevity of jade/pug. Jsx feels like a
lot of boilerplate braces and ending tags.

[https://github.com/tdumitrescu/virtual-
jade](https://github.com/tdumitrescu/virtual-jade)

~~~
pjungwir
I've been using pug with the babel plugin for a React project, and I really
like it. I'm a fan of Haml for server-side rendered Rails views, too. I'm
surprised pug isn't more widely used in front-end dev, since it is so popular
in Node apps.

Also: projects are still using the "jade" name? I thought they were forced to
change?

~~~
lf-non
pug is really nice (as is haml).

The only reason I bear with the superfluous verbosity of JSX is because it
plays well with typescript. The moment you switch to text based templates
typesafety goes out of the window.

I really wish javascript/typescript had a good builder syntax like Ruby.
Hyperstack [1] (previously Hyperloop) is a great project that uses ruby blocks
for component composition. I wish this was possible in javascript.

[1] [https://hyperstack.org/](https://hyperstack.org/)

------
macco
I would advice against using JSX alternatives. I come from a Clojure
background and I like the ijk solution to just use an array to represent the
virtual dom.

But still I would recommend using JSX because it the "standard". Every
documentation and problem solution you find on the internet is written with
JSX. Using a JSX alternative will make debugging much harder for you.

------
pier25
The fact that front end has to deal with 3 different languages (JS + HTML +
CSS) is a problem nobody has completely solved.

These days the solution usually falls into 3 camps:

1) Write everything in JS like React.createElement or Mithril. No build setup
but a pain to use.

2) JSX. Requires a build setup which might become complex as the project
grows.

3) Templates. Probably the less elegant of all 3 but the most pragmatic and
easy to use.

Someone attempted to solve this and created a new language called Imba. It's
like a mutant Ruby with HTML that compiles to JS.

[http://imba.io/](http://imba.io/)

It has a lot of productivity benefits compared to previous attempts at solving
the same problem, but goddammit it's ugly.

~~~
sephoric
The project "create-react-app" is a good mixture of #2 and #3 that I have been
using for almost a year with almost no issues, it's just a generally great way
to use React. The only issue I had is that, even though all your configuration
is "for free", you don't really get new features right when they come out. But
you get them after their configuration has been polished up, so that you don't
have to shave all the yaks yourself.

~~~
pier25
Personally I'd rather have my own configuration than use a CLI like create-
react-app or Vue CLI.

It's easy enough to create a template/starter kit the way you want it and
tweak it to your taste. Also when (not if) you get a problem you know what's
going on instead of a black box.

------
SkyPuncher
HTM actually looks pretty intriguing to me.

One thing I like about JSX is that it looks and feels like HTML.

For me, that has two huge benefits:

1\. It narrows the dissonance between the code I'm writing and the actual
structure that will be rendering into the DOM. I find it much easier to write
and debug when I don't have translate between some JS factory function and the
actual DOM implementation.

2\. It's almost pure HTML. Sure I'll have to change class to className and
update some other tags. Generally, though, if something works in HTML, it's
little fuss to do in JSX. With tools like JSX, I can write in a single
templating language across all of my software.

~~~
wtfrmyinitials
One thing the author missed about htm is that you don’t necessarily need to
parse it at runtime— there’s a Babel plug-in to compile it to plain js
function calls. This way you can develop without a transpiler and add one
later when (if) the extra performance becomes necessary.

------
keymone
i'm surprised hiccup was never mentioned. ofc it's not for pure JS but there's
this thing -
[https://github.com/lantiga/react.hiccup](https://github.com/lantiga/react.hiccup)
though i never tried and don't know how well it works. still interesting.

~~~
simongray
Hiccup is awesome for ClojureScript since we get to use plain Clojure data
structures rather than a DSL that must be parsed in a separate step, but I
think this advantage disappears when using it outside the context of
Clojure/ClojureScript.

------
oorza
There's also kotlin-react which let's you write React in Kotlin in a Kotlin
DSL which looks exactly like your first imagination probably suggests:
[https://github.com/JetBrains/kotlin-
wrappers/tree/master/kot...](https://github.com/JetBrains/kotlin-
wrappers/tree/master/kotlin-react)

It's also a pretty impressive demonstration of the typesafe flexibility of
Kotlin's DSL support, but that's another conversation.

------
ertucetin
ClojureScript + Reagent

~~~
kgwxd
This combo is insanely beautiful. Not only does it solve the JSX issue, it
does it without any new syntax and adds persistent, immutable data structures,
something React is just begging for. My only problem is that I'd have to
switch jobs for any chance of using it at work.

------
droobles
A point to the discussion of whether JSX is preferable or not to a programmer,
most React projects with JSX I've worked on has had the awesome bonus of a
designer who knows markup/css to be able to add layouts to our web and React
Native projects. Just wanted to throw that out there as a plus to JSX. I don't
think the designer could follow hyperscript very well.

------
fnordsensei
There's also HDOM, part of the larger Umbrella collection of libraries:
[https://github.com/thi-
ng/umbrella/tree/master/packages/hdom](https://github.com/thi-
ng/umbrella/tree/master/packages/hdom)

Purported benefits from the readme:

\- Use the full expressiveness of ES6 / TypeScript to define user interfaces

\- No enforced opinion about state handling, very flexible

\- Clean, functional component composition & reuse, optionally w/ lazy
evaluation

\- No source pre-processing, transpiling or string interpolation

\- Less verbose than HTML / JSX, resulting in smaller file sizes

\- Supports arbitrary elements (incl. SVG), attributes and events in uniform,
S-expression based syntax

\- Supports branch-local custom update behaviors & arbitrary (e.g. non-DOM)
target data structures to which tree diffs are applied to

\- Component life cycle methods & behavior control attributes

\- Suitable for server-side rendering and then "hydrating" listeners and
components with life cycle methods on the client side

\- Can use JSON for static components (or component templates)

\- Optional dynamic user context injection (an arbitrary object/value passed
to all component functions embedded in the tree)

\- Default implementation supports CSS conversion from JS objects for style
attribs (also see: @thi.ng/hiccup-css)

\- Auto-expansion of embedded values / types which implement the IToHiccup or
IDeref interfaces (e.g. atoms, cursors, derived views, streams etc.)

\- Fast (see benchmark examples)

\- Only ~6.2KB gzipped

------
mmmeff
Awesome article. I appreciate the lack of bias. Thanks for writing this, OP.
It's good to keep an eye on the horizon for potential alternatives to tech we
use day in day out, but it looks like we're still on solid ground with JSX so
no need to switch :)

------
fromalex
There is also a babel-transform for pug[1]. It works quite well as JSX
replacement. Not having any endig tags can be quite beneficial when
reformatting stuff.

Paired with Tachyons (best atomic CSS lib) you get superpowers and can write
code like

    
    
      const someComponent = ()
        => pug`
          ul.p2.f3 Some list
            li.red Some text
            li.pink Some more`
    

[1] [https://github.com/pugjs/babel-plugin-transform-react-
pug](https://github.com/pugjs/babel-plugin-transform-react-pug)

------
jayar95
I think a lot of readablity issues with jsx are caused by the amount of logic
react devs will put in their markup. It's painfully reminiscent of old-school
PHP templating

------
batiste
My problem with JSX is that if you introduce a DSL, why would you limit it to
basic function calls/expressions?

I created a small language to demonstrate what I mean
[https://github.com/batiste/blop-language](https://github.com/batiste/blop-
language)

~~~
com2kid
Easier to reason about.

JSX is a simple wrapper around a JS call, it is trivial to mentally convert
from JSX to what the real JS is.

JSX is also super copy-pastable. Less logic and all that.

If you want complex logic around what JSX to render, it get factored out into
a function call (or its own component), which returns the appropriate JSX
after evaluating any required logic. This means you are back to plain JS with
all the existing tooling and language features around it.

JSX being simple also makes the learning curve simple.

~~~
batiste
> JSX is a simple wrapper around a JS call, it is trivial to mentally convert
> from JSX to what the real JS is.

Then maybe it is an indication is not worth very much. Why not using something
like hyperscript instead if it is just some javascript.

> JSX is also super copy-pastable. Less logic and all that.

In my experience the copy-paste-reuse in FE is a red herring. And React is no
exception. And a logic less templating is not necessarily helping with a
flexible/reusable piece of code.

> JSX being simple also makes the learning curve simple.

Not so sure about that. I think I would have personally preferred not having
to learn a new DSL if some basic function call in Javascript can do the same
job.

I guess I have been scared by colleagues using ugly ternary operator
expressions with React.

I also used so many template languages in the past: PHP, Django, Pug, Rails,
etc, etc. That I try to reproduce similar features/mistakes.

------
oldboyFX
I was a bit apprehensive about JSX before quickly getting used to it. Now I
love it.

The only decision I dislike is renaming class to className. Why not klass,
cls, cs... anything shorter.

ClassName is simple to understand but adds a lot of clutter to component
files.

~~~
acemarke
Because it matches the field name for DOM nodes:

[https://developer.mozilla.org/en-
US/docs/Web/API/Element/cla...](https://developer.mozilla.org/en-
US/docs/Web/API/Element/className)

------
itsbits
lit-html surely does a good job..

\- ES6 string literals

\- partial template rendering

are few cool features with it.

~~~
lauritzsh
I haven't looked much into lit-html but is it possible to type check your
templates like you can do with JSX? That is one big advantage I found for JSX
compared to template-based frameworks.

~~~
Technetium_Hat
All components, expressions, etc are in template curlies `${}` so type
checking works out of the box. If you mean type checking on HTML properties,
no it does not.

Lit HTML seems very extensible, so it should be possible to add support for
thus.

------
hardwaresofton
If you read this article and thought Hyperscript might be something you wanted
to try, please check out Mithril[0].

It's an excellent project, pretty decently fast (checkout the js-framework-
benchmark[1] code, or more specifically the results of round 8[2]) -- but is
currently suffering from a lack of recognition. It's the kind of project that
absolutely doesn't care about that kind of metric (as in, the team seems to be
more focused on slow, steady improvement of the library rather than chasing
stars on github), but I figured I should say something.

Shameless plug: I recently really wanted to contribute something (and kick the
tires more) so I wrote an article that goes through replicating a simple mail
design I saw[3] -- it might be a decent overview of what mithril is like to
write (though I'm certainly not a mithril expert).

This brings me back to the point at hand -- as others have noted, in my
opinion one of the best things about hyperscript is the straight-forwardness
with which you construct the render function. I'm not convinced it's necessary
to segregate stateless/stateful components -- and mithril is simpler in that
it doesn't introduce this dichotomy -- in the end there's the render function,
and that's it. If you want to use state, go ahead -- if you don't, then don't.
It's the simplicity I've wanted from component frameworks (and mostly get with
Vue) without any of the posturing/looming complexity.

Also there's the fact that you could write a completely vanilla es5
application with hyperscript (arguments whether you should or not aside) --
JSX is/was revolutionary, but is basically required in practice, which often
makes people jump into bed with webpack without thinking, and makes frontend
development harder than it has to be.

[EDIT] - Another point for mithril is that it's _self contained_ \-- routing
and ajax calls some with the framework. When people these days talk about
"react" or "vue" what they're really talking about is react/vue + react-
router/vue-router + flux/vuex and some other odds and ends. Mithril is by far
the simplest and most feature-complete of these frameworks despite being
smaller (both conceptually and on-the-wire).

One of my only current gripes with Mithril is the lack of controllable subtree
rendering (it isn't as much of a problem in practice, but more me wanting to
optimize early).

[0]: [https://mithril.js.org](https://mithril.js.org)

[1]: [https://github.com/krausest/js-framework-
benchmark](https://github.com/krausest/js-framework-benchmark)

[2]:
[https://www.stefankrause.net/wp/?p=504](https://www.stefankrause.net/wp/?p=504)

[3]: [https://vadosware.io/post/mithril-systemjs-and-rollup-
gettin...](https://vadosware.io/post/mithril-systemjs-and-rollup-getting-
started-guide/)

~~~
panoply
I enjoyed your article very much. I'm a huge fan and proponent of this
framework. Since I come across Mithril I have used it exclusively on all
internal projects at our agency and haven't looked back.

Adopting Mithril also opened me up to a whole list of lesser known but
vigorously thought through projects like BSS, Patchinko and the beautiful
Meiosis pattern which changed the way I went about developing resulting in far
better productivity.

~~~
hardwaresofton
Thank you very much! I really wanted to see more writing on the internet
around Mithril -- it seems it's like lisp in the way that most people who are
using it productively are just doing heads down working on stuff.

> Since I come across Mithril I have used it exclusively on all internal
> projects at our agency and haven't looked back.

I'd love to see some writing on some of the patterns you've developed with it!
Also, it might be cool for mithril to have a "trusted by" section on their
main page to showcase some companies that use mithril to increase trust for
people who wander in (though I'm also OK with mithril not having this section
-- it's a bit overly-prodcuty and distracting).

> Adopting Mithril also opened me up to a whole list of lesser known but
> vigorously thought through projects like BSS, Patchinko and the beautiful
> Meiosis pattern which changed the way I went about developing resulting in
> far better productivity.

> Adopting Mithril also opened me up to a whole list of lesser known but
> vigorously thought through projects like BSS, Patchinko and the beautiful
> Meiosis pattern which changed the way I went about developing resulting in
> far better productivity.

Thanks a ton for the references, looking up all those things right now, looks
like more pieces of the Mithril ecosystem that I've never heard of. Patchinko
looks super useful (I'm surprised I've never needed something like this in the
past...), and Meiosis looks like a simpler version of the reactive/flux
pattern, and looks interesting to me since it's cross-framework!

~~~
panoply
So most of these projects are all maintained by members of the Mithril team or
heavy contributors of Mithril, so you can trust they are created with care and
have been thoroughly thought through.

You should definitely join the Gitter chat for Mithril. It's a very active
channel and a little lesser known part of the internet where you will get a
constant flow of engaged developers of all levels discussing Mithril and also
where some of the core team discuss concepts, roadmaps, ideas and drop
knowledge.

------
austincheney
I am getting a 404.

~~~
masklinn
Works for me.

