Lit 3.0
lit.dev
lit.dev
Would it help if we listed more open source projects on our site?
Because of our focus on components and the fact that you really can use just about any libraries and scaffolding for apps, we don't really have an app starter kit, but it's something we've talked about.
I think the starter kit would be beneficial, just a way of laying out how the pieces fit together.
Picture angular, or vue, or react - only with native web components and the shadow dom, instead of a vdom. You can use whatever routing you like, use whataver state management you like. Lit just helps you make web components.
Lit: Simple, fast web components - https://news.ycombinator.com/item?id=36806747 - July 2023 (141 comments)
Also related:
Lit 3.0 Pre-Releases - https://news.ycombinator.com/item?id=36097790 - May 2023 (2 comments)
Offical Lit team’s guide to building your first Lit Web Component - https://news.ycombinator.com/item?id=31169173 - April 2022 (1 comment)
Lit is a simple library for building fast, lightweight web components - https://news.ycombinator.com/item?id=27980807 - July 2021 (1 comment)
Lit – Simple. Fast. Web Components - https://news.ycombinator.com/item?id=26891866 - April 2021 (2 comments)
WebComponent libraries lit-HTML and litElement released - https://news.ycombinator.com/item?id=19089360 - Feb 2019 (18 comments)
Something that caught my attention is that, in their homepage (https://lit.dev), the list of organizations using Lit actually specifies where it is being used in each organization and even provides some links.
In other projects it's not rare to see just the organization logos.
Maybe I'm wrong here.
Note: I don't use Lit/LitElement, I just use lit-html with vanilla web components.
I don't find a lot of value in the more complex "component" model/wrapper around native web components, though YMMV.
My components are very simple native light-dom web components that have a render() method that calls lit-html render. For reactivity, I just use class properties. On a setter that needs to mutate the dom, I just call render manually.
It's not really any extra lines of code at the end of the day, and it gives me full control over the lifecycle and render cycle of my components. It's also super easy to debug.
I've used different routers over the years, currently I'm using Vaadin, but I've used Ionic's and others. I may try out the new router that's in Lit/labs.
I'm very satisfied with it. No framework churn, no complex builds, easy debugging, lighting fast performance, minuscule js downloads, easy authoring and vscode has magical tooling support.
lit-html is one of my all time favorite pieces of tech.
I will sometimes do a little trickery in my setters to prevent pointless server round-trips though.
The general rule of thumb with lit-html is "meh, just render. It's just a template clone, and pretty much free".
There's no need to miss css selectors, they work just fine. That's the advantage of avoiding shadow dom.
There are really only two major web browser engines left in existence (three if you are extremely generous and still include Firefox). Are there really enough differences in Chrome and Safari's implementation of Web Components to still require a polyfill after all these years?
The original polyfill was Polymer, and I believe that both it and this Lit library are both Google projects. If so, then what is the delta between the two? It looks like Polymer is now in maintenance mode, so clearly Lit is the successor. But are there fundamental changes beyond a branding refresh?
I've used Web Components nearly exclusively at multiple jobs for 7 years now, so my experience is that they are out there and in use.
Had to start using React recently for a job and it feels like a mess in comparison. Too many ways to do things, big black box components that are hard to introspect, compilation is not optional, and poor documentation on some aspects due to not using standards. I'm still struggling to understand "stale closures" and the react component life cycle. It seems to have a lot of baggage.
Building on top of the Web Components standards, Lit adds just what you need to be happy and productive: reactivity, declarative templates and a handful of thoughtful features to reduce boilerplate and make your job easier.
It’s like using jQuery in the mid 2000s - it’s not like it allows you to do anything you couldn’t normally with vanilla JavaScript, it just provides some shortcuts for common scenarios. The process of defining the class that controls a custom html element is a bit of a slog in vanilla JS - in Lit, especially with Typescript decorators in play, it’s a breeze. It saves time and helps keep things fairly DRY.
I should think the dream is that Lit, like jQuery, will slowly get absorbed into the web components spec itself, until all the things you used to need to reach for a library to do efficiently - will simply be a part of the vanilla language itself. Like jQuery’s css selector functionality has now been superseded by JS’s querySelector.
So they introduced "File System Tables" which was their vendor-blessed replacement for databases, but it did a bunch of things really differently from SQL databases for no clear reason, and forced you to think about things like file locking and write durability that you were actually pretty happy to let a DBMS take care of for you.
People designing WC think vdom is a pointless overhead, and React is a fad that will have to switch to Web Components eventually.
Now, as a Lit maintainer I do think that VDOM is a lot of unnecessary overhead, and the benchmarks show that, but rendering libraries and web components are orthogonal things.
Web components provide a life cycle (mounted, unmounted, attribute changed) and an encapsulation mechanism; but they aren't reactive. They don't rerender when you change an attribute or a property. They don't have a concept of local state, whose changes would result in a rerender. Html templates don't have a convenient syntax for binding properties or events. Lit adds all this convenience, with very little code. The result is that the web components that it produces remain standard and interoperable, but are also much more pleasant to author than plain components.
When the project grew enough, I found out about Lit and it was a clear winner for me. I've ported my custom elements to Lit with ease, it's a pleasure to work with.
Well done Lit team.
The most direct problem is styling issues. Cross-component CSS in either direction has some serious limitations. I've written a little bit about it[1] in my blog but the short version is that there are some things that simply become absolutely impossible when using web components.
My main other gripe with them is the need for a build phase. The nature of WC almost begs for them to eventually become zero-build-time, but right now this just isn't practical. It requires too much boilerplate in every .html file (utf8 is broken on my site), the syntax isn't natively there even with tagged template literals, and there's no concept of data-list-fetching or data-based file generation.
There's a branch on my personal website[2] where I tried to start using web components, and it was so problematic that I long abandoned it.
Overall, I abandoned web components entirely in favor of making my own customized JSX-based SSG from scratch[3] which solves the same problems Lit, Next.js, et al. are intended to solve, but in a completely different way: using components for convenience, conciseness, and reusability, but only at the build-phase time. So far it's a well kept secret, which is probably good since it's been evolving so quickly that I wouldn't have been happy with any iteration being widely adopted so far. (Though I think this morning I finished off most of what I was unhappy with.)
[1]: https://sdegutis.github.io/articles/2023-08-07-modern-90s-we...
[2]: https://github.com/sdegutis/immaculatalibrary.com/tree/reset...
IMHO shadow dom isn't really useful for application authoring, it's beneficial for library authors and such.
Web Components become a lot easier if you just stick with the light dom.
I have WC scenes, which are top level components that are able to be accessed by a url/deep linking/router outlet.
Scenes are built from html and css that lay out smaller components - sometimes WCs, sometimes vanilla html, depending on what makes sense.
Components mostly take care of themselves, load the data they need, and maintain their own state. Unless that doesn't make sense, in which case data is passed to them via properties.
I have hundreds of thousands of lines of high performance, quality production code running this way and again - have never needed a slot.
Slots are mostly useful for library authors, IMHO.
Feedback and support of the need for something like this would help a lot: https://github.com/WICG/webcomponents/issues/909
Now classes have been super-charged in the latest JavaScript proposed standards, with the addition of syntax for private and static variables, getters and setters, accessors, decorators and more. All of which are either in engines already, soon will be, or adopted by TypeScript or other precompilers.
I think it's interesting because TC39 decorators which Lit is now using aren't usable with functions yet, only classes and class methods. The standards groups seem to be at odds with the general JavaScript community consensus on dev patterns. But with classes becoming so much more central to how JS is structured, I guess we're going to see a lot more class-centric JavaScript. Which is OK, I guess. I just hope it doesn't turn into Java.
It's really like anything - extreme/purist FP can have terrible application performance with limited benefit. Same with extreme/purist OOP.
JS classes hit a sweet spot for me. They are minimalist, composable, easy to duck-type, and are basically just a convenient unit of code organization more than anything.
I never really jumped on the "pure fp" bandwagon. It gave birth to monstrosities like RxJs - which some people actually use, and I don't understand how or why.
Same for me with React - class based components are a lot less magical than all the useEffect and use* stuff. They're easy to reason about, and self-contained. I never really understood the drive for "pure functional components".
There's so much cruft and artifacts that arise from that, it interferes with application feature deliver and performance. You end up spending your days doing crazy Redux or RxJs like things, increase complexity by an order of magnitude, all for very limited actual benefit (like theoretical time rewinding during debugging - which I have never actually had a need for).
So what is happening is:
1. On the first render, every template that is rendered gets prepared. And there is that 46% improvement. 2. On the second render, some code paths change and some new templates that haven't yet been rendered get rendered. This results in a smaller improvement.
Then over time, as different code paths are exercised, the improvements of compilation reduce as every template has been seen at least once.
The Failed Promise of Web Components: https://news.ycombinator.com/item?id=24640151
Why I don't use web components: https://news.ycombinator.com/item?id=20232628
> Lit’s expressive, declarative templates (utilizing JavaScript tagged template literals) make it easy to describe how a component should be rendered.
> Reactive properties represent a component’s public API and/or internal state; your component automatically re-renders whenever a reactive property changes.
Also, good question, I would like to see more discussion here vs. downvote without comment.
I admittedly haven't done any searching yet, but figured someone may have written one or have experiences switching.
However, if you are wanting to share your components with the world, starting with fresher code, and/or have the resources to tackle the shadow DOM gotchas then I would consider Lit over Stencil.
Just dropping this out here for those in the research phase as it wasn't super clear to me at first which way to go. Both are really good options but better for certain situations.
We support a non-decorator API (the static properties block), but I don't think it's particularly ergonomic compared to decorators which allow us to declarative modify standard class fields.
Decorators work better with type systems, which don't have to be taught about our bespoke property declaration convention, and they're coming natively to JS so they won't require compilers.
I don’t like them because they make it more difficult for me to understand what is actually happening when you run the code that is decorated. I have to go and read the decorator source and then it’s some metaprogramming nonsense instead of something more straightforward.
It’s very possible i’m just a curmudgeon but I still find it off putting and is one of the reasons i haven’t really experimented with lit more than vaguely paying attention to it.
Decorators, especially the newly standardized decorators, provide a structured for of metadata where the possible actions are limited. Decorators can basically only replace the decorated class member with another member of the same kind: replace an accessor, or a method.
This should make things easier to reason about. The Lit @property() decorator for instance wraps the decorated setter with one that calls `this.requestUpdate()` - that's it.
The alternative is writing all the boilerplat by hand, which most users don't want to do (but is possible) or the adhoc metaprogramming systems that are fairly popular now, and I think those are much harder to reason about.
Lots of frameworks already have the ability to set properties on elements declaratively in templates. By using setters we work with their data binding system without hanging to teach them about Lit-specific APIs.
For example custom button that should behave like native html button - submit form on click, submit form on enter if I am in one of the text inputs, correctly handling "form" attribute when the button is outside of the form itself etc.
I know about "formAssociated" and "ElementInternals" but they don't solve the problem completely.
Imho this isn't solved anywhere and makes the web components no-go for design systems. https://github.com/WICG/webcomponents/issues/814
I also find baffling that there is _zero_ information about forms in the Lit3.0 documentation.
If someone figured this out please enlighten me.
Example: https://lit.dev/playground/#project=W3sibmFtZSI6InNpbXBsZS1n...
I use Web Components as a lightweight wrapper around that stuff.
For example, if I'm using bootstrap I generally have a Web Component that uses all the boostrap styling in the light dom and have a "scene" or "modal" or whatever component that just has regular HTML rendered by lit-html.
The component contains all the functionality for the form - fetching data, filling dropdown lists, validating, submitting, etc... so in that case, the web component isn't at the button level, it's at the logical application feature/form level.
There are plenty of design systems that'll do what you're talking about though, Ionic is probably the most popular, but there's shoelace and a bunch of others that wrap and enhance form element functionality.
Most frontend frameworks/libs are (understandbly) still in their boring client-side bubble but actual full stack solutions like Phoenix Liveviews or Laravel Livewire are so much more interesting IMO.
That's why we're working on packages like @lit-labs/ssr-react and @lit-labs/nextjs. SSR is in Labs still because it's APIs may need to change to support those integrations.
An alternative is using this solution but it doesn't inspire a lot of confidence for any serious project.
- Websites that care about SEO rarely need front-end frameworks. - Web apps that need front-end frameworks tend to be behind a login screen or used for creating documents rather than publishing them. - SSR strategies sometimes render loading states through `</html>` and then tack on additional JavaScript streamed at the end for fully-loaded state, removing any NoScript benefit you might hope to get.
https://developers.google.com/search/docs/appearance/core-we...
The simple truth is server rendered or static HTML will always result in better CWV than CSR with an API.
There are still a lot of things that are popular in the CSR space that are just based on some very weird architectural choices that do typically lead to worse CWV metrics, worse accessibility etc. Looking at you NextJS and larger React community in general.
However hitting those CWV metrics using a CSR solution, especially one that is just straight up standard web platform stuff such as Lit is not going to be a problem at all and you aren’t somehow improving your SEO simply because you rendered it on the server.
I think there is a misconception here that the CWV metrics are processed in a numerical fashion like 0.2s for LCP is better than 0.3s but there is literally not a single shred of evidence for that nor does it even make sense.
Those metrics are bucketed into 3 categories of good, needs improvement and poor intentionally.
These weird quasi-frameworks exist in large part due to production use of NodeJS being banned at Google. What you get with Google OSS is a weird backwash, digesting external technical direction in a way that caters to internal consumers. They then flop it onto the ground on Hacker News.
Why would I use this? There's a million reasons not to, and then there's having a safe cushy jobs and priorities that have nothing to do with the core business.
Bleh.
Lit is javascript, and would greatly benefit from Google's internal stack having better support for NodeJS.
x - hot JS library of the week, substitute with Angular/React/Vue/Shoelace/Vite/Lit/... depending on the year and month.
Now compare it to React, Angular and Vue: the 3 of them had a complete change of course at some point and lost a good amount of documentation and ecosystem while having to maintain both for some time. That never happened with Lit (although it seems to have being created by the same team that maintained Polymer).