I like the idea of Lit a lot, but every time I’ve tried to use it, it feels kind of unclear what the intended way of using it actually is. Like, what an actual code base that uses it heavily would look like. All of their example code seems to have no context around it at all, so it’s really difficult to infer from that how to actually make anything useful, or even how to get started. I hope they sort that out at some point.
There are lots of open-source design systems built with Lit. Shoelace is a popular component set that you might check out: https://github.com/shoelace-style/shoelace There are many others...
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.
Honestly you can organize it however you like, it’s just an easier way to define native web components.
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.
I haven’t used Lit, but I’ve had my eye on it for some time as a potential good fit for some project ideas. One of the things I like is that it seems to be strongly in the “use the platform” camp, while still adding clear value (and ecosystem, which IMO is a tough charge for anything in the space not named React). For a semver major release, this one seems compelling if mundane (that’s a good thing!). But that’s just my observation as a current spectator. Looking forward to reactions from actual Lit users.
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.
If you visit Reddit without logging in, you will see the new lit-based UI. It is lighter and faster — but then, Reddit hasn't yet pooped all over it with ads.
They also have the Google logo there claiming it's used for "many projects" - but nothing linked. Google has several in-house-built web frameworks, so this is questionable.
There are thousands of Lit elements in google's internal repo, and new products are launching with Lit regularly. One of the recent ones I really like is Google Maps' API built on Lit and web components. Makes it super easy to drop a map into a page: https://developers.google.com/maps/documentation/javascript/...
Lit was originally written by a group of engineers at Google, and most of the main team is still at Google working on Lit either full time or part time, though there's increasing contributions and governance from outside Google.
Pretty much 100% of my greenfield frontend development is using lit-html, and has been since they originally launched it.
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.
That's interesting. I guess you miss out on batched rendering--if all your setters re-render, you might trigger multiple renders for a single logical update. If you're using signals, maybe you don't care as much about batched rendering. I would probably miss CSS selectors too.
I'm a backend developer, so pardon my ignorance. I'm reading here that this basically a thin wrapper on top of the Web Components standards, which I've been reading about for nearly 15 years now. So this makes me wonder... why does basically no one ever write directly to the Web Components standard?
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?
Probably just due the network effect of React coming to the scene first, and the cost of change.
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.
Speaking as a front end developer with 4 years experience using Lit -
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.
This is definitely the dream of the Lit team, that Lit itself gets smaller and smaller as the platform gets more capable. For example, the DOM Parts proposed spec would let us drop a lot of the most complicated code in lit-html.
Lit is not a polyfill, it's an easier way to write Web Components without writing DOM manipulations manually.
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.
This in itself is why web components have had such a hard time actually taking off as a viable platform to build on. You need some other library to handle the things you actually need to accomplish.
That's how open standards work. Create a common ground so every tool built on top of it can be integrated. So Lit integrates with other web components frameworks. Imagine if React, Vue and Angular could be integrated? That's the change that Web Components brings. And currently Lit is a great choice to create components that can be integrated with those frameworks.
All of them allow Lit components. Almost all frameworks support them, because they are just standard web components underneath. The only way they wouldn't work is if the framework did something actively stupid to break web components.
> why does basically no one ever write directly to the Web Components standard?
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.
I'm not sure what you're talking about, but DOM rendering systems aren't really part of the web components suite of standards right now. That's left to userland and there are a few web components libraries that do use VDOM for rendering.
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.
Imagine if a big OS vendor like Apple decided that people were not "using the platform" correctly by building on top of third-party database libraries instead of using the filesystem directly.
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.
Web components are just a natural fit for the web platform, which has grown into a general GUI platform and deserves a built-in component model. No other GUI platforms lack a standard way of building components.
Few years ago I started working on a project and didn't want any heavy framework. I used customElements and liked it.
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.
Overall I'm not super happy with web components to solve the issues of reusability, conciseness, and self-containment.
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.)
Shadow DOM is what enables interoperable composition. Without it you don't get <slot>s and without that you can't put children into a component without some very ad-hoc hacks.
Yeah - I've been writing native web component applications for many years now, and I have never, not a single time, needed slots.
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.
We're trying to advocate for greater flexibility in cross-component styling. One proposal is "open styleable shadow-roots" which would be an opt-in to let styles from above a component to apply to it's shadow root. I think this would help migration in situations where app teams are currently using global stylesheets.
I think it's interesting how JavaScript has gone full circle on classes. At one point a decade or so ago, classes became vilified as substandard syntactic sugar on functions. That combined with a surging interest in pure functional programming lead to devs using functions for everything and libraries like underscore to assist. Just five years ago, React added hooks as a way to avoid classes all together.
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.
I like a lot of the concepts of FP, but once you get past the "new shiny" aspect of it and start writing applications, the warts start to show.
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).
Interesting how they say that compiled templates are ~21% faster to update, I wonder why. In theory pretty much anything that they could be doing at compile time could just be done at runtime, since they are building on top of tagged template literals, which enable this, so I guess there were some optimizations missing for that in v2? I'd be interesting if anybody knows what was missing.
I ran that benchmark and can let you know what's going on. The benchmark switches templates using conditionals.
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.
I'll preface with saying I'm not too familiar with the technology, but I don't really get web components, everything I've seen online says they're a bad API and abstraction. Does Lit fix those issues? Genuinely curious as I haven't used Lit or WC before, I've been mainly working with React.
The first link complains about databinding a bit. Not a lit expert, but this seems to help with that:
> 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.
Web components are just custom html elements, with the option of an added shadowDOM. Oh, and slots. But that’s it. If you’ve got an interface component that you find yourself using over and over - like say a complicated multi select drop down type thing - maybe you just make it a custom element, define a custom class that controls it, and drop instances of it throughout your site, the same as you’d drop default <select>s.
I used Lit 2 in a complex client project once, which was tough to work on, not because of Lit, but because of Web Component composition. I would not choose Web Components for a new project with component composition again. The Shadow DOM makes many things harder than I was used to when building with a JavaScript library like React or Vue.
For framework independent individual components (e.g. a video player component), Lit is excellent.
As an alternative, check out Stencil.js. If you are componentizing within a controlled environment, then the shadow DOM feels like an unnecessary complexity. If the style collisions are a concern, you can turn on Stencil's scoped styling which dynamically creates unique css classes. It also has popular framework bindings so that you can output your components to work with different frameworks along with native web components.
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.
Adding decorators to JS is a mistake but thats just my opinion.
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.
Metaprogramming can be applied in ways that makes code hard to reason about, but that doesn't mean all metaprogramming is that way.
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.
I mean couldn’t lit have just exposed a method like this.setReactiveProperty that calls this.requestUpdate and sets the property? The need for decorators seems because the api was designed to use decorators not because they are particularly necessary for this sort of thing
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.
There's one thing that I haven't figured out about custom web components which make them completely broken for me: using them as form elements with good DX and UX.
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.
I think a lot of that is pushed down to the design system/library implementations.
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.
A bit disappointed that Lit SSR is still considered experimental.
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.
I've been a front-end engineer for over a decade and I still struggle to understand the value of SSR as a feature of front-end frameworks.
- 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.
I just wanted to point out here because the distinction is kind of important.
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.
SSR is useless and a waste of money. But VC money is gone and the tools maintainers need the users to waste money on their cloud so that is the direction they are pushing. Lit is so simple that it can't become a VC-backed project (I hope).
We're working on it. It's a bigger challenge for us because part of the reason people use Lit is for interoperable components, so our SSR solution can't be a silo: it needs to integrate with other framework's SSR systems.
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.
If you can give a solid SSR solution specifically built for Lit, it would still be good because many want a solution which is cloud provider agnostic and are willing to switch to whatever works anywhere.
If only Google were as committed to its products as they are to the insanely over engineered proposals that fail to solve any legitimately useful use cases. Half of why these projects exist is for internal gate keepers at Google to make excuses for why they're not allowing productive engineers to adopt React/Vue, etc.
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.
This is, uh, a pretty confused set of things to say. Shadow DOM is implemented in every browser. Now that we've dropped IE11, Lit doesn't need any polyfills in any of our supported browsers.
Lit is javascript, and would greatly benefit from Google's internal stack having better support for NodeJS.
Fair, removed that part -- I remember something about Shadow DOM got delayed or had a lot of push back, back in the day -- and I thought it was dead in the water when I started seeing Shady DOM stuff internally. But regardless, I've never had a single use for it working on SaaS products.
Lit's been around, starting as lit-html and lit-element, since 2017. Chrome, Firefox, Photoshop, Reddit, and more are built with it, so it's definitely not a library of the week, it just has less hype than others.
That's the opposite of my impression using Lit for the past 6 months. A thriving community, well-maintained packages and libraries, old content most of the times works the same and it won't change after 3.0 release because the API didn't change. Besides that, the code keeps getting smaller so with a reduced interface it becomes easier to reason about.
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).
Lit has not really changed direction or how things are done. In the release presentation today the exact same code was shown that runs in lit-element, Lit 2 and Lit 3.
What was hot in the previous weeks, each week? You seem to be informed (I'm mostly focused on backend tech) so I'm curious if you could share each week of the year and what JS tools were hot for each one?