Skip to content

JavaScriptExpert/htm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hyperscript tagged markup demo

HTM (Hyperscript Tagged Markup) npm

htm is an implementation of JSX-like syntax in plain JavaScript, using Tagged Templates. It lets your build apps using Preact/React/etc directly in the browser. JSX can be converted to htm with only a few tiny modifications. Templates are parsed by the browser's HTML parser and cached, achieving minimal overhead.

htm is just 650 bytes standalone, or only 500 bytes when used with Preact! (through the magic of gzip 🌈)

Syntax: Like JSX but more lit

The syntax is inspired by lit-html, but includes features familiar to anyone who works with JSX:

  • Rest spread: <div ...${props}>
  • Self-closing tags: `
  • Components: <${Foo}> (where Foo is a component reference)
  • Boolean attributes: <div draggable />

Syntax: better than 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:

  • HTML's optional quotes: <div class=foo>
  • HTML's self-closing tags: <img src=${url}>
  • Optional end-tags: <section><h1>this is the whole template!
  • Component end-tags: <${Footer}>footer content<//>
  • Support for HTML comments: <div><!-- don't delete this! --></div>

Project Status

The original goal for htm was to create a wrapper around Preact that felt natural for use untranspiled in the browser. I wanted to use Virtual DOM, but I wanted to eschew build tooling and use ES Modules directly.

This meant giving up JSX, and the closest alternative was Tagged Templates. So, I wrote this library to patch up the differences between the two as much as possible. As it turns out, the technique is framework-agnostic, so it should work great with most Virtual DOM libraries.

Installation

htm is published to npm, and accessible via the unpkg.com CDN:

For npm:

npm i htm

To hotlink:

import { html, render } from 'https://unpkg.com/htm?module'

Example

Curious to see what it all looks like? Here's a working app! It's just an HTML file, there is no build or tooling. You can edit it with nano.

<!DOCTYPE html>
<html lang="en">
  <title>htm Demo</title>
  <script type="module">
    import { html, Component, render } from 'https://unpkg.com/htm/preact?module';

    class App extends Component {
      addTodo() {
        const { todos } = this.state;
        this.setState({ todos: todos.concat(`Item ${todos.length}`) });
      }
      render({ page }, { todos = [] }) {
        return html`
          <div class="app">
            <${Header} name="MyApp: ${page}" />
            <ul>
              ${todos.map(todo => html`
                <li>{todo}</li>
              `)}
            </ul>
            <button onClick=${this.addTodo.bind(this)}>Add Todo</button>
            <${Footer}>footer content here<//>
          </div>
        `;
      }
    }

    render(html`<${App} page="To-Do's" />`, document.body);
  </script>
</html>

How nifty is that?

About

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • JavaScript 100.0%