Hacker News new | past | comments | ask | show | jobs | submit login
Shoelace: A Web Component Kit (shoelace.style)
117 points by pyentropy on April 3, 2022 | hide | past | favorite | 48 comments



As someone that's done a lot of webcomponent work, this actually looks really solid compared to a lot of other libraries out there. These docs look great too.

All issues I can see are fairly minor. I'd like to see inputs use the native formAssociated api rather than just relying on hijacking FormData (though using the FormData hijack as a fallback). Component scoped design tokens should be part of the `:host{}` style for that component, not in the global scope. Semantic tokens would also be a better approach for improved themability. The localization is hacky, but I'll give the authors major props for actually pushing a suggestion to the spec[1] to allow for better handling in native components.

Some other minor things I'd like to see is performance comparisons with similar React/Vue/Svelte components as well. Webcomponents can fall into poor performance when there are many occurances that overuse observedAttributes.

All in all though, this library looks really great.

[1] https://github.com/whatwg/html/issues/7039


Have you seen OpenUI5 by SAP? -> https://github.com/SAP/ui5-webcomponents

Look neat. They even have Typescript type definitions to it.

I did a simpile test with ScalablyTyped in order to import those into ScalaJS to no avail but there might be a fix.


The only implementation of OpenUI5 I've encountered as an end-user was "SAP Fiori" for managing expenses at a previous job.

It looks strictly OK if you just glance at it from a distance, but was incredibly buggy across every single browser that I threw at it, and SLOW AS HELL to boot. I'm talking UI elements taking a second or so to respond to actions that don't even interact with anything over the network.

I don't know how much of this is just down to the app itself being poorly designed and built, but just looking at the UI5 components was enough to make me recoil in disgust.


You just made me conscious on my initial choice for an invoices ingest app, so I might end up looking somewhere else: you are totally right, it takes ages to load a moderatively simple layout, not even taking into account a single XHR request.


https://sap.github.io/ui5-webcomponents/

If they are eating their own dog food it needs some work, if this page is any indication


The playground is not that bad: https://sap.github.io/ui5-webcomponents/playground/component... (for instance). But as other commenter pointed out, just take a look how long it takes to load some badges.


I've used shoelace components, overall I've been happy with them.

The only parts I don't like are the event based APIs.

It's 2022, I feel like we've settled on promises as the best way to handle async.

The author wasn't particularly receptive to the issue I raised around it, even offering to create a PR.

I think event based APIs are really holding what would otherwise be a very nice component set back.


Events, promises and callback functions all work differently, exist in their own lanes and can co-exist in the same library. Each one is perfect in the use case it was designed for.

That said, while promises are a very useful tool, I consistently find events to be an easier mental model to work with in the context of the DOM. This is primarily due to the bubbling nature of events.

It's entirely possible that you and your friends concluded in a bubble that promises are the pattern to rule them all, but don't speak for all of us.


You think being event based is holding back a web component library? When the DOM is event based now?


Events are foundational to JS, we've had them since the beginning and they're not broken. You don't need any nonsense to use them. They're also completely unrelated to promises in my opinion, so I'm not even sure what the ecosystem would look like if you tried to replace Events with promises.


do you have code samples of what you mean or the issue?



I miss Shoelace being a CSS library :(

Web components are nice and all but they need JS and I want my sites to work without JS.


As someone who doesn't have a clue about frontend components, but have the desire to build them, how does this compare to https://lit.dev/ ?


Lit is a tool for building web components, this is a collection of common UI components and is actually built using Lit.


Shoelace uses Lit.


Relevant previous discussion from when 2.0 was released a couple of years ago, changing Shoelace from a CSS library to a JavaScript/Web Components/Shadow DOM library: https://news.ycombinator.com/item?id=23866894.

My top-level comment thread there is particularly still relevant and applicable; the mandatory use of Shadow DOM means client-side JavaScript execution is required and server-side rendering impossible, which I don’t think is good for most web stuff.


it's not quite impossible, there are some more "out there" server-side rendering approaches which would work:

- https://github.com/airbnb/hypernova

- https://github.com/prerender/prerender

Fans of efficiency and simplicity might recoil but if it works and is easy to setup, these far out approaches might just catch.


Shoelace depends on Shadow DOM. Shadow DOM is not at this time part of the HTML serialisation. Server-side rendering is thus currently impossible.


Ah, I didn't realize this wasn't solved -- a quick search turns up:

- https://github.com/WICG/webcomponents/issues/788

- https://github.com/w3c/DOM-Parsing/issues/58

- https://github.com/w3ctag/design-reviews/issues/494

- https://web.dev/declarative-shadow-dom

In pre-render they seem to have started in this direction extremely recently:

https://github.com/prerender/prerender/pull/731/files

I don't use prerender so I can't definitively speak to it being solved and hiccup-free, but I think that limitation is going to go away in the future.


Hmm, I see that Chromium shipped their implementation a year ago now; I had missed that. Other than that, there’s been no real change in the situation in the last almost two years (since Shoelace 2.0 was released, the last time I examined the situation). And there still doesn’t look to be any real interest in actually implementing it outside of Google: Mozilla are unenthusiastic though not against it <https://mozilla.github.io/standards-positions/#declarative-s...>, and WebKit still find fault with some aspects of the design (https://lists.webkit.org/pipermail/webkit-dev/2021-February/..., https://github.com/mfreed7/declarative-shadow-dom/issues/9), though they’re content most of the earlier issues (especially performance) are ironed out.

So you certainly can’t rely on scriptless server-side rendering of Shadow DOM being possible—it’ll work in Chromium only, and it’ll probably be at least another year or two before other browsers even contemplate doing anything with it.

(And of course, even once Shadow DOM is serialisable, that’s a far shot from a particular frameworky thing being SSR-compatible, but I was quibbling over the Shadow DOM and impossibility aspects, so I shan’t step back on that.)


Ahh thanks for explaining this, it looks like there's definitely still some work to be done (and as usual even more work until it' something everyone's on board with).

I personally know that I make the choice between client-side rendered (Vue, Svelte, Mithril, Lit, etc) and server-rendered (Nuxt, SvelteKit) these days and I purposely made the choice to use client-side rendered when I was dogfooding my own native web component project. Looks like it's still a choice that has to be made and SSR isn't quite there (everywhere) yet.


The complete and utter failure of the web as a platform is evidenced by the umpteenth framework offering the same set of the most basic components: avatars, badges, radio buttons, selects.

Kudos to Shoelace for including a draggable splitter which is usually missing from other libs.

The web is stuck in the perpetual "reinvent the concept of circle" stage without even moving onto "reinvent the wheel" stage. This "great and new" lib is literally indistinguishable from, say, jQuery UI from almost 20 years ago.


Try to find a treeview. Good luck!


I'm trending in the same direction. It feels like a majority of my time now as a dev is spent working on making sure all the fucking tooling works so stuff compiles properly and doesn't repeatedly break.

The day-today enjoyment of writing code has withered away somewhere.


Shoelace looks awesome, and I think it's libs like these that are the future. People get hung up on the apparent confusion and circular movement of the frontend community but if you look closer you can see the incremental improvement.

Native web components are the endgame for flourishing frontend ecosystem (that many see as mostly waste, and sometimes they're not wrong) -- in the future you'll be to build whole sites writing HTML like:

    <script src="/path/to/some/custom-component"/>

    ...

    <custom-component> ... </custom-component>
That's the future Shoelace is helping bring about and I think it's a really nice minimally, and paradoxically simple way to build webpages that have the functionality you want without the hassle of heavier frameworks, if you're lucky to find just the right component to spice up your page.

I will say that it's hard to execute cleanly on this vision and it looks like Shoelace is doing a pretty good job -- I made a small contribution to this space[0], and I have to say that getting started with my project is much less clean (as far as dogfooding goes it was functional but didn't taste great!).

Looking forward to trying out Shoelace in the future.

One thing I really want to see tackled though (by a standards body) is the data management story. Maybe it's best left to practitioners and library authors but I think something like services-as-DOM-elements[1] (disclaimer: I thought this up) could work. Then we get a world where we can drop pre-made display elements and pre-made data stores onto pages.

Also heavy mention to tailwind -- the class soup bit is annoying but it's sparked an absolute explosion of reusable templates which I think are helping people build better looking sites faster than ever before. Just like with Bootstrap, of course, we're all getting tired of seeing really similar design elements but the acceleration is probably a net good, even if it requires abusing CSS a little bit.

[0]: https://gitlab.com/mrman/landing-gear

[1]: https://mrman.gitlab.io/services-as-dom-elements


> Shoelace looks awesome, and I think it's libs like these that are the future.

They are decidedly not the future. If they were, they wouldn't implement the same primitive components that we were re=implementing twenty years ago.

> Native web components are the endgame for flourishing frontend ecosystem

They are not.

> in the future you'll be to build whole sites writing HTML like

Funny you say that. Because the original vision of Web Component was against quote, "great example of an empty body tag, and sort of this pathological case of piling yourself into the JavaScript boat" [1]

But now it's apparently "pile everything into a Javascript blackbox"

> it's a really nice minimally, and paradoxically simple way to build webpages that have the functionality you want without the hassle of heavier frameworks

It is literally a framework that you still have to tie together with data handling, events etc. Just because you hide it behind a "custom-component" doesn't mean the complexity has gone anywhere.

> One thing I really want to see tackled though (by a standards body) is the data management story.

Ah yes. The data management story.

> Then we get a world where we can drop pre-made display elements and pre-made data stores onto pages.

And how exactly do you propose to "just drop them" onto pages? Have you also perhaps solved the API story for those elements? I mean, isn't it the great lie that web components perpetuate of "just use premade components"?

And yet there are now a few hundred avatar web components, several thousand button components, a million badge components, and all of these primitive things are not compatible with each other.

[1] https://fronteers.nl/congres/2011/sessions/web-components-an...


Not only is this a web page with its own loading screen, it's a web page with a loading screen that shows every time you open the page or click a link on the website.

My browser has a loading bar and your web page is not a video game pulling in hundreds of megs of assets in the background. What could possibly justify this kind of behaviour for a UI toolkit?


I always applaud this behavior when I see it, and it was one of my favorite features of turbolinks when it was still in vogue. Some people are on satellite internet. Some people are still on dialup. Some people are on a tiny sliver of a 3G connection that is dropping in and out as they go in and out of train tunnels. Sometimes gasp the cloud itself gets slow. In all of these situations a progress bar for practically any network action is greatly appreciated. If you are on a fast connection with a fast CPU, you likely won't even see the loading bar. If you need it, you'll probably see it. What is there to complain about? Who wants a blank screen with no information where you end up looking at dev tools to determine whether something is actually loading?


Yes, a progress bar is nice, that's why every browser has a progress bar built in. Both determinate and indeterminate progress bars appear automatically whenever you click a link. If your browser's progress bar is incorrect somehow, your browser is broken and websites shouldn't have to correct for that.


This is simply a reflection of the depth of design (visual and user experience). I'm saying contemporary UX and UI mostly ignore, or are ignorant of, the platform being used and its features. That's not necessarily the case with shoelace, the loading is simply a design decision made to look nice and I presume not much more. The shoelace component system is ok. It reflects a lot of work applicable to what has been possible and borrows from what has been possible the past few years. I find it interesting to see the details in systems and approach and would avoid using this product myself. I haven't reviewed it enough to get past the general impression that it's too complex to be worth the investment and has some weaknesses in the system and technical design. If I were doing a masters in visual communications it would definitely be worth a look, or if I wanted to lead a new project like it as well--to take the understanding of the problems and approaches.


You can massively accelerate the speed (real, not perceived) of page loads by fetching content asynchronously. There's no way for the browser to know that any given fetch is performing the equivalent of a navigation operation, and there's no API for user scripts to tell browsers that a navigation-via-fetch is happening.

Asynch page fetching is faster, but not instant. If you have a reliable way to improve your app's responsiveness but can't drive a native progress bar, what offers a better UX? A subtle, tasteful custom progress effect or nothing? Or do you declare the entire approach invalid on a technicality?

That seems reductive and petulant, like giving up your favorite wine because the winery switched to screw caps for sustainability reasons.


Ask yourself why you believe loading a megabyte of data at best requires asynchronous content fetching. Web pages with a "loading/splash" screen are a telltale sign that I'm about to have a miserable experience, kinda like UWP apps on Windows. Even better when the javascript crashes and instead of getting the content, perhaps badly rendered, I get nothing and need to reload and pray again.

Not saying these apply to Shoelace, but it's also the sort of page that really doesn't need a spinner on first load. Let the browser load things, it already knows how to do that pretty well. 3G connections you say? Send me the unstyled HTML first so I can at least get to the content instead of making some bullshit spinner that will probably crash anyway.

I hate the modern web.


It's only an argument if you don't acknowledge that 1) you have no idea what kind of apps I build and 2) it's fair to say that we're building different kinds of things.

The behaviour you are describing would indeed be frustrating. It describes (well) many of the sites built with SPAs, IMO.

Thankfully, that's not at all what I'm talking about. My stack - server rendered content, Turbo Drive for asynch page loads, Stimulus for light client interactivity that doesn't involve permanent state - is amongst the most battle-hardened.

In real terms, hard page refreshes take hundreds of ms on top of whatever data is sent. Turbo Drive can replace content in whatever real-time is, which is especially noticable on mobile devices. A properly constructed Turbo Drive powered app can therefore feel native to most users, but with server-rendered content.

If you haven't tried it, you might be shocked when you do.

As an addendum: Shoelace is not my site, and I share your distaste of "Loading" prerolls. That said, a quick blue line across the top of the content area that you only see for the same amount of time you'd be waiting for content to load anyhow seems distinctly fine - and that is, not coincidentally, exactly what Turbo Drive does out of the box.


Browser progress bars don't tell you "what" is loading. Many sites will say "waiting.." continuously because some ad server or request that has nothing to do with the current content is taking forever. A single-channel, catch-all "waiting" indicator isn't enough. Every major browser is broken in this respect. The "waiting" indicator is also typically only noticed by power users who have hundreds of thousands of hours of experience loading pages and some technical insight. This feature isn't accessible, it's a farce.


Are web components SEO friendly?

If my page has an accordion or tab component will Google be able to crawl the text inside it?


AFAIK they're impossible to pre-render on the server, and the CSS tricks mentioned in the docs to hide content before components are registered may cause Google's crawler to ignore them. Haven't looked in depth at the React implementation, but the answer seems to tend towards "no".


This is like asking if html elements are SEO friendly. It depends how they're implemented. Google handles javascript now, if that's the salient detail.


Will the post-JS text have the same weight as pre-JS text? Perhaps due to the extra load time or some undocumented aspect of the algorithm.


Depends on how the components are used.

If the content is part of rendered html and wrapped into webcomponents, crawers have no issues accessing that. If the content is loaded dynamically and injected into open mode shadow dom then js enabled crawlers should be able to crawl those too.

If the content is hidden away inside closed mode shadow dom, and also the content is not part of initial HTML then there is no way for a crawler to access it.


Great presentation. Splitting the code into light and dark theme is bizarre and adds unnecessary complexity in <head>.


Given it's built on Google's Lit, hopefully they don't pull the rug out from under them.


That is one of the nice things about being open source and using web components.

Even if lit gets discontinued/deprecated/whatever, they can gradually switch to another library one component at a time. And the user's won't have to do a thing.

lit is strictly an implementation detail, and the consumers just care about the web component API which is part of the browser platform.


I have to dive deeper into this, it looks very interesting.


Why do I need a web component for a button?

Also, if I have web components, why do I need React?


You might not need a web component for a button, but every component library includes them. You're probably not using default css, so it helps to limit your customization options to a few semantic props.

In react you will be calling <Button> components, whether those are web components or react components doesn't take away from what react is great at: giving you a framework for declaring a reactive ui. Having the base components as web components makes them framework agnostic. maybe you don't need react.


Most applications do not need or benefit from React. There's many superior techniques which can provide similar outcomes using HTML generated by the server (gasp).

React was like a long, painful specs gathering process. Going forward, I would never start a major project with React when simpler, standards-based approaches are now just as viable.

The main reason people use web components for buttons is to provide a consistent API and DX, and to facilitate themes and code reuse.


I'm seeing a loading screen, then a loading bar. Not the best foot to start off on if this is a new frontend kit you're doing.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: