DEV Community

Posted on • Updated on

Running JSX in your browser without Babel

Just for fun, I wondering if I could run React + JSX code directly in a modern browser without transpilation and packaging.

The answer is not rocket science and explained on

<script src="" crossorigin></script>
<script src="" crossorigin></script>

And for JSX, we just have to add babel too

<script src=""></script>

Voilà! 🤗


This approach is fine for learning and creating simple demos. However, it makes your website slow and isn’t suitable for production.

That's right, your code is not optimized and loading Babel can be too heavy.

Remember, it's for just for fun. There is another (and probably better) way with HTM (Hyperscript Tagged Markup) a JSX alternative using standard tagged templates made by @_developit , creator of Preact.

The download weight difference is huge if we don't really need Babel.

Lib Version Loading Size
Babel 6.26 <195KB
HTM 2.2.1 >1KB
<script src="" crossorigin></script>
<script type="module">
// Bind htm with createElement
const html = htm.bind(createElement);

It's 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 end-tags: <${Footer}>footer content<//>
  • Syntax highlighting and language support via the [lit-html VSCode extension] and [vim-jsx-pretty plugin].
  • Multiple root element (fragments): <div /><div />
  • Support for HTML-style comments: <div><!-- comment --></div>

Syntax differences

There is few syntax differences by using tag function html

// JSX syntax
function Header({title}) { return <h1>${title}</h1>} 

function App() {    
  const name="World"
  return (
      <Header title="Hello, ${name}!"/>

// HTM syntax
function Header({title}) { return html`<h1>${title}</h1>`} 

function App() { 
  const name="World"
  return html`
      <${Header} title="Hello, ${name}!"/>


Knowing these differences, you are ready to have fun with React (or Preact of course) in your browser without any transpiler.

Bonus (Preact with Hooks)

If you want to use Hooks with Preact 10 (Currently in Release Candidate).

<script src="" crossorigin></script>
<script src="" crossorigin></script>

<script type="module">
const { useState } = preactHooks;
// ...

First post on, if you enjoy it and want more don't forget to like ❤️

Top comments (4)

fordi profile image
Bryan Elliott

This post inspired me to create this:

devalnor profile image


riceball1 profile image
Dana Ng

Nice this helped with something I wanted to use w/o using create-react-app for some small play around things

yusuf profile image

is htm still being maintained?