We use cookies to understand how the site is used and to display ads. Analytics and advertising only run after you accept. You can change your choice anytime. Privacy policy

Skip to content
devvkit
$devvkit learn --librarie lit-guide

Lit Guide

[web-components][frontend][reactive][custom-elements]
JavaScript / TypeScript
Install
npm create vite@latest my-app -- --template lit-ts
# or: npm init lit

Lit is a web component library from Google. It builds directly on the Custom Elements v1 and Shadow DOM standards. No framework needed: your components work in any HTML page or any framework.

LitElement extends HTMLElement. Reactive properties trigger automatic re-renders. Lit's templating uses tagged template literals (html`...`): extremely fast with no virtual DOM.

Lit 3 is tree-shakeable and tiny (~5 KB gzipped). It supports decorators (@property, @customElement) or the `static properties` pattern. SSR via @lit-labs/ssr.

Setup

Create app· Scaffold Lit project.
npm init lit@latest my-app
cd my-app
npm run dev

Component

Basic component· Lit element.
import { LitElement, html, css } from 'lit'
import { customElement, property } from 'lit/decorators.js'

@customElement('my-greeting')
export class MyGreeting extends LitElement {
  static styles = css`:host { color: blue; }`

  @property() name = 'World'

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

<!-- Usage in HTML: -->
<my-greeting name="Lit"></my-greeting>

Reactive Properties

Reactive properties· Fine-grained reactivity.
class MyElement extends LitElement {
  // Attribute reflects to property
  @property({ type: String }) name = 'Alice'
  // No attribute reflection
  @property({ attribute: false }) data: Record<string, unknown> = {}
  // Boolean attribute
  @property({ type: Boolean }) active = false
}

Templates

Conditional render· Templates with conditionals.
render() {
  return html`
    ${this.loading
      ? html`<p>Loading...</p>`
      : html`<p>${this.data}</p>`
    }
  `
}
Lists· Repeat templates.
render() {
  return html`
    <ul>
      ${this.items.map(item => html`<li>${item.name}</li>`)}
    </ul>
  `
}

Events

Events· Handle user events.
class MyButton extends LitElement {
  @property() label = 'Click'

  private handleClick(e: Event) {
    this.dispatchEvent(new CustomEvent('my-click', { detail: { time: Date.now() } }))
  }

  render() {
    return html`<button @click=${this.handleClick}>${this.label}</button>`
  }
}

Lifecycle

Lifecycle· Reactive update cycle.
class MyElement extends LitElement {
  @property() data: string[] = []

  willUpdate(changed: PropertyValues<this>) {
    if (changed.has('data')) {
      this.processData(this.data)
    }
  }

  updated(changed: PropertyValues<this>) {
    console.log('Component updated')
  }
}