VOOZH about

URL: https://thenewstack.io/the-pros-and-cons-of-web-components-via-lit-and-shoelace/

⇱ The Pros and Cons of Web Components, Via Lit and Shoelace - The New Stack


TNS
SUBSCRIBE
Join our community of software engineering leaders and aspirational developers. Always stay in-the-know by getting the most important news and exclusive content delivered fresh to your inbox to learn more about at-scale software development.
REQUIRED
It seems that you've previously unsubscribed from our newsletter in the past. Click the button below to open the re-subscribe form in a new tab. When you're done, simply close that tab and continue with this form to complete your subscription.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.
Welcome and thank you for joining The New Stack community!
Please answer a few simple questions to help us deliver the news and resources you are interested in.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Great to meet you!
Tell us a bit about your job so we can cover the topics you find most relevant.
REQUIRED
REQUIRED
REQUIRED
REQUIRED
REQUIRED
Welcome!

We’re so glad you’re here. You can expect all the best TNS content to arrive Monday through Friday to keep you on top of the news and at the top of your game.

What’s next?

Check your inbox for a confirmation email where you can adjust your preferences and even join additional groups.

Follow TNS on your favorite social media networks.

Become a TNS follower on LinkedIn.

Check out the latest featured and trending stories while you wait for your first TNS newsletter.

PREV
1 of 2
NEXT
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
Thanks for your opinion! Subscribe below to get the final results, published exclusively in our TNS Update newsletter:
NEW! Try Stackie AI
From clobbered drafts to real-time sync
Apr 14th 2026 10:00am, by David Moore
TypeScript 6.0 RC arrives as a bridge to a faster future
Mar 14th 2026 9:00am, by Darryl K. Taft
Mastra empowers web devs to build AI agents in TypeScript
Jan 28th 2026 11:00am, by Loraine Lawson
2024-09-29 07:00:38
The Pros and Cons of Web Components, Via Lit and Shoelace
tutorial,
Emerging technologies / Frontend Development

The Pros and Cons of Web Components, Via Lit and Shoelace

If you are working in or leading a larger web implementation team, make sure you understand the possible benefits of a web component library.
Sep 29th, 2024 7:00am by David Eastman
👁 Featued image for: The Pros and Cons of Web Components, Via Lit and Shoelace
While developers enjoy working with components in framework libraries, web components are gaining more interest because they work with HTML and CSS and reduce the need for JavaScript. But they also offer the ability to write custom components, enabling larger internal software estates to keep more control of the look and feel on their pages. After our recent story on Shoelace (soon to be re-named Web Awesome) I thought I would take that library for a spin. Before we look at Shoelace, let’s take a quick look at the level just below it, the Google web component library called Lit.

A Quick Look at Lit

This gives us an idea of how components are constructed. We just want to pick out the basic bits, because this is what Shoelace is built on. We’ll just look at the code through the playground here. All we want to do is make a rating button, which takes a thumbs up (and goes green) or thumbs down (red) and changes the rating accordingly. 👁 Image
You can see that we pull in the JavaScript index.js as a module and use our own defined tag called rating-element. The span defined in style doesn’t affect the component because of the isolation of the shadow DOM. Let’s extract the interesting bits from the code: 👁 Image
You can see the import of Lit, and the definition of the RatingElement class extending a LitElement. At the bottom of the file, you can see the registration of the tag as a custom element based on RatingElement:
customElements.define('rating-element', RatingElement);
There is a render method that basically builds the basic element:
render() { 
 return html` 
 <button 
 class="thumb_down" 
 @click=${() => {this.vote = 'down'}}> 
 <svg xmlns="http://www.w3.org/2000/svg" height="24" viewbox="0 0 24 24" width="24"><path d="..."/></svg> 
 </button> 
 <span class="rating">${this.rating}</span> 
 <button 
 class="thumb_up" 
 @click=${() => {this.vote = 'up'}}> 
 <svg xmlns="http://www.w3.org/2000/svg" height="24" viewbox="0 0 24 24" width="24"><path d="..."/></svg> 
 </button>`; 
}
So, that is quite a bit of code to do something quite simple, but you do get your own reusable component.

Shoelace

Let’s go one layer up and use some Shoelace. Now we get built components. We will install a Shoelace template that uses the rollup bundler and start from there. The bundler helps to resolve components without lazy loading them from the web. This brings us closer to a standard developer workflow. First I clone the rollup example template. That will have the right npm packages we need: 👁 Image
Then we install the packages. You may well need to do an npm update too. 👁 Image
And finally, run the project: 👁 Image
And kick up the page on a different shell tab: 👁 Image
This is what you should see: 👁 Image
So how did we get these components to show? First of all, we state in index.js which components we want to load in the bundle:
import '@shoelace-style/shoelace/dist/themes/light.css'; 
import '@shoelace-style/shoelace/dist/themes/dark.css'; 
import SlButton from '@shoelace-style/shoelace/dist/components/button/button.js'; 
import SlIcon from '@shoelace-style/shoelace/dist/components/icon/icon.js'; 
import SlInput from '@shoelace-style/shoelace/dist/components/input/input.js'; 
import SlRating from '@shoelace-style/shoelace/dist/components/rating/rating.js'; 

import { setBasePath } from '@shoelace-style/shoelace/dist/utilities/base-path.js'; 
// Set the base path to the folder you copied Shoelace's assets to 
setBasePath('/dist/shoelace'); 
// <sl-button>, <sl-icon>, <sl-input>, and <sl-rating> are ready to use!%
So that is where the Shoelace button, input and rating components come from. This leaves the index.html to be very lean:
<!doctype html> 
 <html> 
 <head> 
 <title>Shoelace Rollup Example</title> 
 <link rel="stylesheet" href="dist/bundle.css"> 
 </head> 
 <body> 
 <h1>Shoelace Rollup Example</h1> 
 <sl-button type="primary">Click me</sl-button> 
 <br><br> 
 <sl-input placeholder="Enter some text" style="max-width: 300px;"></sl-input> 
 <br><br> 
 <sl-rating></sl-rating> 
 
 <script src="dist/index.js"></script> 
 </body> 
 </html>
Note that the index.js the HTML refers to is the one unrolled by rollup and placed in the distribution directory. Want a dark theme? Just alter the index.html to:
<html class="sl-theme-dark">
And because we already imported  the dark theme in the index.js: 👁 Image
Finally a little bit of interactivity (don’t forget to refresh your cache between bigger changes). Let’s add a toast-style alert (one that goes to the corner) to the button and give the toast a duration countdown before switching off. We include the alert component to index.js:
...
import SlIcon from '@shoelace-style/shoelace/dist/components/icon/icon.js';
import SlInput from '@shoelace-style/shoelace/dist/components/input/input.js';
import SlRating from '@shoelace-style/shoelace/dist/components/rating/rating.js';
import SlAlert from '@shoelace-style/shoelace/dist/components/alert/alert.js';
...
We place the component in our index.html, replacing the button code:
<div class="alert-duration"> 
 <sl-button variant="primary">Show Alert</sl-button> 
 <sl-alert variant="primary" duration="3000" countdown="rtl" closable> 
 <sl-icon slot="icon" name="info-circle"></sl-icon> 
 This alert will automatically hide itself after three seconds, unless you interact with it. 
 </sl-alert> 
</div>
And some control code back in the index.js, before the end:
const container = document.querySelector('.alert-duration'); 
const button = container.querySelector('sl-button'); 
const alert = container.querySelector('sl-alert'); 
button.addEventListener('click', () => alert.toast());
And the result is already quite impressive: 👁 Image
(What you can’t see is the blue countdown line shrinking at the bottom of the alert)

Conclusion

This is just an introduction to using web components with a library like Shoelace — they need a bit of attention initially, but (like a framework) have a lot of rich content. However, unlike a framework, these are working mainly with HTML and CSS. To make things easier for React users to transition, every Shoelace component can be available to import as a React component. The downside is that SSR (server-side rendering) is still not suitable with web components. And it is true that custom elements are not quite the same as components; the problems that this might cause are fleshed out here. But overall, if you are thinking of working in or leading a larger web implementation team, make sure you understand the possible benefits of a web component library.
TRENDING STORIES
David has been a London-based professional software developer with Oracle Corp. and British Telecom, and a consultant helping teams work in a more agile fashion. He wrote a book on UI design and has been writing technical articles ever since....
Read more from David Eastman
SHARE THIS STORY
TRENDING STORIES
SHARE THIS STORY
TRENDING STORIES
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.
The New Stack does not sell your information or share it with unaffiliated third parties. By continuing, you agree to our Terms of Use and Privacy Policy.