Running JSX in your browser without Babel
Tags: react, jsx, babel, javascript
Published: 2019-09-03 09:03:58

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 [reactjs.org](https://en.reactjs.org/docs/add-react-to-a-website.html)

```html
<script src="https://unpkg.com/react@16/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js" crossorigin></script>
```

And for JSX, we just have to add babel too

```html
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
```

Voilà! 🤗

## But!

> 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](https://github.com/developit/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** |


```html
<script src="https://unpkg.com/htm@2.2.1" crossorigin></script>
<script type="module">
// Bind htm with createElement
const html = htm.bind(createElement);
</script>
```

### 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
// JSX syntax
function Header({title}) { return <h1>${title}</h1>} 

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

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

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


### Demo

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

{% jsfiddle https://jsfiddle.net/Devalnor/aeLupb4t/24 html,result %}

### Bonus (Preact with Hooks)

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

```html
<script src="https://unpkg.com/preact@10.0.0-rc.1/dist/preact.umd.js" crossorigin></script>
<script src="https://unpkg.com/preact@10.0.0-rc.1/hooks/dist/hooks.umd.js" crossorigin></script>

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

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