Lit 3 upgrade guide
If you are looking to migrate from Lit 1.x to Lit 2.x, see the Lit 2 upgrade guide.
OverviewPermalink to “Overview”
Lit 3.0 has very few breaking changes from Lit 2.x:
- IE11 is no longer supported.
- Lit's npm modules are now published as ES2021.
- APIs marked deprecated in Lit 2.x releases have been removed.
- SSR hydration support modules have moved to the
- Type only: Type of
createRenderRoot()have been updated.
- Decorator behavior has been unified between TypeScript experimental decorators and standard decorators.
- Support was removed for Babel decorators version "2018-09".
For the vast majority of users there should be no required code changes to upgrade from Lit 2 to Lit 3. Most apps and libraries should be able to extend their npm version ranges to include both 2.x and 3.x, like
"^2.7.0 || ^3.0.0".
Lit 2.x and 3.0 are interoperable – templates, base classes, and directives from one version of Lit will work with those from another.
Lit is now published as ES2021Permalink to “Lit is now published as ES2021”
Lit 2 was published as ES2019, and Lit 3 is now published as ES2021 which has wide support in modern browsers and build tools. This may be a breaking change if you need to support older browser versions and your current tooling can't parse ES2021.
Using Lit 3 with Webpack 4Permalink to “Using Lit 3 with Webpack 4”
Webpack 4's internal parser doesn't support nullish coalescing (
??), logical assignment (
??=), or optional chaining (
?.), which are syntaxes introduced in ES2021 so will throw a
Module parse failed: Unexpected token when encountering those.
The preferred solution is to upgrade to Webpack 5 which does support parsing these newer JS syntax. However if you are unable to do so, it is possible to use
babel-loader to transform Lit 3 code to work with Webpack 5.
To transpile Lit 3 in Webpack 4, install the following required babel packages:
And add a new rule that is similar to the following (you may need to modify it based on your specific project):
Updates to Lit decoratorsPermalink to “Updates to Lit decorators”
This means that there is more than one version of the decorator API in existence: standard decorators, TypeScript's experimental decorators, and previous proposals that Babel has implemented, such as version "2018-09".
While Lit 2 supported TypeScript experimental decorators and Babel's "2018-09" decorators, Lit 3 now supports standard decorators and TypeScript experimental decorators.
The Lit 3 decorators are mostly backwards compatible with the Lit 2 TypeScript decorators - most likely no changes are needed.
Some minor breaking changes were necessary to make the Lit decorators behave consistently between both experimental and standard decorator modes.
Changes to Lit decorator behavior in Lit 3.0:
requestUpdate()is called automatically for
@state()decorated accessors where previously that was the setters responsibility.
- The value of an accessor is read on first render and used as the initial value for
changedPropertiesand attribute reflection.
- Lit 3 decorators no longer support the
version: "2018-09"option of
@babel/plugin-proposal-decorators. Babel users should migrate to standard decorators.
- [Optional]: We recommend migrating
@state()to the setter for hand-written accessors to aid in migrating to standard decorators.
List of removed APIsPermalink to “List of removed APIs”
If your Lit 2.x project does not have deprecation warnings you should not be impacted by this list.
- Removed re-export of decorators from main
- Removed deprecated call signature for the
- Moved experimental server side rendering hydration modules from
Steps to upgradePermalink to “Steps to upgrade”
Removed Permalink to “Removed UpdatingElement alias for ReactiveElement”
UpdatingElement alias for
Replace Lit 2.x usage of
ReactiveElement. This is not a functional change as
UpdatingElement was aliasing
Removed re-export of decorators from Permalink to “Removed re-export of decorators from lit-element”
Lit 3.0 built-in decorators are no longer exported by
lit-element, and should instead be imported from
Deprecated Permalink to “Deprecated queryAssignedNodes(slot: string, flatten: bool, selector: string) decorator signature removed”
queryAssignedNodes(slot: string, flatten: bool, selector: string) decorator signature removed
Migrate any usage of
queryAssignedNodes taking a selector to use
Usages without a
selector now must take an options object.
Server side rendering experimental hydration modules removed from Permalink to “Server side rendering experimental hydration modules removed from lit, lit-element, and lit-html”
Experimental hydration support has been moved out of core libraries and into
[Type only]: Type of Permalink to “[Type only]: Type of renderRoot and createRenderRoot() have been updated”
createRenderRoot() have been updated
This is a type only change with no runtime effect.
The type of
ReactiveElement.renderRoot was changed from
Element | ShadowRoot to
HTMLElement | DocumentFragment and the return type of
ReactiveElement.createRenderRoot() was changed from
HTMLElement | ShadowRoot to
HTMLElement | DocumentFragment. This makes them congruent with each other, as well as lit-html's
This change generally should not affect code that simply accesses
this.renderRoot. However, any code that had explicit type annotations for their former types should be updated.
Optional: Upgrade to standard decoratorsPermalink to “Optional: Upgrade to standard decorators”
While Lit 3 adds support for standard decorators, we still recommend that TypeScript users stay with experimental decorators. This is because the emitted code for standard decorators from the TypeScript and Babel compilers is quite large at the moment.
We will recommend standard decorators for production when browsers support them, or when we release decorator transform support in our new Lit compiler.
But you can try standard decorators now, and they work in TypeScript 5.2 and above and Babel 7.23 with the
ConfigurationPermalink to “Configuration”
TypeScriptPermalink to “TypeScript”
Install TypeScript 5.2 or later, and remove the
"experimentalDecorators" setting from your tsconfig if it's present.
BabelPermalink to “Babel”
Install Babel 7.23 or later, and
@babel/plugin-proposal-decorators. Be sure to pass the
"version": "2023-05" option to the plugin.
Code changesPermalink to “Code changes”
Add the Permalink to “Add the accessor keyword to decorated fields”
accessor keyword to decorated fields
Standard decorators are not allowed to change the kind of class member they decorate. Decorators that need to create getters and setters must be applied to existing getters and setters. To make this more ergonomic, the decorators standard adds the
accessor keyword which creates "auto accessors" when applied to a class field. Auto accessors look and act much like class fields, but create accessors on the prototype backed by private storage.
@queryAssignedNode() decorators require the
Move decorators from getters to settersPermalink to “Move decorators from getters to setters”
Standard decorators can only replace the class member they're directly applied to. Lit decorators need to intercept property setting, so the decorators must be applied to setters. This is different from the Lit 2 recommendation of applying decorators to getters.
@state() you can also remove any
this.requestUpdate() calls in the setter since this is done automatically now. If you need to not have
requestUpdate() called, you'll have to use the
noAccessor property option.
Note that for
@state() the getter will be called by the decorator when setting the property to retrieve the old value. This means that you must define both a getter and a setter.