Is the `solid-element` library still being maintained?
I'm working with an engineering team at
SuperTokens
to create a set of reusable Web Components, and the team was interested in using solid-element
to get the job done. However, there doesn't seem to be extensive documentation for this tool, and it hasn't gotten an update for quite some time.
Is the recommendation to use something else like lit-html
for creating Web Components? And is it safe to assume that solid-element
is "Use at your own risk", or will it be getting more attention later?22 Replies
https://dev.to/ryansolid/maybe-web-components-are-not-the-future-hfh
not all "components" need to be DOM elements
https://keithjgrant.com/posts/2023/07/web-components-arent-components/
I leave you to draw your own conclusions.
Also if you want to support WC-SSR in any form Lit is probably your safest bet. Of course there is the Preact signals integration.
I also think it's a matter of priorities. Over the past year it's been SolidStart, now Solid 2.0. It's not inconceivable that an update may happen post-2.0.
DEV Community
Maybe Web Components are not the Future?
I know you are thinking, yet another article in this back and forth between Web Component proponents...
Ryan Carniato
YouTube
Let's look at Web Components
In the spirit of looking at technology I haven't covered on stream, and that I have a long history with, this week we will look at Web Components. There has been a struggle between frameworks and "the platform" that has culminated around them that is worth exploring, plus looking at tools and approaches to using them.
[0:00] Introduction
[5:42]...
Web Components Aren’t Components
Modern web frameworks are built entirely on the concept of components. In the realm of these frameworks, a component is a reusable piece of application code. Al
I don't know too much about web components myself, but maybe @trusktr (Joe Pea) can help since he is a big proponent of solid and web components.
Thanks for linking the articles. I think the difficult thing for us is that, ideally, we'd have a library of reusable components that work in any environment and that are more future proof. To my knowledge, the components we need wouldn't be doing anything too crazy either.
That seemed to be the use case that Ryan said WCs can be useful for, which I agree with. If we were building a full-on web app, we probably wouldn't be considering WCs. But because of the use case I mentioned, that's our focus. SSR WCs would also be desirable as long as it wouldn't require too much effort in userland.
Right now it looks like
solid-element
has some friction with TypeScript.
https://discord.com/channels/722131463138705510/1251556278963146845/1251556278963146845
SSR WCs would also be desirableWell, there is no-such-thing because that was never part of their client-centric design which is why as a feature SSR firmly locks you into a WC-framework which seems like a philosophical contradiction. https://lume.io/ is a showcase of the CE/WC API and Solid being used in concert but on a lower level than
solid-element
.I wrote Lume Element, which is an alternative to
solid-element
, and still maintained:
https://GitHub.com/lume/elementGitHub
GitHub - lume/element: Fast and simple custom elements.
Fast and simple custom elements. Contribute to lume/element development by creating an account on GitHub.
I wouldn't say it is lower level than solid-element, but the dev experience is built around the actual custom element classes instead of function wrappers.
I have a WIP example for SSR and SSG coming out soon for Astro. I'd love to get it working in Solid Start too, but that might require some updates to Solid Start.
Just to avoid confusion, the 3D elements from the
lume
library are built on top of the @lume/element
library. The @lume/element
library can be used as alternative to solid-element, Lit, and other Custom Element libs and does not have anything 3D-specific in it.
Don't listen to the above article, Custom Elements are the future.
@peerreynders posted only negative bias articles. Custom Elements, especially without any build tools, are very liberating.
Lit elements, for example, can be written without any build tools, and an optional build can be added to compile the templates to something more optimized for startup time.
Lume Element doesn't have an html
template tag compiler yet, but if you want to use a build you can use Solid JSX instead of html
inside your templates to optimize. But keep in mind that for most apps, this optimization is premature.
Also!
Custom Elements have a great dev experience: you can inspect them in the devtools element inspector of any browser, out of the box! With non-custom-element component systems, you have to install browser-specific devtools, if they even exist.
The truth is that the form of reactivity in Solid is the best type of reactivity we have in JS (signals and effects, after which the new TC39 Signals spec for JavaScript is named), and hence the best for custom elements. (Lit's reactivity is diff-based like React, more overhead, but honestly the difference doesn't matter for most apps anyway).
Lume is also TypeScript-friendly. The custom elements in JSX can be type checked.
SSR WCs would also be desirable as long as it wouldn't require too much effort in userland.It may require following some conventions, for example put client-side logic only in connectedCallback, as that will run only on the client, or similar. I'm working out these details for Lume, but Lit has similar rules for SSR. If you really need SSR now, I'd say search for Lit Astro. If you don't need SSR now, Lume Element dev paradigm is a lot better with signals and effects imo.
solid-element is "Use at your own risk", or will it be getting more attention later? (edited)There's been chat about updating solid-element ( @davedbase 🌈 ), and I've proposed an update to get class-based style added to it based on my years-worth of Lume dev (with many unit tests). I've built with Lume Element at Velodyne Lidar, NASA, SpaceX, and now at Uthana (AI-generated 3D animation). Rest assured if you need help with Lume Element, I'm not going anywhere just ping me (or join Lume Discord).
The class based approach doesn’t fit with Solid’s philosophy unfortunately. It’s best that Lume Element exists in its own form so that it’s not tainted by Solid’s ideology or opinions.
Hah. Lume is tainted by Solid (not a bad thing), for it uses Solid signals and templating.
I mean it’s a bit of both. lol they are just unique in their ideals
How so?
It comes down to opinions and ideology ultimately. It’s preferences. Decorators and classes are not common in Solid ecosystem and probably won’t be as far as I can tell.
Btw just stating what I’ve come to understand. I’m not looking for a debate of if that’s good or bad.
I think if users prefer Lume Element and that style it’s a fantastic tool
As for Solid Element, it probably needs work to define how it can be improved in a Solidlike way. Lume Element has had years of work though and is pretty awesome in its own right
Well, there is no-such-thingI'm aware, though I can't tell if the declarative shadow DOM is supposed to help with that. I probably could've chosen my words better. The plan is to use some kind of tool to help with Web Components regardless, since it'll make the development faster and easier. It's just a question of what tool will help us accomplish our goals best. Those are a lot of helpful insights and resources! Thanks so much! I'll give Lume a look. I do like the idea of being able to skip a build step with Lit. But I think the dev team likes the idea of having something Solid-esque more. So Lume sounds potentially promising. If we do end up working with that tool, I'll probably end up having to ping you. 😅 So thanks for being willing to be spammed. (I won't actually spam you. lol. That would be bad. But I'll still ask questions. Haha.)
Joe’s great! Always willing to help out. I think you can contract him too 😉 haha
He has a great vision for how Solid reactivity can help the WC community as well.
Hah, I'll try my best to answer all Q's, if you decide to try it out.
@XxX_MLG Noob_XxX My recommendation would be to take both solid-element and Lume Element for a test run (and even Lit), so you can get a feel for what they offer and how they differ.
solid-element gives a function-based wrapper around custom elements, but because of the way it is implemented, it makes it very inflexible compared to raw classes.
For example, solid-element offers no control over the attribute types. All attribute string values always get passed in as-is. But Lit and Lume Element both offer control over this. For example
@numberAttribute foo = 123
in Lume (and something similar on Lit) will ensure that an attribute with the value "123"
gets coerced into a number
. With solid-element, you will need to implement all the string coercions yourself.
All of three offer a way to specify to us ShadowRoot or not. But solid-element does not provide scoped style when opted out of the ShadowRoot.
With solid-element, if you want to for example add a method to your element, you'll need to add it onto the element reference, which will not be supported for type checking in TypeScript:
With Lume or Lit, you'd just define the method in your class, and it will be natively supported by TypeScript:
With Lume and Lit, you implementation is more flexible because you can use more patterns like mixins. For example, let's use a mixin that added childConnectedCallback()
to our class for easily handling connected children:
(Check out the wrapper that creates the custom element class for solid-element here: https://github.com/ryansolid/component-register/blob/master/src/element.ts)
Hiding the element class definition just to make it a function is, in my opinion, unnecessarily limiting, fights against the grain of web standards, and introduces new issues to solve such as out-of-the-box TypeScript support eliminated (f.e. element methods).
Now what if you want to use ElementInternals
? Well guess what, you need to access this in your Custom Element class, which is hidden in solid-element
! Every new feature that is added to Custom Elements, solid-element
will need to expose it, which is unnecessary work. With Lume or Lit, you can just use this.attachInternals()
in your class constructor as you see fit, without Lume or Lit having to adjust to expose it to you.
With solid-element, you cannot make base element classes to extend from, you're limited only to composition. Sometimes composition is not desirable, and sometimes inheritance is.
@davedbase 🌈 ^ differences between solid-element and class-based libs like Lume and Lit you might like to be aware of.
At a high level, it is also worth noting that if you've written this,
you've essentially written a class with all properties being private. That's how classes were first implemented before class
syntax existed to make it easier, syntactically cleaner, and more flexible.Those are some helpful comparisons. Yeah I've only played a tiny bit with
solid-element
and I quickly noticed the limitations of having to attaching things to the element instance (instead of being able to define them on the class directly).
Does Lume's JSX support/have something like Solid's <Show>
/<For>
?Yeah, it is Solid's JSX. But you can also use Solid's
html
for buildless.
It is flexible, all you need to do is return DOM, or Solid template result (JSX/html
), from template
, just as with a function component.
Basically:
Behind the scenes, the Element.connectedCallback()
method simply calls Solid's render
, something like render(this.template, this)
, so essentially the template
method is like a Solid component. You can even write template
in a similar way to a solid component, for example:
This is nifty, because can use Solid "hooks" inside of the template
method. F.e. anything from solid-primitives
, etc.
Solid reactivity is so flexible, you could work with DOM in any way you want, for example the following make an element wrapper around some hypothetical jQuery component:
This is so flexible and simple compared to Lit or React for example.Oh wow! Nice!
It seems like a component could just be passed to
template
then. 🤔 Interesting. Does it still work with stuff like Solid's Context too?I am curious about this as well. State sharing across components is a concern of mine.
This works surprisingly well!
Yep, you can use any Solid components in the template.
Each element is its own reactive root, so currently Solid-style contexts are limited to the shadow root of the element they are in. But we could fix that, I just haven't needed it.
I use DOM-based context patterns, instead of the solid-specific pattern, if I need a context. For example a child element deep in the DOM tree can dispatch a bubbling composed event to receive a context, and an element higher up can pass the context to the element (event.target). This is all using plain DOM APIs.
To support contexts for Solid, instead of creating a new root for each element, we could perhaps use getOwner and connect to a parent element's reactive context.
Child element deep in the DOM, nested in any shadow root down below:
Ancestor element up high that provides a context:
There's a multitude of ways to implement. event.detail could be a callback, etc.
Here is for example a convention for it:
https://github.com/webcomponents-cg/community-protocols/blob/main/proposals/context.md
GitHub
community-protocols/proposals/context.md at main · webcomponents-cg...
Cross-component coordination protocols. Contribute to webcomponents-cg/community-protocols development by creating an account on GitHub.
Lit implements additional API around it using decorators:
https://lit.dev/docs/data/context/