lit-element: the legacy 2.x base class, and what installing it actually gets you
LEGACY REPO. This repository is for maintenance of the legacy LitElement library. The LitElement base class is now part of the Lit library, which is developed in the lit monorepo.
At a glance
- What is it?
- LitElement 2.x is a maintenance-only repository now that the base class lives in the Lit monorepo. Here is what the package contains, how to install it, and when reaching for it is the wrong call.
- Who is it for?
- Adopt lit-element 2.x only if you are maintaining an existing 2.x codebase or must support a build that cannot move to Lit 2; anyone starting a web component project should install lit instead, because the README states the base class now lives in the Lit monorepo and Lit 2 includes lit-html 2.x and LitElement 3.x. Before committing, verify three things: that the published package version is 2.5.1, that your toolchain can handle the decorator imports the README moves to lit-element/decorators.js, and that your target browsers are covered, since Edge and Internet Explorer 11 need the web components polyfills.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 98 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What problem lit-element 2.x solves, and for whom
Writing a custom element by hand means calling customElements.define, managing a shadow root, tracking which attribute changes should trigger a re-render, and diffing the DOM yourself. LitElement is a base class that takes over those chores. The README describes it as a simple base class for creating fast, lightweight web components with lit-html, and the mechanism is narrow on purpose: you declare reactive properties, and the class reacts to changes in properties and attributes and renders declaratively. The audience is anyone shipping a component that has to work inside a page they do not fully control, whether that page is a framework app, a CMS, or plain HTML.
The repository itself is the important caveat. Its first line calls it a legacy repo, kept for maintenance of the legacy LitElement library. The code here is LitElement 2.x. If you are starting fresh in 2026, the README points you at the Lit library monorepo, where Lit 2 includes lit-html 2.x and LitElement 3.x. So this page is about a package you inherit, not one you pick.
How the base class turns properties into rendered DOM
The data flow is short. A class extends LitElement, declares properties, and returns a lit-html template from render(). When a declared property changes, the element schedules an update, runs the template, and lit-html patches only the parts of the shadow DOM that changed. That is the whole loop, and it is why the README can call the class lightweight: there is no virtual DOM tree to diff, only the bindings inside the template.
The README's example shows the decorator route. @customElement registers the tag name, @property creates a property accessor that triggers rendering and an observed attribute, and static styles holds a css tagged template. The rendered output for a mood of awesome is the sentence with the value substituted into a span. The README notes that decorators are a proposed standard available in TypeScript or Babel, and that LitElement also supports a vanilla JavaScript method of declaring reactive properties. That second path matters if your build pipeline has no decorator support, because the decorator syntax is not something the browser parses for you.
Installing lit-element and rendering a first element
The README gives one install command, run from inside your project folder. It installs the published package, which package.json lists as version 2.5.1.
$ npm install lit-elementIf you need to support older browsers, the README adds a second, dev-only install for the web components polyfills.
$ npm i -D @webcomponents/webcomponentsjsWith the package in place, the README's own example is the shortest real use. It uses decorators, so this is the TypeScript or Babel path.
import {LitElement, html, css, customElement, property} from 'lit-element';
@customElement('my-element')
export class MyElement extends LitElement {
@property()
mood = 'great';
static styles = css`
span {
color: green;
}`;
render() {
return html`Web Components are <span>${this.mood}</span>!`;
}
}Consume it from HTML with the attribute that @property observes. What you should see is the mood value rendered inside a green span.
<my-element mood="awesome"></my-element>The README also points at runnable versions of this on Glitch, Stackblitz, JSFiddle, JSBin and CodePen, plus a single HTML file you can copy locally and open in any browser with JavaScript modules support. If your build system fights you, that HTML file is the fastest way to confirm the library itself works before you debug the toolchain.
Forward compatibility: the 2.5 renames you must make before Lit 2
The README's most useful section is a migration table, because Lit 2 introduced breaking changes and deprecations that were back-ported to LitElement 2.5 to ease upgrading. If you are on 2.4 or earlier, these renames are the work.
Decorator imports move off the main entry point: import {customElement} from 'lit-element' becomes import {customElement} from 'lit-element/decorators.js'. @internalProperty() becomes @state(). Overriding _getUpdateComplete() becomes overriding getUpdateComplete(). Shadow root options move from overriding createRenderRoot() to a static shadowRootOptions field. And importing UpdatingElement becomes importing ReactiveElement.
Each of these is a small edit, but they are not optional if you want a later upgrade to be mechanical. Doing them while you are still on 2.x is cheaper than doing them at the same time as a major version jump, which is exactly why the maintainers back-ported them.
Where lit-element 2.x is the wrong tool
The clearest limitation is stated by the repository itself: this is a legacy repo for maintenance. The last push was on 2026-06-24, but the newest release listed is v2.4.0 from 2020-08-19, and package.json carries 2.5.1. A repository receiving maintenance commits is not the same thing as a library receiving features. Treat the 2.x line as frozen and expect fixes rather than new capability.
The second limitation is browser support. The README says the last 2 versions of all modern browsers are supported, including Chrome, Safari, Opera, Firefox and Edge, and that Internet Explorer 11 is also supported. Edge and IE11 require the web components polyfills. That polyfill requirement is a real cost in bundle size and load order, and it is the sort of thing that pushes teams toward a different rendering strategy entirely.
The third is the decorator dependency. If your build cannot run TypeScript or the Babel decorator plugin, you fall back to the vanilla JavaScript property declaration the README mentions, which is a different and less compact way to write the same class. None of these are defects. They are the boundaries of a 2.x library, and the README is honest about them.
lit versus lit-element: the same class, a different repository
The real alternative is Lit, and the difference is not stylistic. Lit is the successor project in the lit monorepo; the README states that Lit 2 includes lit-html 2.x and LitElement 3.x. So the base class you get from lit-element 2.x is an earlier version of the same idea, developed in a different repository with a different release cadence.
Practically, choosing Lit means you are on the line that is still being developed, and you inherit a different set of import paths than the 2.x ones. Choosing lit-element 2.x means you are on a package whose newest listed release is from 2020, with a documented rename table as the bridge between the two. The migration table exists precisely because the two are close enough that a set of mechanical edits gets you across.
If you want an alternative with a genuinely different approach, that is a different conversation: a virtual-DOM framework re-renders a component tree it owns, while LitElement hands rendering to lit-html and patches bindings inside a shadow root. The README frames the class as lightweight for exactly that reason. That distinction matters more than any feature list when you are embedding a component into someone else's page.
Licence and the cost of staying on 2.x
The licence is BSD-3-Clause, listed in package.json and in the repository's LICENSE file, with Google LLC as author. That is a permissive licence, and nothing in the repository suggests any additional term attached to the published package. This is a description of what the files say, not legal advice; if your organisation has a licence review process, run the package through it.
The upgrade cost is the thing to budget for. The README's table lists five API changes between 2.4 and 2.5/Lit 2, and each one touches source files rather than configuration. The decorator import change touches every file that imports a decorator. The @internalProperty to @state rename touches every internal reactive field. The _getUpdateComplete to getUpdateComplete change touches any subclass that overrode it. The createRenderRoot to static shadowRootOptions change touches any element that customised its shadow root. And the UpdatingElement to ReactiveElement rename touches any code that imported the base class directly.
That is a finite, greppable list. The cost is not in any single edit; it is in the fact that these renames have to land before the version jump, so the work happens twice if you defer it.
Editorial conclusion
Adopt lit-element 2.x only if you are maintaining an existing 2.x codebase or must support a build that cannot move to Lit 2; anyone starting a web component project should install lit instead, because the README states the base class now lives in the Lit monorepo and Lit 2 includes lit-html 2.x and LitElement 3.x. Before committing, verify three things: that the published package version is 2.5.1, that your toolchain can handle the decorator imports the README moves to lit-element/decorators.js, and that your target browsers are covered, since Edge and Internet Explorer 11 need the web components polyfills.
Frequently asked questions
What is a lit element?
LitElement is a base class for creating web components with lit-html, which renders into the element's shadow DOM and adds API for managing properties and attributes. The README describes it as simple, fast and lightweight, and it reacts to property changes by re-rendering a lit-html template.
Is lit better than react?
The README does not compare LitElement to React, so it makes no claim either way. It does describe a different rendering approach: LitElement renders declaratively with lit-html into a shadow root rather than managing a component tree, and the repository positions the class as lightweight.
What is lit used for?
According to the README, it is used to create fast, lightweight web components. You declare reactive properties, and the class reacts to changes in properties and attributes and renders declaratively using lit-html, with the result placed in the element's shadow DOM.
What are the alternatives to lit-element?
The README points to the Lit library monorepo, where Lit 2 includes lit-html 2.x and LitElement 3.x. That is the successor to this repository, which exists for maintenance of the legacy LitElement 2.x code.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lit-lit-element)