Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replacing Goober with something else #40

Open
phiberber opened this issue Oct 17, 2022 · 15 comments
Open

Replacing Goober with something else #40

phiberber opened this issue Oct 17, 2022 · 15 comments

Comments

@phiberber
Copy link

As there is no discussion tab in this repo, I think an issue would be appropriate.

Goober may be very small, having CSS in JS in 1kb gzipped is amazing, but it may not be good to use in big projects. In andreipfeiffer's CSS in JS Goober Analysis he mentions how inefficient Goober can be for dynamic styles.

Not only that but Goober does not allow Atomic CSS, when an update is made to the stylesheet, not only it seems to duplicate, but it seems to duplicate the whole rule, even for things that haven't been changed at all. Here is a CodeSandbox sample that demonstrates this behaviour.

The 1kb promise may look good to the eyes, but I think that behind there's a very unoptimized library that in the end, suffers from being optimized as it is only 1kb.

How easy would it be to replace Goober in the internals of Solid-Styled-Components?

Has anyone built something in production with SSC that's scalable?

There's some examples that I can give of alternatives to CSS in JS but I would like to first hear your opinion about it.

@ryansolid
Copy link
Member

Yeah great discussion topic. I did pick Goober on size, and not much else. I'm not so much a CSS in JS person and I was just trying to check the boxes. Definitely interested to hear thoughts.

@phiberber
Copy link
Author

phiberber commented Oct 17, 2022

Streamich, the creator of React-Use (useCss) also the creator of FreeStyler may have created but mentioned CSS in JS Generations, I really like his approach to the situation but I would like to add more to it.

I imagine that Solid Styled Components was made to look like React Styled Components, mommy said never judge a book by its cover but I'm doing it now.

I was going to do some benchmarking because it is of my interest to really know which CSS in JS Libraries is the best, but just noticed how incorrect the results would turn out.

To help a little to the research I've made a list of CSS in JS Libraries (From most star count to less star count), here's the list:

Styled Components (37.6k Stars) - 4th Generation
Emotion (15.6k Stars) - 4th Generation
Linaria (9.7k Stars) - 4th Generation
Radium (Archived) (7.4k Stars) - 2nd Generation
Styled-JSX (7.2k Stars) - 3rd Generation
JSS (6.8k Stars) - 3rd Generation
Stitches (6.4k Stars) - 5th Generation
Vanilla Extract (6.4k Stars) - 3rd Generation (Maybe 5th Generation)
Aphrodite (5.3k Stars) - 3rd Generation
Glamorous (3.7k Stars) - 4th Generation
Glamor (3.6k Stars) - 3rd Generation
Styletron (3.3k Stars) - 3rd Generation
TypeStyle (3k Stars) - 3rd Generation
Goober (2.7k Stars) - 5th Generation
Fela (2.2k Stars) - 5th Generation
Astroturf (2.1k Stars) - 3rd Generation
Xstyled (2.1k Stars) - 4th Generation
Compiled (1.7k Stars) - 5th Generation
Cxs (1.2k Stars) - 5th Generation
Treat (1.1k Stars) - 3rd Generation
Griffel (824 Stars) - 3rd Generation
Otion (620 Stars) - 4th maybe 5th Generation
CsJS (578 Stars) - 3rd Generation
NyanCss (555 Stars) - 1st Generation
Glam (502 Stars) - 5th Generation
Fower (485 Stars) - 5th Generation
Style9 (447 Stars) - 3rd Generation
NanoCss (403 Stars) - 5th Generation
Picostyle (350 Stars) - 4th Generation
Trousers (300 Stars) - 5th Generation
Css-Zero (283 Stars) - 3rd Generation
FreeStyler (265 Stars) - 5th Generation
Styled-JSS (220 Stars) - 4th Generation
Aesthetic (199 Stars) - 4th Generation
Stylex (184 Stars) - 3rd Generation
Filbert (168 Stars) - 4th Generation
J2c (167 Stars) - 3rd Generation
Style-it (152 Stars) - 5th Generation
Scoped-Style (135 Stars) - 4th Generation
Uranium (127 Stars) - 2nd Generation
Macaron (119 Stars) - 3rd Generation (Maybe 5th Generation)
NanoStyled (103 Stars) - 4th Generation
Rockey (97 Stars) - 4th Generation
Css-Out-Js (90 Stars) - 3rd Generation
Catom (86 Stars) - 3rd Generation
Nano-Style (85 Stars) - 4th Generation
Yocss (60 Stars) - 5th Generation
HyperStyles (59 Stars) - 1st Generation
Stylemug (54 Stars) - 3rd Generation
Tsstyled (52 Stars) - 4th Generation
Glitz (43 Stars) - 5th Generation
SuperStyle (Archived) (39 Stars) - 4th Generation
Dash-UI (30 Stars) - 3rd Generation
Taddy (26 Stars) - 3rd Generation
Classy (24 Stars) - 4th Generation
Cease (21 Stars) - 4th Generation
Glory (20 Stars) - 5th Generation
Tasty (19 Stars) - 3rd Generation
Tassel (18 Stars) - 3rd Generation
Sheety (17 Stars) - 3rd Generation

My personal recommendations for some libraries would be nano-css, fela and free-styler. Glory has made a benchmark to test CSS in JS libraries, this benchmark shows a lot about Fela's performance over Goober, Emotion and Nano-CSS.

There's a lot of differences also in the way the CSS is implemented in the page, some use CSSOM, some use single style tag injections while others use multiple style tag injections (better for 5th gens while worse for 3rd gens). CSS in JS is a whole world where everyone's trying to grab a little of performance in something.

The way I do it in my personal projects are to use nano-css or any 5th generation performant library and implement my own theme system on top of it, using styled-system Styled Props, I love them.

@danil-instacart
Copy link

danil-instacart commented Nov 26, 2022

That's a lot of great alternatives. Thank you!

@phiberber I ran into this amazing thread when realized that goober is not well suited for the CSP policy default-src 'self' | style-src 'self' since it injects inline <style> at runtime, and there are no rollup/vite plugins for making it generate actual *.css files at build time, the way https://www.npmjs.com/package/mini-css-extract-plugin does it with webpack (not sure if mini-css-extract-plugin would ever work with goober).

@danil-instacart
Copy link

danil-instacart commented Nov 26, 2022

I'm far from understanding the whole landscape of CSS-in-JS, but so far, linaria looks like the best of all worlds: it's among the most popular ones, lightweight, it correctly extracts *.css and has the most conventional developer experience with component co-location (pretty similar to hugely popular styled-components, emotion, etc.) I briefly looked at what is the so-called 5th generation and, honestly, not sold by it so far – probably DX looks too unusual.

@phiberber
Copy link
Author

There's a problem with zero runtime css-in-js that's it has no runtime at all. Dynamic styling is pretty limited because of that, I would recommend Solid-styled-components to look like and act like styled-components, which has a runtime and allows any kind of dynamic prop.

That's why all the recommendations I've made are libraries with runtime. This project probably only exists to extend the Solid ecosystem, that has no problem at all, the problem is making an unpredictable library.

Don't get me wrong, Linaria is really good, but it's not a perfect replacement for styled-components nor goober.

One thing that I had never seen before was an adapter css-in-js system, where one could use the same API with different libraries, just like deploy adapters, if that were the case, I would agree in supporting Linaria.

About the CSS files, it's a big problem that static CSS is generated in runtime when SSRing. I'vent noticed any library yet that allows static css extraction while still running with runtime dynamic styles. Nano-css does have a really good implementation of static vs dynamic styles, but I don't think that would be enough to work with.

It has always been a thought of mine of creating such library, which through partial evaluation is able to determine dynamic styles, in-line static styles and extract them to pure css at build time, while then only delivering the JS of the dynamic styles. I've tried to do that once, but the babel's partial evaluation system had some big problems.

I would be up to help creating such library, but I don't think that's what @ryansolid is planning to this SSC. That's why I still keep my recommendations.

@phiberber
Copy link
Author

I would also like to add, Solid Start is implementing the Islands Architecture. In my opinion not only Islands are something hard to achieve with a good level of DX by it own, but implementing CSS-in-JS using Islands always turned out to be a mess (to me).

I don't think this project is a serious project. I know it's here to be used, but it has been shown that Ryan is not focusing on SSC. I think SSC exists only because Solid needs ecosystem, Ryan is then trying to deliver that fast, at the cost of using making bad decisions (goober).

If this project were to be serious, I would suggest discussing about the following topics:

  • Should SSC be exactly like Styled Components.
  • Should SSC do Static CSS extraction?
  • Should SSC do Dynamic CSS isolation?
  • How would theme properties work inside Islands?
  • How would component loading work inside Islands? Do we need to load the full component?
  • Should SSC have a runtime? Should it be a compiler?
  • Should SSC focus on microbenchmarks? If so, from who? How valid can these microbenchmarks be?
  • Should SSC be a serious project, in case it isn't yet?

It's a lot of discussion and it's all related subjects. Should this be all discussed here in this thread? The islands problem does have a big effect in which library to replace Goober with, being like Styled Components too. I'm really unsure about the future of this issue, it can go to amazing places, it can turn into a mess.

@phiberber
Copy link
Author

It is also good to mention. Solid Styled Components is currently being used along Styled-System by some people. There's even an issue about it solidjs/solid#148.

When thinking of a goober alternative, it would be good to check for the compatibility of that x library with Styled-System.

I'd also like to know about @ryansolid's opinion on this, it may be too late to change libraries, I'm not in the position to say that though.

@Profesor08
Copy link

The only advantage of goober is it size. Class generation is wrong, it not respecting nesting of class and their relations. This is related to recently opened issues: solidjs/solid-styled-components#7, cristianbote/goober#397

There is very very simple example, where this library totaly fails. It was very hard to debug and to find this. I have spent a lot of time to find the issue in my components styling. And there was no issues, styling was perfect, but goober thinks different and broke everithing.

Before you try this example, try to guess the style of all 4 components, on parent element hover.

const ChildA = styled("div")``;

const ChildB = styled("div")``;

const ChildC = styled("div")`
  color: yellow;
`;

const ChildD = styled(ChildC)``;

const Parent = styled("div")`
  &:hover {
    ${ChildA.class} {
      color: red;
    }

    ${ChildB.class} {
      color: blue;
    }
  }
`;

export const App = () => {
  return (
    <Parent>
      <ChildA>ChildA</ChildA>
      <ChildB>ChildB</ChildB>
      <ChildC>ChildB</ChildC>
      <ChildD>ChildB</ChildD>
    </Parent>
  );
};

@azuwo
Copy link

azuwo commented Dec 10, 2022

When thinking of a goober alternative, it would be good to check for the compatibility of that x library with Styled-System.

I think the best option is Linaria or any Zero-runtime library for css-in-js, in fact there is a PR for solid integration in Linaria repo

@millette
Copy link

@azuwo quoting #40 (comment) from above:

There's a problem with zero runtime css-in-js that's it has no runtime at all. Dynamic styling is pretty limited because of that, I would recommend Solid-styled-components to look like and act like styled-components, which has a runtime and allows any kind of dynamic prop.

@phiberber
Copy link
Author

When thinking of a goober alternative, it would be good to check for the compatibility of that x library with Styled-System.

I think the best option is Linaria or any Zero-runtime library for css-in-js, in fact there is a PR for solid integration in Linaria repo

Like I've said and has been quoted. Solid-Styled-Components should in my strong opinion look and act like Styled-Components.

I would recommend a Solid-Styled library to be created to support multiple CSS in JS adapters, which is the idea I've already mentioned here. Then Linaria would really be a good option as an adapter.

I agree that the only good factor of Goober is its size.

@phiberber
Copy link
Author

@ryansolid Can this issue have your attention? It makes no sense using Solid which is one of the fastest frameworks along with Solid-Styled-Components currently. SSC uses Goober which has been shown to have serious performance issues when updating styles (Like changing from Light theme to Dark theme).

@MrFoxPro
Copy link

@phiberber I made something you can add to your CSS-in-JS tier-list :P
https://github.com/MrFoxPro/vite-plugin-toad

@miloofcroton
Copy link

@phiberber I made something you can add to your CSS-in-JS tier-list :P https://github.com/MrFoxPro/vite-plugin-toad

Cool idea. I see it is in maintenance mode now. Do you have a better alternative?

@MrFoxPro
Copy link

@phiberber I made something you can add to your CSS-in-JS tier-list :P https://github.com/MrFoxPro/vite-plugin-toad

Cool idea. I see it is in maintenance mode now. Do you have a better alternative?

I switched to unocss

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants