lit-html, JavaScript templating from the Polymer team at Google

lit-html

Producing HTML output in JavaScript remains an unsettled area. There are many schools of thought here. Some are still using traditional back end focused templating languages like Handlebars or Twig in JavaScript, while at the other extreme developers want to do templating in pure JS. While Vue.js and Angular have their own syntaxes. W3C Web Components have used the HTML Templates standard.

So there is no shortage of options for doing templating in JavaScript. Currently the top of mind options are "Just JavaScript" templating approaches such as the JSX format from React, and custom templating syntaxes like the one from Vue.js or the one from Angular. In addition there is the native HTML template specification used by Polymer, and the HTML Literals usable in *any* project using ES6+.

The sheer number of options and the lack of a de-facto standard shows that there is room for improvement in the area. The Polymer team team at Google agrees and have developed an interesting alternative called lit-html. Lead by Justin Fagnani, they have worked on a hybrid solution, where ES6+ templates literals are used together with concepts familiar to users of the JSX template format.

At the time of writing the project is in PolymerLabs; the effort put into it is limited, and the project is not yet recommended for production use. The library can be installed from NPM as lit-html.

lit-html has JSX like syntax based on Web Standards

This lit-html project seems to be a response to the criticism from the React community regarding Web Components templating and state management issues. Some React proponents have slated the lagging of adoption of Web Components due to having cumbersome templating syntax and making providing no clear way of State Management from JavaScript. But in this article we will focus on templating.

The lit-html project is somewhat aimed at this critique, and it has four major goals it aims to fulfill:

  1. Efficient updates of previously rendered DOM
  2. Easy access the JavaScript state that needs to be injected into DOM
  3. Standard syntax without required build steps, understandable by standards-compliant tools
  4. Very small size

With these as the guiding rules, lit-html could grow to be a universal templating library usable in many kinds of projects. As an example, here is how you could build a React styled component with lit-html:


static get observedProperties() {
  return ['message', 'name'];
}

title = `About lit-html`;
body = `It's got potential.`;

render() { return html`
  <h1>${this.title}</h1>;
  <p>${this.body}</p>;
`;}
        

As you could see from the code example above, React developers accustomed to JSX can easily pick up lit-html and it's practises. Lit-html is essentially a templating library, you could use it anywhere where JavaScript runs and templating is needed. I see lit-html used similar to how React is used for templating everywhere, supported by the fact that adopting the library in JavaScript projects is straightforward:


const sayHello = (name) => html`<div>Hello ${name}!</div>`;

const container = document.querySelector('#container');
render(sayHello('Steve'), container);
// renders <div>Hello Steve!</div> to container
        
Illustration of rendering paths of VDOM (React), lit-html and HTML Templates (Polymer)

In browser implementations, dynamic DOM updates are often seen to be as inefficient. Lit-html does offer an improvement over raw DOM manipulation that the team claims is an improvement over virtual DOM based libraries like React. In the case of lit-html the team has implemented a template handler, a part of the ECMAScript standard, that returns a TemplateResult instead of raw DOM nodes.

The TemplateResult is an object that contains the template and values that are used to create or update the Document Object Model (DOM) by the native browser implementation. As an example if we continue on the previous example and re-render the template with a different variable:


render(sayHello('Kevin'), container);
// renders to <div>Hello Kevin!</div>
        

In this case lit-html will take control and update the output, but behind the scenes it only updates the ${name} part instead of rendering the complete DOM node - because the element has already been created before in the earlier snippet. The mechanics of this algorithm are roughly described in the technical documentation and in the video embedded below.

Polymer 3.0 and lit-html going forward

At the Polymer Summit 2017, the project announced team announced some significant changes coming in the 3.0 version of the library, most notably moving away from Bower to NPM. This change, together with the use of ECMAScript Modules going forward will bring Web Components closer to React and other JavaScript projects' workflow. For details I recommend watching the session videos from PS 2017.

One of the biggest changes these will bring is that Polymer templating is moving to JavaScript. This means that lit-html will be a valid option for templating in Polymer 3.0 (now available in preview). There was a talk, Efficient, Expressive, and Extensible HTML Templates, that gives insight to lit-html:

Adding a new technical option does not necessary add value, but there reasoining for creating lit-html is solid. The existing standards based solution has received criticism, so instead the project is aligning with common real-world practises. The result is an evolutionary product that builds on proven techniques as well as browser standards to avoid additional polyfills. I look forward to see where this is going.

-- Jani Tarvainen, 23/08/2017