I had lit in a project at work and not having to deal with it anymore is just great. We already have another heavier component framework to do the actual application stuff anyway, so having two just because somebody wanted to optimize their resume was such a drag.
It all looked nice in theory, but one thing shadow DOM makes worse is A11y, because element ids are now scoped and all the missing describe-by, label-for for things that should link to other side of the fence are a massive pain in the ass.
Big part of it is just skill issue on our part of course.
kubb · 1h ago
Shadow DOM is optional in Lit - you can just disable it on a per-component basis.
gitaarik · 2h ago
I made a state management lib for Lit, that's just as lightweight (258 lines) and intuitive:
I've used it extensively myself, for creating complex web apps with many (nested) components interacting with each other.
I don't understand why Lit hasn't gained more popularity, because for me it is basically React, but then more browser-native, much less boiler plate, and much faster rendering. There are some things you have to get used to, but when you do it doesn't limit you in any way.
jfagnani · 5h ago
Lit maintainer here. I should be going to bed, but I'll answer any questions if people have any!
Not sure why Lit showed up on the front page tonight :)
polyrand · 5h ago
Hi! Not really a question, but just an appreciation message. I haven't used the full "Lit" package a lot, but "lit-html" is incredibly useful.
I use it in almost all my personal websites. And when I don't use it, I end up reinventing half of it and realize I should have used it from the start. This command is in most of my projects:
I've never felt I'm using a framework or anything that deviates from Vanilla JS and valid HTML, which is why using it hardly causes any more cognitive load than using regular string templates and JavaScript functions. Which is something that I can't say about other frontend tools.
Another thing I like from Lit is that with the CDN bundle, it's straightforward to experiment and use all the features without needing a build step.
dtagames · 42m ago
Nice to see you here and THANK YOU for the amazing tool that is Lit. It's everything you want from a framework without a framework getting in your way.
I'm sold and build all my work and personal apps with it and have for many years. I wrote this article about why in 2022:
Thanks, great article. It’s always good to understand the context of where libraries fit into the web ecosystem and why they exist. Much appreciated!
krikou · 2h ago
Here just to say thank you for Lit! It is a real pleasure to use (for simple and complex use-case).
Sometimes, I am wondering why it is not more widely used ...
akmittal · 5h ago
Curious which web platform features are missing that are preventing Web components to complete with React(for application development not widgets)?
jfagnani · 5h ago
I think web components already compete extremely well for application development, and you see very complex apps built with Lit out there: Photoshop, Firefox, Chrome OS, Chrome DevTools.
Apps are well served because they have more control about how components are used: they can import the same shared styles into every component, take are to not double-register elements, etc.
But I think there are some important standards still missing that would open things up even more in the design system and standalone components side:
- Scoped custom element registries. This moves away from a single global namespace of tag names. Seems like it's about to ship in Safari. Chrome next.
- Open styleable shadow roots. Would allow page styles to flow into shadow roots. This would make building components for use with existing stylesheets easier.
- CSS Modules. Import CSS into JS. Shipping in Chrome. About to land in Firefox.
- ARIA reference target: make idref-based reference work across shadow roots
notnullorvoid · 32m ago
Please do not refer to CSS type imports in JS as CSS Modules.
CSS Modules has an established meaning for over a decade, one that is still relevant today. The CSS type imports are very different, and arguably worse.
Call them CSSStyleSheet imports of you need a name suggestion.
brazukadev · 2h ago
> - Open styleable shadow roots
What people using web components want is to get rid of shadowDOM and not feel like they are deviating from the correct path. shadowDOM sucks, stop trying to convince the world that we are using it wrong. shadowDOM is the whole reason web components did not become mainstream (yet?).
dtagames · 35m ago
I disagree completely. Shadow DOM is a huge help and when combined with per-component CSS using the :host() and nesting pattern, makes for very small CSS files and very short CSS class names. In other words, as far away from Tailwind as you can get.
It's also possible to import shared CSS in a base class and add it with super.styles() so you don't lose anything.
Any whispers of something like lit being made part of the webcomponents standard?
Web components are nice because they're browser-native, but they don't support reactivity, which in hindisight, is a massive oversight, issue, whatever you want to call it - it's hindered adoption.
Lit is nice because there's a very straightforward progression from web components.
jfagnani · 5h ago
Lit has always been designed partially as a prototype for where web component standards could go in the future. That's a big reason Lit is fairly conservative and un-opinionated. It doesn't try to undo or paper-over any of the DOM APIs, but add to them instead.
There is a proposal in TC39 for native signals, which I think would make a huge dent towards library-less reactivity.
I'm also working on a proposal for native reactive templating which would more-or-less obsolete lit-html. I wrote about the idea some on my blog:
I hope there can be ways without JS to populate templates with data - autoloaded from sources. This would tremendously increase the number of JS free web-sites. Also wish the web-components standard did not mandate the use of JS. It should be possible to define simple web-components (HTML+CS) declaratively and have this officially supported in standard and implementation
troupo · 2h ago
> Lit has always been designed partially as a prototype for where web component standards could go in the future.
> There is a proposal in TC39 for native signals,
Which originated (or the modern versions of signals originated) in Solid, not in Lit.
The current draft is based on design input from the authors/maintainers of Angular, Bubble, Ember, FAST, MobX, Preact, Qwik, RxJS, Solid, Starbeam, Svelte, Vue, Wiz, and more…
-- end quote ---
nchmy · 1h ago
They never claimed that signals originated in lit. They were just responding to the comment that there's no native reactivity in web components...
iammrpayments · 4h ago
Are properties reactive?
Can I reassign name in the example by using document.querySelector?
jfagnani · 3h ago
Yes!
mkleczek · 3h ago
Thanks for your great work.
I can't find clear information about how re-rendering and stateful third-party components interact.
Let's say I have a stateful data table web component that I use in the template. Is it going to be re-created every time the template is re-rendered (loosing its internal state)?
jfagnani · 3h ago
Thanks!
Elements are kept stable as long as the template containing them is rendered.
The template docs try to get this across by saying that Lit "re-render only the parts of template that have changed." Maybe that needs more detail.
Is there a way to efficiently use Lit without using a bundler?
jfagnani · 5h ago
Lit's just a JavaScript library published as standard modules, so it doesn't require a bundler. Using Lit efficiently is the same as using any other library.
HTTP/3, import maps, and HTML preloads can make unbundled app deployment almost reasonable in some cases. You'd still miss out on minification and better compression form a bundle. Shared compression dictionaries will make this better though.
BenoitEssiambre · 43m ago
Lit is amazing, one of the most concise framework out there. For deepening my understanding of concepts around Lit, I once built LittleLit, a 37 lines of code framework around Lit-html that helps understand how simple and elegant the moving pieces of this tech can be.
I don't see the need for Lit anymore. Lately I have just been raw dogging web components without any libraries. Having a nice templating system like JSX on the server makes it a breeze.
Part of using web components, for me, is that it is just javascript. There is no upgrades or deprecations to think about. Of course those things still exist on the server though, but it is easier to maintain it there.
mariusor · 4h ago
Personally I find that lit abstracts quite well some pieces of functionality that you're going to implement yourself anyway to not have to write manual <template> all over your code plus the plumbing to add it to the DOM.
o_m · 2h ago
Yeah, it does require some more boilerplate. I abstract some of it JSX, and with LLMs writing boilerplate code isn't that annoying anymore.
jfagnani · 3h ago
The great thing about web components is that you can build them however works best for you.
Native web component APIs don't have the DX that many people expect though, because they are so low-level. Lit provides just that declarative reactivity on top.
kubb · 5h ago
For the frontend work that I did, Lit was a godsend. It really helps you build components and apps without getting in the way.
In comparison, Angular is a monster, and React is designed for the old browser capabilities, and is now staying around by inertia, not by inherent quality.
pmanu · 4h ago
That’s also why I really like Aurelia framework. Its component model feels very intuitive, and it embraces standards like custom elements and decorators instead of inventing new patterns. Compared to Angular’s boilerplate or React’s hook gymnastics, Aurelia lets you write less code that looks more like plain JS/HTML.
Too bad Aurelia never got the same traction as the big frontend names, because the DX is really solid.
SebastianKra · 2h ago
I thankfully migrated or left all Aurelia projects, but every time someone mentions it, I remember new horror stories.
Its .html temples were shipped unmodified directly to the client (yes, including comments). Except they weren't actually html, and sometimes the browser would try to clean them up, breaking the template.
Reactivity was achieved through all kinds of weird mechanisms (eg monkey-patching arrays to watch for mutations). It would frequently resort to polling on every tick or break completely.
DI used TypeScripts experimental decorators, even long after it was clear that it would never become stable.
On the other hand, templates weren't type checked.
SebastianKra · 2h ago
I thankfully migrated or left all Aurelia projects, but every time someone mentions it, I remember new horror stories.
Its .html temples were shipped unmodified directly to the client. Except they weren't actually html, and sometimes the browser would try to clean them up, breaking the template.
Reactivity was achieved through all kinds of weird mechanisms (eg monkey-patching arrays to watch for mutations). It would frequently resort to polling on every tick or break completely.
DI used TypeScripts experimental decorators, even long after it was clear that it would never become stable.
On the other hand, templates weren't type checked.
pmg101 · 4h ago
Which old browser capabilities are you referring to? Could you say more, or link to more details?
kubb · 4h ago
No shadow DOM, no web components, no template strings, etc.
troupo · 2h ago
> No shadow DOM
Funny you should say that when the current advise for web components is to avoid Shadow DOM (almost like the plague)
> no web components
As in?
> no template strings
Why would React need template strings? React is not the only framework that doesn't use template strings for anything (Vue, Solid, Svelte come immediately to mind). And it's hard to accuse those of being behind the times when Solid is literally the reason for the upcoming native signals proposal
iamsaitam · 3h ago
"React is designed for the old browser capabilities and is now staying around by inertia, not by inherent quality." this makes me feel old and I guess React is famous for supporting Internet Explorer /s
kubb · 2h ago
React is 12 years old. That’s a significant chunk of anyone’s life.
troupo · 2h ago
Web components are 14 years old, and still have the most basic issues and problems that even a 6-month-year-old framework would ashamed to have.
kubb · 1h ago
I await your in depth critique on the front page.
mulhoon · 3h ago
Working with a large Vue 3 project and wanting to share some of our components as re-usable web components for other sites to embed...
What would be the benefit of rebuilding these components in Lit over using Vue to build them?
I have used both. Personally I prefer Vue a bit more.
* Built-in state management especially as in v3 (ref/reactive) is super powerful, and you can test the setup function logic by itself without any dependency on DOM which is convenient. By comparison, reactivity in Lit is basic (by design), and mostly work on the widget level -- if something changes, you need to trigger the update process of the widget.
* The lifecycle is also a bit simpler. In Lit, you often need to work with lifecycle callbacks like firstUpdated, connected, shouldUpdate, updated, disconnected etc. (You don't need to implement these for simpler widgets, but often you have to.) You can easily run into bugs if you are not careful, especially in the less common situation where your widget can be both temporarily and permanently removed from the DOM, in which case you need to make sure the state of the widget is properly perserved, which isn't a thing you need to worry about in Vue. We got bitten by this multiple times.
Unless there is a strong technical reason, I suggest that you focus on shipping features instead of changing your tech stack. Rebuilding your widgets is a very time consuming task with, well, near 0 impact on the user.
mulhoon · 1h ago
Thanks for this. I think you're right -> "focus on shipping features instead of changing your tech stack"
Ruphin · 3h ago
I don't know if there is a particular benefit, it's just different. On the consumer side there is no difference, because they consume Web Components, and that is what both solutions deliver. On the implementation side, I can think of a few differences:
Vue is more of a "framework" solution and has more things built-in. You can do the same things with Lit, but the implementation would look different, because you'd lean more on native APIs. A good example of that is the event model, Vue has some event model built in, but with Lit you would use EventTarget.dispatchEvent().
Lit is a runtime solution, it doesn't require a build and you can load your source directly in the browser. Vue on the other hand requires some form of compiler stage to produce something your browser can use. Compilers these days are fast, and Lit is specifically engineered to not have runtime performance overhead, so in practice this difference is rather minor. It is a very fundamental difference, so I think it's worth pointing out.
Vue can compile to other targets. If you are only delivering Web Components, this is mostly irrelevant, but in theory a consumer might be able to use the Vue components directly in their Vue project, which might give them a better DX. On the other hand, Lit is specifically designed to produce Web Components, so you'll probably have a bit less friction compares to using Vue, e.g when some Vue concept doesn't compile cleanly to Web Components.
Is there a major benefit to choosing one implementation over the other? I don't think so, unless you have a very particular requirement that one of them addresses that the other doesn't. For nearly all cases, it is just a different implementation syntax.
In most cases the only relevant metric in deciding between them is what technology your developers are more familiar/comfortable with.
rs186 · 2h ago
Vue can be used as an ordinary JS library without special build setup. You can even load the library from a CDN as a global variable like the old jQuery days.
mulhoon · 1h ago
Thanks for the in-depth response, much appreciated
whs · 2h ago
Does Lit have a good component library? Like, a complete web template (eg. Bootstrap/Ant), datepicker, color picker, virtual scroll, data tables, typeahead, tab, etc.
I shipped a project with Lit and I liked it, but I didn't like that I'd need to know the complete project scope up front that I could write everything from the ground up. I know I could use React component for some of the harder stuff but at that point might as well use React and avoid bundling two systems
jonjlee · 47m ago
DaisyUI and HyperUI, which are both full component libraries based on tailwind, play well with lit. You either opt out of using the shadow dom or import the global styles into the component. Both methods have official lit support.
sibit · 2h ago
I really like the standalone lit-html rendering library but never really saw a need for Lit. Honestly, I find it hard to see a need for more than <any client-side rendering lib> + Web Components when I want client-side rendering.
kavaruka · 5h ago
I have been using Lit in production for 3 years now. I think it is the best abstraction over the web components API out there.
selectnull · 5h ago
Same here.
I have actually wrote a few web components by hand in an environment where I didn't want any external dependencies and when that requirement was dropped I really liked how easy was to convert them to LitElement (and how much nicer it is to work with them).
I also have embraced the shadow DOM which is a default, but I think it's more trouble than it's worth. Now I use LitElement without shadow DOM and it works great as well.
brazukadev · 2h ago
Same about the shadowDOM. The only criticism I have about Lit is that the creators think shadowDOM is amazing and people not liking it are using it wrong. Lit lacks a good direction and someone with vision leading it but it became the technical pet project of a few.
zacian · 6h ago
Lit is amazing, I'm a big fan of Astro for using it as static websites, blogs, etc., but Lit would've been the second choice if not Astro.
No comments yet
tkubacki · 5h ago
Lit is fantastic lib as a way out from legacy web framework (since can be injected in any framework including Vue, Angular, React). I used it as a way out out of old Vue2 project
ricny046 · 5h ago
I love Lit! I have been using it to develop a in-app widget for product updates here: https://supanotice.com (the in app-widget opens up if you click on the bubble in the bottom right corner)
Really love the abstraction that makes web components easy to use.
moxvallix · 3h ago
I’ve been using Lit to develop my Minecraft skin editor and it has been really nice to work with. Having initially tried working with vanilla web components, then creating my own wrapper class to make them easier to work with, I can say that Lit makes web components really nice to work with.
The developers of data-star.dev are working on something interesting they call "Rocket", but it's currently a WiP and hidden behind a paywall so I can't really compare it to Lit. Lit is great though, used it myself a few times (e.g. github.com/romshark/demo-islands). But I still think there's a learning curve to Lit. Better than raw vanilla JS custom elements API, but still not as simple as it could be.
epolanski · 6h ago
Great project but I can't stand syntax such as decorators.
jfagnani · 5h ago
Decorators are the only way to metaprogram over class fields in JS. Otherwise they're not even detectable on the prototype.
We use them to make fields reactive mostly, and I love how declarative they are. But we use them sparingly. I personally don't love how some libraries try to put a lot of things into decorators that could have been standard class features, like a static field or a method.
We also put a lot of effort into making all of our documentation and playground samples on lit.dev available in both JavaScript and TypeScript with decorators. There's a switch that will change everything on the site from JS to TS globally.
epolanski · 4h ago
> Decorators are the only way to metaprogram over class fields in JS.
I can think about few other ways, such as using higher order functions/classes, using getOwnPropertyDescriptor or doing stuff at construction.
> As mentioned by skrebbel, decorators are optional
This is not a pro, it's a con. The more ways there are to achieve the same result the more inconsistent projects become IRL.
Also, do you really want to metaprogram at all? What's the huge benefit of that approach?
jfagnani · 4h ago
There really is no way to metaprogram against class fields except with decorators.
Class fields aren't on the prototype. They're essentially Object.defineProperty() calls that occur right after the super() call of a constructor. You can't get at them at all from the class declaration.
I know more than one way to do something is sometimes a downside, but we have a large audience an a huge portion of it wants to use TypeScript and declarators, and another huge portion of it wants to use vanilla JavaScript. We factored things to give the best DX we could to each group with relatively little cost to us.
As for why metaprogramming, we want a component to update when it's state is changed. Like plain web components, Lit uses classes.
So here, we want setting `el.name` to cause the component to re-render:
class MyElement extends LitElement {
name = 'World';
render() {
return html`<h1>Hello ${this.name}</h1>`
}
}
We do that by replacing `name` with a getter/setter pair where the setter schedules an update of the instance. Without decorators, there's no way to see that `name` even exists, much less replace it.
Decorators actually do the replacement for us, we just have to build the thing to replace it with:
class MyElement extends LitElement {
@property() accessor name = 'World';
render() {
return html`<h1>Hello ${this.name}</h1>`
}
}
brazukadev · 2h ago
> Decorators are the only way to metaprogram over class fields in JS.
No, they are not. Decorators don't even exist in JavaScript. Stop assuming typescript is Javascript or even worse, that everybody is on board.
> There's a switch that will change everything on the site from JS to TS globally.
Lol.
skrebbel · 5h ago
Just to add to a sibling comment, they are optional and not in a “optional but if you dont use them it really sucks” kind of way.
The Lit authors tried hard to use vanilla JS everywhere they could, and it shows.
hliyan · 4h ago
Not seeing decorators in the JS version:
export class SimpleGreeting extends LitElement {
...
}
customElements.define('simple-greeting', SimpleGreeting);
gitaarik · 2h ago
Why exactly?
mdhb · 6h ago
They are optional for what it’s worth. They are also landing in standard JS soon.
Klaster_1 · 6h ago
The proposal is stuck at stage 3. AFAIK, to proceed to stage 4, it needs two independent implementations, but Firefox [0] and Chromium [1] didn't see any progress in this area for about a year. Personally, after working with Angular for many years, that's not a language feature I am looking forward to.
Hands down the most underrated front end library out there. It powers some major projects like ChromeOS, Chrome Devtools, I think most of Firefox’s UI, Photoshop for the web, MDN etc.
CharlieDigital · 2h ago
Also Reddit! Any other surprise sites?
shoeb00m · 2h ago
I think lit is great but the reddit site is the perfect example of why the framework you chose is not the reason your site is slow.
I think lit should distance itself from that mess if possible
Arubis · 1h ago
(Formerly lit-element)
andrewstuart · 3h ago
I looked at lit but chose JSX.
Typescript has JSX built in so when "I made my own framework" I just used that.
mdhb · 6h ago
I just came across this resource the other day and found it super helpful, thought I would share it here for anyone who’s interested in working with Lit.
thank you, I am not brining inheritance and decorators back to the web
troupo · 5h ago
The evolution of lit is fascinating to watch because it's built and promoted by people with rather visible and public dislike of everything React. And yet, it's already turned into React-lite.
// classMap looks like a regular JS function, but it's not.
// Both of these will produce an error
<div class="my-widget ${classMap(dynamicClasses)} ${classMap(dynamicClasses)}">Static and dynamic</div>
<div data-class="${classMap(dynamicClasses)}">Static and dynamic</div>
You have a very large axe to grind against web components and Lit, and you show up just about everywhere to make the same comments, but I'll play along anyway:
Yes, Lit templates give some special meaning to attribute names with a few prefixes. No, it's not "HTML-like". It's valid HTML. Not that it matters much. You bring this up all the time but I'm not sure what the actual criticism is. Developers seem to understand the small syntax carve-out just fine.
No, there are no custom JavaScript rules. Templates have some rules. I'm not sure why they wouldn't? In general you can't make things like tag and attribute names dynamic because you can't change them in HTML. You can actually write the template you show with what we call static templates though.
`classMap()` is a template directive. It has some rules about how it's used in templates, just like other JS functions can have rules about how their used. I'm not sure what makes that not a function.
But to your main point: Lit is not like React because it's not a framework. Lit helps you make custom elements - it's an implementation detail of some web components. Everything else about those elements: how you instantiate them, style them, where they work, etc., is all defined by the HTML and DOM standards. React is a framework, and defines its own rules about how its components work.
dtagames · 10m ago
Time to put the nail in that coffin! I use a static template to select and return components dynamically. It's a key aspect of my own internal "framework," made with Lit.
I love that I get to choose how everything works. I have custom systems for routing, styling, signals, API interactions. I control who gets passed what and when. It makes the app feel light, responsive, and -- most importantly, it fits in my head and I understand how it's put together because I chose it, not because I learned it from someone.
troupo · 5h ago
> You have a very large axe to grind against web components and Lit
Yes, yes I do. Because Web Components are almost 15 years now, and they still struggle with the most basic of things. How's that abandoned roadmap going? https://w3c.github.io/webcomponents-cg/2022.html
> No, there are no custom JavaScript rules. Templates have some rules.
That is "here are regular JS functions. However, you cannot use them as regular JS functions in these specific contexts". Reminds me of certain very specific rules about specific functions in specific contexts in some other framework. Can't put my finger on it.
> I'm not sure what makes that not a function.
I never said it doesn't make it a function.
> But to your main point: Lit is not like React because it's not a framework.
Yeah, React wasn't a framework either, but just a library. Everything about DOM elements that React produces, how you instantiate them, style them, where they work etc. is all defined by the HTML and DOM standards.
But then React grew in the number of features, and can no longer be called a library even though still the only thing it does is output some DOM nodes.
I guess you'll insist on Lit being "just a library" even after it adds a ton of other functionality all other frameworks already have or are moving towards.
> I'm not sure what the actual criticism is
The criticism is usual: Lit is rapidly absorbing all the features from all the other frameworks and becoming a framework itself while many of its developers and proponents can't stop shitting all over other frameworks.
mariusor · 4h ago
As a third party I can't help but notice that the only one doing the "shitting" here, is you.
Ruphin · 3h ago
Web Components is a pretty niche technology and as such it really appeals to some people, and it doesn't appeal to others, and that's okay. You don't have to like it, it isn't meant to be a good fit for everyone. But for some people it might fit really well with their requirements, and they probably have legitimate reasons for that.
If I understand correctly, your criticism is that the people for whom Web Components is a good fit are publicly discussing the reasons why they prefer it over other solutions?
troupo · 2h ago
> pretty niche technology
The main problem is that for a "niche technology" it sure infects too many standards, requires an insane amount of new standards and makes supporting things needlessly complicated.
There are some good parts in the ~30 standards they require, but instead of just the good parts you get the whole horse, and the cart it's attached to, and the cargo in the cart.
> your criticism is that the people for whom Web Components is a good fit are publicly discussing the reasons why they prefer it over other solutions?
It's not.
gitaarik · 2h ago
Ha this guy again, I recognize you too. I also don't understand your obsession with trolling on Lit and Web Components. You keep coming with the same arguments. And always very emotional. I get the feeling that it is something personal that you have against Lit / Web Components. And you're clearly a hater, and haters are gonna hate regardless of whatever happens.
I do wonder, why are you on this crusade? Are you afraid that people are at some point gonna be persuaded by Lit / Web Components, and that you need to be there to prevent that from happening?
mdhb · 3h ago
Take this as some constructive feedback that you really come across as a miserable bastard to everyone reading your comments.
afavour · 3h ago
I’m not one of those people but I don’t see an inherent conflict in what you’re saying. My #1 criticism of React is its size and monoculture, so a React-lite alternative sounds intriguing to me. Much like Preact, which I’ve used a ton.
hk1337 · 3h ago
“You got Lit up!”
TekMol · 3h ago
I'm all for a lightweight approach to software development. But I don't understand the concept here.
Looking at the first example:
First I had to switch it from TS to JS. As I don't consider something that needs compilation before it runs to be lightweight.
Then, the first line is:
import {html, css, LitElement} from 'lit';
What is this? This is not a valid import. At least not in the browser. Is the example something that you have to compile on the server to make it run in the browser?
And when I use the "download" button on the playground version of the first example, I get a "package.json" which defines dependencies. That is also certainly not something a browser can handle.
So do I assume correctly that I need to set up a webserver, a dependency manager, and a serverside runtime to use these "light weight" components?
Or am I missing something? What would be the minimal amount of steps to save the example and actually have it run in the browser?
Ruphin · 2h ago
I guess for most people the standard is to install things from NPM which explains the format of the documentation. If you want to do something completely raw, you can replace 'lit' with something like this:
I estimate the vast majority of "web projects" begin with npm installing something of some sort, yes. React is dominating the web development space (judging from the average "popular web stack 2025" search result), and it and a significant portion of the competing platforms start with installing some dependencies with npm (or yarn, or what have you). Especially projects that compete in the same space as Lit.
That isn't a criticism of projects that don't use npm, and it doesn't make them less valid, but it makes sense for the documentation to match the average developer's experience.
Ruphin · 2h ago
Obviously this wouldn't be suitable for (serious) production deployments, but it is a super accessible way to easily get started anywhere.
It all looked nice in theory, but one thing shadow DOM makes worse is A11y, because element ids are now scoped and all the missing describe-by, label-for for things that should link to other side of the fence are a massive pain in the ass.
Big part of it is just skill issue on our part of course.
https://github.com/gitaarik/lit-state
I've used it extensively myself, for creating complex web apps with many (nested) components interacting with each other.
I don't understand why Lit hasn't gained more popularity, because for me it is basically React, but then more browser-native, much less boiler plate, and much faster rendering. There are some things you have to get used to, but when you do it doesn't limit you in any way.
Not sure why Lit showed up on the front page tonight :)
I use it in almost all my personal websites. And when I don't use it, I end up reinventing half of it and realize I should have used it from the start. This command is in most of my projects:
I've never felt I'm using a framework or anything that deviates from Vanilla JS and valid HTML, which is why using it hardly causes any more cognitive load than using regular string templates and JavaScript functions. Which is something that I can't say about other frontend tools.Another thing I like from Lit is that with the CDN bundle, it's straightforward to experiment and use all the features without needing a build step.
I'm sold and build all my work and personal apps with it and have for many years. I wrote this article about why in 2022:
Getting Started with Web Components & Lit
https://medium.com/gitconnected/getting-started-with-web-com...
Sometimes, I am wondering why it is not more widely used ...
Apps are well served because they have more control about how components are used: they can import the same shared styles into every component, take are to not double-register elements, etc.
But I think there are some important standards still missing that would open things up even more in the design system and standalone components side:
- Scoped custom element registries. This moves away from a single global namespace of tag names. Seems like it's about to ship in Safari. Chrome next.
- Open styleable shadow roots. Would allow page styles to flow into shadow roots. This would make building components for use with existing stylesheets easier.
- CSS Modules. Import CSS into JS. Shipping in Chrome. About to land in Firefox.
- ARIA reference target: make idref-based reference work across shadow roots
CSS Modules has an established meaning for over a decade, one that is still relevant today. The CSS type imports are very different, and arguably worse.
Call them CSSStyleSheet imports of you need a name suggestion.
What people using web components want is to get rid of shadowDOM and not feel like they are deviating from the correct path. shadowDOM sucks, stop trying to convince the world that we are using it wrong. shadowDOM is the whole reason web components did not become mainstream (yet?).
It's also possible to import shared CSS in a base class and add it with super.styles() so you don't lose anything.
Seems like this feature was removed from Chrome.
See https://caniuse.com/mdn-javascript_statements_import_import_...
Or with opinions like this: https://dev.to/ryansolid/web-components-are-not-the-future-4...
O if you want to go down the technical rabbit hole, you can search for all the issues people have with them, e.g.: https://x.com/Rich_Harris/status/1841467510194843982
Web components are nice because they're browser-native, but they don't support reactivity, which in hindisight, is a massive oversight, issue, whatever you want to call it - it's hindered adoption.
Lit is nice because there's a very straightforward progression from web components.
There is a proposal in TC39 for native signals, which I think would make a huge dent towards library-less reactivity.
I'm also working on a proposal for native reactive templating which would more-or-less obsolete lit-html. I wrote about the idea some on my blog:
- The time is right for a DOM templating API https://justinfagnani.com/2025/06/26/the-time-is-right-for-a...
- What should a native DOM templating API look like? https://justinfagnani.com/2025/06/30/what-should-a-dom-templ...
> There is a proposal in TC39 for native signals,
Which originated (or the modern versions of signals originated) in Solid, not in Lit.
Let me quote the readme: https://github.com/tc39/proposal-signals
--- start quote ---
The current draft is based on design input from the authors/maintainers of Angular, Bubble, Ember, FAST, MobX, Preact, Qwik, RxJS, Solid, Starbeam, Svelte, Vue, Wiz, and more…
-- end quote ---
Can I reassign name in the example by using document.querySelector?
I can't find clear information about how re-rendering and stateful third-party components interact.
Let's say I have a stateful data table web component that I use in the template. Is it going to be re-created every time the template is re-rendered (loosing its internal state)?
Elements are kept stable as long as the template containing them is rendered.
The template docs try to get this across by saying that Lit "re-render only the parts of template that have changed." Maybe that needs more detail.
There are details here: https://github.com/lit/lit/blob/main/dev-docs/design/how-lit...
HTTP/3, import maps, and HTML preloads can make unbundled app deployment almost reasonable in some cases. You'd still miss out on minification and better compression form a bundle. Shared compression dictionaries will make this better though.
https://benoitessiambre.com/vanilla.html
Part of using web components, for me, is that it is just javascript. There is no upgrades or deprecations to think about. Of course those things still exist on the server though, but it is easier to maintain it there.
Native web component APIs don't have the DX that many people expect though, because they are so low-level. Lit provides just that declarative reactivity on top.
In comparison, Angular is a monster, and React is designed for the old browser capabilities, and is now staying around by inertia, not by inherent quality.
Its .html temples were shipped unmodified directly to the client (yes, including comments). Except they weren't actually html, and sometimes the browser would try to clean them up, breaking the template.
Reactivity was achieved through all kinds of weird mechanisms (eg monkey-patching arrays to watch for mutations). It would frequently resort to polling on every tick or break completely.
DI used TypeScripts experimental decorators, even long after it was clear that it would never become stable.
On the other hand, templates weren't type checked.
Its .html temples were shipped unmodified directly to the client. Except they weren't actually html, and sometimes the browser would try to clean them up, breaking the template.
Reactivity was achieved through all kinds of weird mechanisms (eg monkey-patching arrays to watch for mutations). It would frequently resort to polling on every tick or break completely.
DI used TypeScripts experimental decorators, even long after it was clear that it would never become stable.
On the other hand, templates weren't type checked.
Funny you should say that when the current advise for web components is to avoid Shadow DOM (almost like the plague)
> no web components
As in?
> no template strings
Why would React need template strings? React is not the only framework that doesn't use template strings for anything (Vue, Solid, Svelte come immediately to mind). And it's hard to accuse those of being behind the times when Solid is literally the reason for the upcoming native signals proposal
What would be the benefit of rebuilding these components in Lit over using Vue to build them?
https://vuejs.org/guide/extras/web-components#building-custo...
* Built-in state management especially as in v3 (ref/reactive) is super powerful, and you can test the setup function logic by itself without any dependency on DOM which is convenient. By comparison, reactivity in Lit is basic (by design), and mostly work on the widget level -- if something changes, you need to trigger the update process of the widget.
* The lifecycle is also a bit simpler. In Lit, you often need to work with lifecycle callbacks like firstUpdated, connected, shouldUpdate, updated, disconnected etc. (You don't need to implement these for simpler widgets, but often you have to.) You can easily run into bugs if you are not careful, especially in the less common situation where your widget can be both temporarily and permanently removed from the DOM, in which case you need to make sure the state of the widget is properly perserved, which isn't a thing you need to worry about in Vue. We got bitten by this multiple times.
Unless there is a strong technical reason, I suggest that you focus on shipping features instead of changing your tech stack. Rebuilding your widgets is a very time consuming task with, well, near 0 impact on the user.
Vue is more of a "framework" solution and has more things built-in. You can do the same things with Lit, but the implementation would look different, because you'd lean more on native APIs. A good example of that is the event model, Vue has some event model built in, but with Lit you would use EventTarget.dispatchEvent().
Lit is a runtime solution, it doesn't require a build and you can load your source directly in the browser. Vue on the other hand requires some form of compiler stage to produce something your browser can use. Compilers these days are fast, and Lit is specifically engineered to not have runtime performance overhead, so in practice this difference is rather minor. It is a very fundamental difference, so I think it's worth pointing out.
Vue can compile to other targets. If you are only delivering Web Components, this is mostly irrelevant, but in theory a consumer might be able to use the Vue components directly in their Vue project, which might give them a better DX. On the other hand, Lit is specifically designed to produce Web Components, so you'll probably have a bit less friction compares to using Vue, e.g when some Vue concept doesn't compile cleanly to Web Components.
Is there a major benefit to choosing one implementation over the other? I don't think so, unless you have a very particular requirement that one of them addresses that the other doesn't. For nearly all cases, it is just a different implementation syntax.
In most cases the only relevant metric in deciding between them is what technology your developers are more familiar/comfortable with.
I shipped a project with Lit and I liked it, but I didn't like that I'd need to know the complete project scope up front that I could write everything from the ground up. I know I could use React component for some of the harder stuff but at that point might as well use React and avoid bundling two systems
I have actually wrote a few web components by hand in an environment where I didn't want any external dependencies and when that requirement was dropped I really liked how easy was to convert them to LitElement (and how much nicer it is to work with them).
I also have embraced the shadow DOM which is a default, but I think it's more trouble than it's worth. Now I use LitElement without shadow DOM and it works great as well.
No comments yet
Really love the abstraction that makes web components easy to use.
My editor: https://needcoolershoes.com
We use them to make fields reactive mostly, and I love how declarative they are. But we use them sparingly. I personally don't love how some libraries try to put a lot of things into decorators that could have been standard class features, like a static field or a method.
edit: As mentioned by skrebbel, decorators are optional. Every decorator has a simple plain-JS way of doing it. Event reactive properties: https://lit.dev/docs/components/properties/#declaring-proper...
We also put a lot of effort into making all of our documentation and playground samples on lit.dev available in both JavaScript and TypeScript with decorators. There's a switch that will change everything on the site from JS to TS globally.
I can think about few other ways, such as using higher order functions/classes, using getOwnPropertyDescriptor or doing stuff at construction.
> As mentioned by skrebbel, decorators are optional
This is not a pro, it's a con. The more ways there are to achieve the same result the more inconsistent projects become IRL.
Also, do you really want to metaprogram at all? What's the huge benefit of that approach?
Class fields aren't on the prototype. They're essentially Object.defineProperty() calls that occur right after the super() call of a constructor. You can't get at them at all from the class declaration.
I know more than one way to do something is sometimes a downside, but we have a large audience an a huge portion of it wants to use TypeScript and declarators, and another huge portion of it wants to use vanilla JavaScript. We factored things to give the best DX we could to each group with relatively little cost to us.
As for why metaprogramming, we want a component to update when it's state is changed. Like plain web components, Lit uses classes.
So here, we want setting `el.name` to cause the component to re-render:
We do that by replacing `name` with a getter/setter pair where the setter schedules an update of the instance. Without decorators, there's no way to see that `name` even exists, much less replace it.Decorators actually do the replacement for us, we just have to build the thing to replace it with:
No, they are not. Decorators don't even exist in JavaScript. Stop assuming typescript is Javascript or even worse, that everybody is on board.
> There's a switch that will change everything on the site from JS to TS globally.
Lol.
The Lit authors tried hard to use vanilla JS everywhere they could, and it shows.
[0] https://bugzilla.mozilla.org/show_bug.cgi?id=1781212
[1] https://issues.chromium.org/issues/42202709
I think lit should distance itself from that mess if possible
Typescript has JSX built in so when "I made my own framework" I just used that.
https://lit.dev/articles/lit-cheat-sheet/
- Custom HTML-like syntax
- Custom Javascript rules - Custom rules for special functions. - Context https://lit.dev/docs/data/context/- Experimental compiler: https://github.com/lit/lit/tree/main/packages/labs/compiler#...
Yes, Lit templates give some special meaning to attribute names with a few prefixes. No, it's not "HTML-like". It's valid HTML. Not that it matters much. You bring this up all the time but I'm not sure what the actual criticism is. Developers seem to understand the small syntax carve-out just fine.
No, there are no custom JavaScript rules. Templates have some rules. I'm not sure why they wouldn't? In general you can't make things like tag and attribute names dynamic because you can't change them in HTML. You can actually write the template you show with what we call static templates though.
`classMap()` is a template directive. It has some rules about how it's used in templates, just like other JS functions can have rules about how their used. I'm not sure what makes that not a function.
But to your main point: Lit is not like React because it's not a framework. Lit helps you make custom elements - it's an implementation detail of some web components. Everything else about those elements: how you instantiate them, style them, where they work, etc., is all defined by the HTML and DOM standards. React is a framework, and defines its own rules about how its components work.
I love that I get to choose how everything works. I have custom systems for routing, styling, signals, API interactions. I control who gets passed what and when. It makes the app feel light, responsive, and -- most importantly, it fits in my head and I understand how it's put together because I chose it, not because I learned it from someone.
Yes, yes I do. Because Web Components are almost 15 years now, and they still struggle with the most basic of things. How's that abandoned roadmap going? https://w3c.github.io/webcomponents-cg/2022.html
> No, there are no custom JavaScript rules. Templates have some rules.
That is "here are regular JS functions. However, you cannot use them as regular JS functions in these specific contexts". Reminds me of certain very specific rules about specific functions in specific contexts in some other framework. Can't put my finger on it.
> I'm not sure what makes that not a function.
I never said it doesn't make it a function.
> But to your main point: Lit is not like React because it's not a framework.
Yeah, React wasn't a framework either, but just a library. Everything about DOM elements that React produces, how you instantiate them, style them, where they work etc. is all defined by the HTML and DOM standards.
But then React grew in the number of features, and can no longer be called a library even though still the only thing it does is output some DOM nodes.
I guess you'll insist on Lit being "just a library" even after it adds a ton of other functionality all other frameworks already have or are moving towards.
> I'm not sure what the actual criticism is
The criticism is usual: Lit is rapidly absorbing all the features from all the other frameworks and becoming a framework itself while many of its developers and proponents can't stop shitting all over other frameworks.
If I understand correctly, your criticism is that the people for whom Web Components is a good fit are publicly discussing the reasons why they prefer it over other solutions?
The main problem is that for a "niche technology" it sure infects too many standards, requires an insane amount of new standards and makes supporting things needlessly complicated.
A few links here: https://news.ycombinator.com/item?id=45114450
There are some good parts in the ~30 standards they require, but instead of just the good parts you get the whole horse, and the cart it's attached to, and the cargo in the cart.
> your criticism is that the people for whom Web Components is a good fit are publicly discussing the reasons why they prefer it over other solutions?
It's not.
I do wonder, why are you on this crusade? Are you afraid that people are at some point gonna be persuaded by Lit / Web Components, and that you need to be there to prevent that from happening?
Looking at the first example:
First I had to switch it from TS to JS. As I don't consider something that needs compilation before it runs to be lightweight.
Then, the first line is:
What is this? This is not a valid import. At least not in the browser. Is the example something that you have to compile on the server to make it run in the browser?And when I use the "download" button on the playground version of the first example, I get a "package.json" which defines dependencies. That is also certainly not something a browser can handle.
So do I assume correctly that I need to set up a webserver, a dependency manager, and a serverside runtime to use these "light weight" components?
Or am I missing something? What would be the minimal amount of steps to save the example and actually have it run in the browser?
https://unpkg.com/lit@3.3.1/index.js?module
You can even dynamically import that in the a running browser console and use it directly on any webpage.
https://plnkr.co/edit/2y9JEOgSZLpO4bE7
That isn't a criticism of projects that don't use npm, and it doesn't make them less valid, but it makes sense for the documentation to match the average developer's experience.
https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/...
Overall, the example does not seem like something that is supposed to run directly in the browser without some kind of intermediate step.
That is why I asked what the minimal number of steps would be to download the example and have it work locally.