solid-styled-components icon indicating copy to clipboard operation
solid-styled-components copied to clipboard

Replacing Goober with something else

Open phiberber opened this issue 3 years ago • 30 comments

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.

phiberber avatar Oct 17 '22 16:10 phiberber

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.

ryansolid avatar Oct 17 '22 17:10 ryansolid

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.

phiberber avatar Oct 17 '22 21:10 phiberber

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 avatar Nov 26 '22 15:11 danil-instacart

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.

danil-instacart avatar Nov 26 '22 23:11 danil-instacart

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 avatar Nov 27 '22 11:11 phiberber

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 avatar Nov 27 '22 23:11 phiberber

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 https://github.com/solidjs/solid/issues/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.

phiberber avatar Dec 03 '22 23:12 phiberber

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, https://github.com/cristianbote/goober/issues/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>
  );
};

Profesor08 avatar Dec 10 '22 13:12 Profesor08

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

azuwo avatar Dec 10 '22 19:12 azuwo

@azuwo quoting https://github.com/solidjs/solid-styled-components/issues/40#issuecomment-1328227822 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.

millette avatar Dec 10 '22 19:12 millette

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 avatar Dec 10 '22 20:12 phiberber

@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).

phiberber avatar Feb 13 '23 13:02 phiberber

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

MrFoxPro avatar Jul 20 '23 10:07 MrFoxPro