$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')
}
}