Skip to content

Introduction to Lit

Lit is a small, fast library from Google for building Web Components — reusable custom HTML elements that run natively in the browser without a framework runtime. This lesson introduces what Lit is, why it exists, and where it fits in modern frontend development.

What Is Lit?

Lit is an open-source library maintained by Google (the successor to the earlier Polymer project) for authoring standards-based Web Components. At its core, Lit provides a base class called LitElement that extends the browser's native HTMLElement, adding an efficient rendering system, a reactive property system, and encapsulated styling through Shadow DOM.

Instead of inventing a new component model, Lit embraces the platform: every Lit component is a genuine custom element, so it works in plain HTML, inside React or Vue apps, or alongside Angular, without any adapter layer. Lit's job is simply to make writing those native components pleasant and efficient.

import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';

@customElement('greeting-card')
export class GreetingCard extends LitElement {
  static styles = css`
    p { color: darkslateblue; font-weight: 600; }
  `;

  @property() name = 'World';

  render() {
    return html`<p>Hello, ${this.name}!</p>`;
  }
}

A complete Lit component: @customElement registers the tag, @property makes name reactive, and render() returns a template that re-renders whenever name changes.

The Shape of a Lit Component

class MyElement extends LitElement {
  static properties = { /* reactive fields */ };
  static styles = css`/* scoped styles */`;

  render() {
    return html`/* template markup */`;
  }
}
customElements.define('my-element', MyElement);
  • Every Lit component extends LitElement, itself a subclass of the native HTMLElement.
  • customElements.define() (or the @customElement decorator) registers the tag name with the browser.
  • The render() method returns a TemplateResult produced by the html tagged template function.
  • Lit re-runs render() only when a reactive property actually changes, then updates only the changed DOM.

Lit at a Glance

The essential vocabulary you need before writing your first Lit component.

Concept Example Purpose
Base class class Foo extends LitElement Adds rendering and reactivity to a custom element
Register a tag @customElement('my-foo') Registers the custom element name
HTML templates html<p>Hi</p>` Declarative, efficient templating
Scoped styles static styles = css...` Shadow DOM-encapsulated CSS
Reactive property @property() name = 'x' Triggers a re-render when changed
Internal state @state() private count = 0 Reactive field not exposed as an attribute
Render method render() { return html...; } Describes the component's DOM
Install npm install lit Adds Lit to a project

Why Lit Exists

The Web Components standards (Custom Elements, Shadow DOM, and HTML Templates) give browsers a native way to define reusable elements, but writing them by hand is verbose: you must manually diff and patch the DOM, manage attribute/property synchronization, and write imperative update logic for every change.

Lit removes that boilerplate. It gives you a declarative template (html tagged templates), automatic re-rendering when reactive properties change, and an efficient update algorithm (based on the lit-html library) that only touches the parts of the DOM that actually changed, rather than re-creating the whole subtree.

  • Lit components are real custom elements — no virtual DOM, no framework runtime required to consume them.
  • lit-html templates use tagged template literals, so tooling (syntax highlighting, linting) works with plain JavaScript/TypeScript files.
  • Lit's runtime is only a few kilobytes, making it a practical choice for shareable, framework-agnostic UI libraries.

Where Lit Fits in the Ecosystem

Lit is not a full application framework like Angular or Next.js — it has no built-in router, no global state store, and no opinion about how you fetch data. It focuses narrowly on the component layer: defining, rendering, and updating individual custom elements well.

Because of that narrow focus, Lit is frequently chosen for design systems and shared component libraries that need to work across multiple frameworks (or no framework), for browser extensions, and for embeddable widgets that must be lightweight and self-contained.

Need Typical Choice
Framework-agnostic design system components Lit
Full application with routing and state management Angular, React, or Vue framework
Lightweight embeddable widget Lit
Server-rendered marketing site Astro, Next.js, or similar meta-framework

Common Mistakes

  • Assuming Lit is a full application framework rather than a focused component-authoring library.
  • Forgetting that Lit components are genuine custom elements and can be used from any framework, or none at all.
  • Confusing lit-html (the templating engine) with lit (the package that also provides LitElement and decorators).
  • Skipping the platform fundamentals (Custom Elements, Shadow DOM) and treating Lit's APIs as magic instead of a thin, understandable layer on top of them.

Key Takeaways

  • Lit is a lightweight library from Google for building standards-based Web Components.
  • Every Lit component is a real custom element, usable in any framework or none at all.
  • LitElement adds efficient templating, reactive properties, and Shadow DOM styling to native custom elements.
  • Lit intentionally stays focused on components, leaving routing and state management to the rest of your stack.

Pro Tip

Before writing your first component, spend five minutes in the browser DevTools inspecting any existing Lit-based site (many admin dashboards and design systems use Lit) and expand the Shadow DOM tree. Seeing real shadow roots in the Elements panel makes Lit's mental model click much faster than reading about it.