JSX, HTML-in-JS and CSS-in-JS

Lately, I’ve been hearing a lot of people talk about JSX as if it is HTML-in-JS. So let me clear something up:

JSX is not HTML-in-JS.

The thing about JSX is that it is just a special syntax for writing plain-old JavaScript.

Each JSX element compiles to a call to a JavaScript function called React.createElement. In fact, you can write apps without using JSX at all; just call React.createElement by itself. Like this:

ReactDOM.render(
  React.createElement('div', {}, "Hello, world!"),
  document.getElementById('app')
)

To repeat myself, JSX is not HTML-in-JS. Yes, it is a way to specify the structure of the DOM. But so is raw JavaScript, like this:

const app = document.getElementById('app')
const hello = document.createElement('div')
hello.appendChild(document.createTextNode('Hello, world!'))
app.appendChild(hello)

If you’re writing an app with JavaScript, you need some way to modify the DOM. JSX is one way of doing it. Raw JavaScript is another. But in either case, you’re still working with JavaScript.

In contrast, HTML-in-JS would look a little like this:

const hello = "<div>Hello, world!</div>"
document.getElementById('app').innerHTML = hello

And sure, this is something you can do. Just like you could chug a bottle of Tabasco. A friend did that once. He was weird. But I digress.

Want to learn more about fundamentals like React.createElement? My Learn React By Itself series was made just for you!

CSS-in-JS

Another thing a lot of people are talking about lately is CSS-in-JS.

Unfortunately, CSS-in-JS is actually exactly what it sounds like. It is literally CSS in a JavaScript file. Let me repeat that. It is actually CSS in a JavaScript file.

The thing is, there are a number of very good reasons we generally put CSS in CSS files (or their LESS/SCSS cousins). For example:

  • Browsers expect to load CSS from CSS files.
  • Editors have syntax highlighting based on file extension.
  • Tooling such as minifiers and linters expect CSS.
  • Existing CSS libraries are written in CSS, LESS or SCSS.
  • CSS files can be cached separately from JS files.

Some CSS-in-JS tools do lots of very clever things to provide workarounds for all of these issues. But if you just use CSS or LESS or SCSS, you don’t need to provide workarounds. It just works.

Of course, there are supposedly a number of benefits. But most of these benefits can be had from more mature tooling like LESS, SCSS, CSS Modules and Webpack (which you’ll need anyway to, you know, put your CSS back into CSS files).

There are some benefits that are unique to CSS-in-JS:

  • You can add things like media queries directly to components, whilst you can’t with standard inline styles. (Yay?)
  • You can share JavaScript variables with stylesheets. Except that this is is massive security hazard.

But all the big names are using it, so it has to be good, right?

So here’s the thing: CSS isn’t perfect. It makes sense that smart people are building alternatives. And the tools do have some compelling use cases — they’ll work with react-native, for instance. But unless you 100% know what you’re getting into, and 100% understand the security implications, I’d wait a little bit longer before jumping on any bandwagons.

I’ve put a few more details on React Armory in my answer to Should I use CSS-in-JS?.

More good news

Keeping up with JavaScript and React can be exhausting — but it doesn’t have to be! The secret is that the basics never change. In fact, my most popular articles are ones I wrote years ago, and they’re still as relevant as ever.

JavaScript fatigue happens, but you can avoid it by sticking to the basics. And that’s why my fortnightly newsletter just focuses on the JavaScript and React fundamentals. So subscribe now — and get a bunch of free PDF cheatsheets as a bonus.

I will send you useful articles, cheatsheets and code.

I won't send you useless inbox filler. No spam, ever.
Unsubscribe at any time.

One more thing – I love hearing your questions, offers and opinions. If you have something to say, leave a comment or send me an e-mail at james@jamesknelson.com. I’m looking forward to hearing from you!

Read more at React Armory