Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Deprecate glamorous πŸ’„ in favor of emotion πŸ‘©β€πŸŽ€ #419

Closed
kentcdodds opened this issue May 9, 2018 · 92 comments
Closed

Comments

@kentcdodds
Copy link
Contributor

For a long time now I've been considering deprecating glamorous (NOT glamorous-native) in favor of emotion.

Here's my reasoning:

  1. Emotion can do everything glamorous can do
  2. Emotion can do more than glamorous can do
  3. Emotion is faster than glamorous
  4. Emotion is smaller than glamorous
  5. It's good for the community to consolidate and rally around using and improving a single solution

I would not recommend people spend a bunch of time migrating to emotion. glamorous isn't bad, it's just not as good as emotion and I don't think it would be worth the effort to manually migrate. That said, I'm fairly confident that a codemod could be written to automatically migrate your glamorous code to emotion.

What a deprecation would mean:

  • I would add a notice to the README and website indicating that this project is no longer maintained and encouraging people to use emotion instead.

What a deprecation would NOT mean:

  • glamorous-native is still the best-in-class for styling native applications and is entirely separate from glamorous. It would NOT be deprecated. It is an entirely separate project with no shared dependencies anyway, so a deprecation of glamorous wouldn't impact glamorous-native directly.

What I want from you:

Please give this a πŸ‘ if you agree or a πŸ‘Ž if you disagree.

If you disagree, please list reasons why and whether you would be willing to assume the maintainer role.

Thanks friends!

@kentcdodds kentcdodds changed the title Deprecate glamorous in favor of emotion Deprecate glamorous πŸ’„ in favor of emotion πŸ‘©β€πŸŽ€ May 9, 2018
@kentcdodds
Copy link
Contributor Author

Things are looking very positive for this. If someone would like to help a LOT of people here are a few things you could do:

  1. Write a migration guide. It could be a simple markdown file here.
  2. Write a codemod. If you don't have any experience with ASTs then this might be a bit of a challenge for you. I have some resources for you though:

A good starting point for the codemod could be the one I wrote for upgrading people's version of glamorous due to the theme breaking change we had a few months ago: https://github.com/paypal/glamorous/blob/master/other/codemods/theme-move.js

I don't think that I'll have time to do either of these things any time soon, but I'd love it if anyone would like to pitch in to do it :)

I'm 99% certain that we'll be doing this.

@morajabi
Copy link
Contributor

morajabi commented May 9, 2018

I can think of one concern, this move can confuse people (like some already asked) and raise this question that what would happen to glamorous-native again and again. Adding a notice mentioning "This is actively maintained" or something like that in that project's readme would be helpful :)

@rob-swu
Copy link

rob-swu commented May 9, 2018

nice! I recently migrated our entire codebase from glamorous to emotion. I'll see if I have some cycles to write up some of the things I did to migrate and any gotchas I ran into

@Ailrun
Copy link
Contributor

Ailrun commented May 9, 2018

One thing that can (probably) confuse people is TS support. Emotion's TS support is quite immature compared to Glamorous. It does almost nothing with CSS typing, does not have proper plugin type, ...

@kentcdodds
Copy link
Contributor Author

@Ailrun, that is a very valid concern and I'm sure it would be frustrating for folks like you and others who have poured a TON of effort into making glamorous as great as it is with regards to TypeScript. Hopefully by switching to emotion we can combine efforts with other folks to take the things we've learned from glamorous to improve the Typings in emotion.

@Ailrun
Copy link
Contributor

Ailrun commented May 9, 2018

@kentcdodds Hm... then, I should spend some time on emotion typing to move there safely. Thank you for kind comment.

@quicksnap
Copy link
Collaborator

Does anyone have a react+emotion demo repo/codepen or something I could test a few things with?

My primary use case with Glamorous has been css-object composition+ThemeProvider--nested arrays of objects or functions-returning-objects. I'd like to validate that emotion can work with some of those patterns.

Soon enough I'll test it out, but if there's already a codesandbox or something I could test things very quickly.

@kentcdodds You're making a very awesome decision to rally around a single solution. Love the direction here.

@brentertz
Copy link
Contributor

brentertz commented May 10, 2018

@kentcdodds Emotion does not seem to have any notion of prop filtering, and the associated API's rootEl, filterProps, forwardProps, like Glamorous does. Was this a difficult thing to maintain in Glamorous? Any thoughts on how to approach if migrating to Emotion? The library that I work on relies on it pretty heavily at present.


Update: Apparently Emotion supports a shouldForwardProp option and also has a @emotion/is-prop-valid package. Investigating further...


Update: Emotion has similar capabilities, but as usual, the devil is in the details. It does not appear that this will be a simple migration. Need time to investigate further, but unfortunately don't have it at present. Issues documented in mineral-ui/mineral-ui#692

@kentcdodds
Copy link
Contributor Author

Interesting. Could you file an issue on emotion @brentertz? Let's see if this is something they'd be willing to implement. Either that or we could implement a small layer on top of emotion that could do this.

@Andarist
Copy link
Contributor

@quicksnap

My primary use case with Glamorous has been css-object composition+ThemeProvider--nested arrays of objects or functions-returning-objects. I'd like to validate that emotion can work with some of those patterns.

Emotion should handle all that jazz just fine. We use it on production and receiving serializable theme objects through the wire + ofc we use some local functions etc to style based on props.

@VinSpee
Copy link

VinSpee commented May 11, 2018

I'm curious about the implication for this kind of use:

  <glamorous.Div
    backgroundColor={theme.color('white')}
    paddingTop={theme.size(0.1)}
    paddingLeft={theme.size(0.2)}
    paddingRight={theme.size(0.2)}
    display="flex"
    jusitfyContent="center"
    alignItems="center"
  >
    This gets nicely styled using props
  </glamorous.Div>

@Andarist
Copy link
Contributor

In emotion this can be achieved by using custom helpers or libraries like styled-system

@bjoernricks
Copy link
Contributor

bjoernricks commented May 14, 2018

From #421

Object Syntax If moving to emotion you will need their babel-plugin-emotion

Is that true? In that case moving from glamorous to emotion is a no go for me and users of create-react-app who like to still use the object notation.

@Andarist
Copy link
Contributor

@bjoernricks that's not true, emotion handles object syntax without babel's help

@ctrlplusb
Copy link

ctrlplusb commented May 14, 2018

@bjoernricks the babel plugin is only needed if you want a similar API to glamorous.

Without babel plugin:

import styled from 'react-emotion'

const Foo = styled('div')({
  position: 'relative'
})

With babel plugin:

import styled from 'react-emotion'

const Foo = styled.div({
  position: 'relative'
})

So whilst the plugin isn't required, it certainly makes the migration easier.


Update:

FYI, I also use create-react-app, and would encourage you to look at react-app-rewired. Sometimes it's really helpful to be able to add a plugin to CRA without ejecting.

Someone has built a plugin for emotion too πŸ‘

@Andarist
Copy link
Contributor

Also there is a plan to support styled.div style without a babel plugin in upcoming emotion@10, but it's still recommended to use babel plugin nevertheless to downsize production bundles.

@danielberndt
Copy link
Collaborator

danielberndt commented May 14, 2018

fyi: v2 of create-react-app supports babel-macros. This means that you can use emotion/macro without having to eject.
Macros seem to support all features that babel-plugin-emotion support except for the css-prop.

@dragosbulugean
Copy link

dragosbulugean commented May 15, 2018

Two things that emotion doesn't do are exactly the things that I used glamorous for:

  • being able to inline styles like this (lets you not give anything a name if you don't reuse it):
<Div width={100} height={100}>
 <H1 backgroundColor="green">Hello</H1>
</Div>
  • if you used TypeScript, these props would be type-checked at compile time.

So, not really feeling 'emotion is better than glamorous'.
I will probably continue to use it.

@VinSpee
Copy link

VinSpee commented May 15, 2018

@dragosbulugean I started migrating and found

<div
  css={{
    width: 100,
    height: 100,
  }}
>
  <h1
    css={{
      backgroundColor: 'green',
    }}
  >
    Hello
  </h1>
</div>

to be a suitable alternative. I even like it a bit more.

@dragosbulugean
Copy link

@VinSpee thanks, but where do you get the div and h1 from? not sure you are allowed to name them exactly like the included dom react components.

@VinSpee
Copy link

VinSpee commented May 15, 2018

@dragosbulugean it uses a babel transform:

https://emotion.sh/docs/css#css-prop

@kentcdodds
Copy link
Contributor Author

In addition, the css prop is actually more powerful because you can use media queries and such, so I haven't used the named css props for a long time. On top of that, when you use the built-in components with glamorous, you're putting that code on the slow path. It's fast enough to not be a problem most of the time, but it's definitely the slowest way to use glamorous. That's not the case with emotion. They've done some amazing work to make it super fast.

@ctrlplusb
Copy link

ctrlplusb commented Jul 5, 2018

Upgraded a pretty huge side project of mine (approx a year worth of dev on it) within an hour. Pretty decent! Huge thanks to @TejasQ for the codemod. ⭐️


Side note: emotion is really fast! Noticed a distinct improvement in perf already. Great decision to move towards it. πŸ‘

@TejasQ
Copy link
Contributor

TejasQ commented Jul 6, 2018

@ctrlplusb awesome to hear it! Glad I could help! I hope your project flourishes!

@danielberndt
Copy link
Collaborator

danielberndt commented Jul 23, 2018

I just migrated quite a big project using a lot of glamorous features to emotion. I'm almost done, and it took me about a day of work.

Notable things the codemod does not support (yet):

  • wont work with glamorous.macro (should be easy to fix)
  • won't work if you do imports like import g from "glamorous" the codemod expects import glamorous from "glamorous"
  • you manually need to convert code like <glamorous.div marginTop={5}/> to <div css={{marginTop: 5}}/>
  • no automatic translation from filterProps/forwardProps to shouldForwardProps (the latter expects a function), most other options (e.g. withProps) are also not directly translatable
  • forwardProps: ["innerRef"] does not work with emotion
  • global styles and keyframes can't be automatically translated yet either
  • won't work with create-react-app out of the box, but react-app-rewire-emotion makes it fairly straight forward without the need to eject.

@TejasQ
Copy link
Contributor

TejasQ commented Jul 24, 2018

Wow! Thanks so much @danielberndt! Would you be interested to implement these features in the codemod together?

@danielberndt
Copy link
Collaborator

@TejasQ this would be quite a nice opportunity for me to dig into AST-transformations which I've never done before. :)
But I can't promise anything since my schedule is quite full at the moment.

@TejasQ
Copy link
Contributor

TejasQ commented Jul 24, 2018

@danielberndt No worries whatsoever. The easiest thing would probably be working with generic default import specifiers (number 2 on your list). Shall I reserve that for you?

I could even just submit PRs that you review and could use for learning.

What would you prefer?

@danielberndt
Copy link
Collaborator

Ah, how nice! Yes, if you have the time, feel free to go ahead and implement it yourself. I'd be very happy to learn from your changes πŸ‘

@TejasQ
Copy link
Contributor

TejasQ commented Jul 24, 2018

I don't really have the time, but I'll make the time for you. <3

@antoniobrandao
Copy link

@danielberndt does the standard ref work ?

@danielberndt
Copy link
Collaborator

danielberndt commented Jul 24, 2018

@antoniobrandao both innerRef and ref work the same way in glamorous and emotion. I was referring to a very niche feature that was introduced here:

If you want to prevent glamorous from appling the innerRef mechanism and instead just forward that prop to the underlying Component (e.g. use react-routers own <Link innerRef={handler}/> you could just do

const StyledLink = glamourous(Link, {forwardProps: ["innerRef"]})({...styles})

This feature is not supported by emotion and instead you need to do something like:

const MyLink = ({underlyingInnerRef, ...rest}) => <Link innerRef={underlyingInnerRef} {...rest}/>
const StyledLink = emotion(MyLink)({...styles})

// use it like this
<StyledLink underlyingInnerRef={handlerReceivingTheATag}/>

// or to be more specific about the differences:
<StyledLink 
  underlyingInnerRef={handlerReceivingTheATag}
  innerRef={handlerReceivingTheLinkComponent}
  ref={handlerReceivingTheStyledLinkComponent}
/>

@antoniobrandao
Copy link

@danielberndt thanks man

@antoniobrandao
Copy link

antoniobrandao commented Jul 24, 2018

How does this work in Emotion with object styles? Can't find it in the docs.

Glamorous way to make a element that is blue by default, be red when it has a certain class:

// glamorous way doesn't work in emotion
const SomeDiv = styled.div({
  color: 'blue',
  ['.someClass']: {
    color: 'red',
  }
})

@VinSpee
Copy link

VinSpee commented Jul 24, 2018

@antoniobrandao:

const SomeDiv = styled.div({
  color: 'blue',
  ['&.someClass']: {
    color: 'red',
  }
})

@antoniobrandao
Copy link

Thanks @VinSpee πŸ™

@tkh44
Copy link
Contributor

tkh44 commented Jul 25, 2018

Thanks @VinSpee. FWIW you do not need the [ ] around the selector @antoniobrandao.

CMD+F "linkClass" here https://codesandbox.io/s/xrpjw8jnnq

@syberen
Copy link

syberen commented Jul 26, 2018

Does anyone have guidelines for migrating from glamorous to styled-components? Having a lot of trouble getting it to work properly.

@TejasQ
Copy link
Contributor

TejasQ commented Jul 26, 2018

@syberen is there a reason you've chosen to migrate from glamorous to styled-components instead of to emotion? πŸ€”

@syberen
Copy link

syberen commented Jul 26, 2018

@TejasQ We're researching both options, but styled-components does seem to have a larger community and I've gotten some reports of buggy behavior from emotion from fellow developers, although I don't know the details.

@Andarist
Copy link
Contributor

@TejasQ We're researching both options, but styled-components does seem to have a larger community and I've gotten some reports of buggy behavior from emotion from fellow developers, although I don't know the details.

Not sure where did that come from, but we barely receive any bug reports for emotion and even if there are bugs reported they are fixed pretty quickly.

@danielberndt
Copy link
Collaborator

Hello people!
I've taken some time to rewrite a big chunk of the codemod.
It's now in a much more solid state, and tackles most of my points above.

I'm most excited about all the transforms around the <glamorous.Div> syntax. Here some examples:

import g from "glamorous";

<g.Div marginTop={5}/>
// transformed to ↓
<div css={{marginTop: 5}}/>

<g.Div marginTop={5} css={{marginTop: 10}} marginBottom="5" onClick={handler}/>
// transformed to ↓
<div onClick={handler} css={{
  marginTop: 10,
  marginTop: 5,
  marginBottom: "5"
}} />

<g.Img width={100}/>
// transformed to ↓
<img width={100} />

<g.Span width={100}/>
// transformed to ↓
<span css={{width: 100}} />

<g.Span css={redStyles} marginLeft={5}/>
// transformed to ↓
<span css={{ ...redStyles, marginLeft: 5}} />

There's also an withBabelPlugin option, allowing you to decide what kind of emotion setup you want to support.

Thanks a lot to @TejasQ for the helpful code reviews! The code is in quite a readable state, should you be curious about babel-transforms :)

@kentcdodds
Copy link
Contributor Author

That's fantastic @danielberndt! Thank you and @TejasQ for all your work on that πŸ‘ πŸ‘ πŸ‘ πŸ‘ πŸ‘ πŸ‘

@kentcdodds
Copy link
Contributor Author

kentcdodds commented Dec 6, 2018

I just published glamorous@5 and deprecated it so people installing latest will now get a deprecation message. (This means that existing projects using 4.x will not see a deprecation message, only people installing glamorous for the first time). I will also be archiving this repository in the next few days. https://glamorous.rocks will remain untouched for the foreseeable future (though the repo https://github.com/kentcdodds/glamorous-website will be archived as well).

image

I would like to give a special thank you to everyone who helped make this project what it was and inspired other projects to be built and enhanced pushing the css-in-js coding style forward. It was an awesome run. Thanks everyone who helped make the transition as smooth as possible.

I love you all <3

@TejasQ
Copy link
Contributor

TejasQ commented Dec 6, 2018

Love you too Kent πŸ’ž

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

No branches or pull requests