DEV Community

Cover image for React is great...but you should try Lit.
Robert Tate for Developers @ Asurion

Posted on

React is great...but you should try Lit.

Does anyone else out there need a quick break from React? For just a few minutes maybe?

I've been using React for years now, and I miss the days where it felt new and exciting. In my brain, React has gone from a sports car to a minivan. It's still very good at what it does, but I'm a little bored of it. I don't get very excited using it anymore. We've lost our spark, you might say.

So, I thought I would try something new and get Lit for a little while.

You heard me.

So what is Lit? Per the "about" section on their github page: Lit is a simple library for building fast, lightweight web components.

Their slogan is:

Simple. Fast. Web Components.

If you don't know what a web component is, take a step backwards here and read about web components on MDN.

Put simply, web components are a set of native browser APIs that let you create your own HTML elements. Those elements can do whatever you want them to. Lit is a library that wraps around web components, making them easier to work with. Instead of setting up web components using the native APIs directly, you can use Lit to make Lit Components.

Your next question might be:

  • That's not what React does at all...so is Lit really comparable?

  • Can I use Lit to build web apps, websites, and user interfaces, just like I can with React? Is that even what Lit is meant for?

Yes, Lit is comparable to React in many ways. Yes, you can use it to build websites, web apps, and UI's. And yes, it's intended to be used for those things.

It even does some things React can't do (gasp).

Let's start looking at the differences between a React component and a Lit component. I made a silly little component that takes in a string from user input, and spits it out reversed. Imports not included. And just assume reverseString does what it says it does, in both cases.

The React Component:

export default function TextReverser() {
  const [revText, setRevText] = useState("");
  const inputElem = useRef();

  const handleClick = () => {
    setRevText(reverseString(inputElem.current.value));
  };

  return (
    <div>
      <input ref={inputElem} type="text"></input>
      <button onClick={handleClick}>Reverse Me!</button>
      {revText && <h2>{revText}</h2>}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Here's the same thing as a Lit Component:

@customElement('text-reverser')
export class TextReverser extends LitElement {
  @state()
  private revText: string = '';

  @query('#input')
  inputElem!: HTMLInputElement;

  handleClick() {
   this.revText = reverseString(this.inputElem.value)
  }

  render() {
    return html`
     <div>
      <input id="input" type="text"></input>
      <button @click=${this.handleClick}>Reverse Me!</button>
      ${this.revText && html`<h2>${this.revText}</h2>`}
     </div>
    `;
  }
}
Enter fullscreen mode Exit fullscreen mode

Oh boy! Such wow! So many new things to talk about and look at.

First, Lit uses TypeScript. It's not required, but it's encouraged and it's awesome. It saves you time on some syntax by enabling the use of decorators. It also gives you strong typing. It also gives you code completion.

Why would you not want those things?

Second, Lit components are class based. Less wow, if class syntax is not your thing. But if I had to guess, I would think that Lit will eventually get support for function based Lit components. I mean, you gotta stay with the times.

To compare what's going on...

In React:

  • I used useState to manage state for the value of revText.
  • I used useRef to grab a reference to the input element DOM node.
  • I wrote a handleClick function which gets called when the button is clicked. It reverses the string and sets the new value for revText using setRevText, which causes the component to re-render.
  • I rendered html by returning JSX. If revText has a value, it displays it in an h2.

In Lit:

  • I used the @state decorator to initialize some internal state for the component: revText. I access that in other places in the component using this.revText.
  • I used the @query decorator to grab a reference to the input element DOM node.
  • I wrote a handleClick method which gets called when the button is clicked. It reverses the string, and reassigns this.revText to that new value. Because this.revText was initialized using the @state decorator, when its value is reassigned, the component re-renders.
  • I rendered html in the render method of the component, by returning a tagged template literal, by using Lit's html tag function. If this.revText has a value, it displays it in an h2.

So what did we just learn?

They both encapsulate state & behavior.

Lit and React components both generally implement the same concept: encapsulating state and behavior into little interactive UI bits.

Mmmm....little bits.

They are both composable

Lit and React are both component-based. For each library, you can create more complex UI's by composing your components together. I didn't show how to do this in my code examples above, so here's some reading if you want to dig in further:

They are both reactive.

There is a Lit component lifecycle (no virtual DOM required) and there is a React component lifecycle. When the component state changes, the UI reflects that change.

SIDE NOTE: they both can use redux. Check out this article to learn how to set that up for Lit.

Lit is starting to feel pretty similar to React, after unpacking things a little.

So what's truly different about Lit?

Lit is closer to the browser

With Lit, a lot of the heavy lifting is done by native browser APIs, instead of by additional framework boilerplate code that also has to be downloaded.

I really like this, because it makes sense in my head to use things that are already freely available. You wouldn't make your own ice using ice trays if your fridge already had an ice machine, right?

Because of the emphasis towards leaning on what the browser already offers us (web components), Lit is a tiny library - about 5kb when minified and compressed. So if you're worried about page load and interested in browser features, Lit makes a good argument for itself.

Lit is interoperable (can be used in other things)

Because a Lit component is just a web component at the end of the day, you can use Lit anywhere! You can use Lit on its own, or you can slide Lit components into projects that are using any other front-end framework.

This is especially exciting for the purposes of implementing a design system, for instance. In one of my previous jobs I helped work on one specific implementation of our companies design system - the one that was used in our CMS. Folks from other teams that used React had to create their own React based design system implementation. And so on and so forth for all the other frameworks we used, of which there were a good number. So you can imagine there was a lot of developer time spent on rebuilding the same components over and over for different frameworks.

What if you could just implement your design system once? And reuse it everywhere? That's something Lit can offer. If you need to use one of your design system components in React - first build it with Lit. Then, pull that Lit component into React and get going.

For further reading:

  • Check out this article on how to integrate a Lit component into a React component.
  • Lit also has a separate package you can use called @lit-labs/react, which provides a utility to make a React component wrapper for a Lit component.

Parting thoughts

The main thing I want you to get from this article: Lit is cool, and you should give it a try! Please hear me when I say this: React is also excellent at what it does, and this article shouldn't be construed as a recommendation to never use React ever again.

Sometimes it's just nice to branch out, is all.

As a developer, learning should be a constant priority. So if you're feeling how I was feeling about React, and want to feel that spark again, I recommend learning Lit! They've got incredible documentation and interactive tutorials, by the way.

Thanks for reading! If you want to read any of my other articles, you can find them at quickwinswithcode.com.

Top comments (1)

Collapse
 
bradstondev profile image
Bradston Henry

You wouldn't make your own ice using ice trays if your fridge already had an ice machine, right?

You got a solid head nod from me on this statement! haha

I've been a die hard "React-ite" and it's my default for personal projects as well, but I genuinely think I'll be trying out lit in the very near future.

I already have a project that I think it would work really well with!