question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

with regards to emotion vs jss for mui v5

See original GitHub issue

(Btw I was hoping to post this in the discussions section, but github won’t allow me)

Ever since v5 was released, I’ve noticed a strong push towards using emotion styling (styled) over the previous recommendation of jss (makeStyles).

This weekend I began the process of attempting to migrate our codebase to mui v5. In the process, I decided to try my hands at the new use of styled components. At the end of this little experiment, I am highly doubtful that using emotion style is the way to go for non-library authors.

Firstly, I have very little experience using emotion, and much less styled, but after running the codemods and playing around with the syntax, I came to the following conclusions:

  1. The end result of using styled (especially for large components which have lots of styling), makes the component look more complex than it should be. The reason for this is mostly due to the insistence of having to “wrap” a component with a given style, which then forces us to create a special “StyledXYZ” version of the topmost element, outside the component tree. Then inject it once again into component tree. 😬 yikes! Not to talk about the namespacing with having to prefix all styles with the name of the component, then these have to be interpolated inside template strings…
  2. Styled components become too tightly coupled to the code used to style them. If I decide to change the outermost element of my component to ZXY, I now have to rename my “StyledXYZ” component to “StyledZXY”, to maintain the new naming convention.
  3. Due to the two above reasons, I come to a third conclusion that emotion styling seems more suited for library authors who are trying to create a branding around their components, rather than users who are just styling a few parts of their components…
  4. Styled components leak styling props to the component which they wrap. This adds an unnecessary burden on the author to write a filter function (shouldForwardProp) to determine if some props should be forwarded or not. I mean why is that even a question.

At the end of the day for me, this is more readable…

with jss styling
const useStyles = makeStyles<Theme, { mini: boolean, colour?: string }>(theme => ({
    avatar: ({ colour = lighten(theme.palette.secondary.main, 0.7), mini }) => ({
        width: theme.spacing(mini ? 6 : 9),
        height: theme.spacing(mini ? 6 : 9),
        borderColor: colour,
    }),
    avatarText: ({ mini }) => ({
        ...,
    }),
    name: ({ mini }) => ({
        ...,
    }),
    value: ({ mini }) => ({
        ...,
    }),
}));

interface SomeComponentProps {
    colour?: string;
    size?: "mini" | "normal";
}

const SomeComponent: React.FC<SomeComponentProps> = React.memo(({ colour, size = "normal" }) => {
  const classes = useStyles({ mini: size === 'mini', colour: color });
  return (
    <Box  ... >
                ...
    </Box>
  );
}

export default SomeComponent;

than this

with emotion styling
const PREFIX = "SomeComponent";

const classes = {
    avatar: `${PREFIX}-avatar`,
    avatarText: `${PREFIX}-avatarText`,
    name: `${PREFIX}-name`,
    value: `${PREFIX}-value`,
};

const StyledBox = styled(Box, {
    shouldForwardProp(prop) {
        return (typeof prop !== 'string' || prop[0] !== '$');
    }
})<{ $mini: boolean, $colour?: string }>(({ theme, $mini, $colour = lighten(theme.palette.secondary.main, 0.7) }) => ({
    [`& .${classes.avatar}`]: {
        width: theme.spacing($mini ? 6 : 9),
        height: theme.spacing($mini ? 6 : 9),
        borderColor: $colour,
        ...,
    },
    [`& .${classes.avatarText}`]: {
        ...,
    },
    [`& .${classes.name}`]: {
        ...,
    },
    [`& .${classes.value}`]: {
        ...,
    },
}));

interface SomeComponentProps {
    colour?: string;
    size?: "mini" | "normal";
}

const SomeComponent: React.FC<SomeComponentProps> = React.memo(({ colour, size = "normal" }) => {
  return (
    <StyledBox $mini $colour={colour} ...>
                ...
    </StyledBox>
  );
}

export default SomeComponent;

What are your thoughts on this? Apart from the promise of decreased bundle size, what other real advantage does emotion offer over jss?

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:37
  • Comments:10 (7 by maintainers)

github_iconTop GitHub Comments

28reactions
Talendarcommented, Sep 19, 2021

I really like JSS. I don’t understand the appeal of emotion/styled-components.

24reactions
garronejcommented, Sep 20, 2021

Hi @aleccaputo,
What I can say is that I am committed to maintaining tss-react for the foreseeable future.
I take great care to ensure that tss-react do integrate well with MUI and I always respond to issues.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Material UI v5 is out, and I'm unsure if I like the move ... - Reddit
I'd love to know of good resources that can go over how to best use Emotion in this context, and how to unlearn...
Read more >
Introducing MUI Core v5.0
We have replaced JSS with emotion as a default styling solution while adding support for styled-components at the same time. We recommend ...
Read more >
MUI v5 @mui/material/styles vs @emotion/react - Stack Overflow
MUI v5 uses emotion as a default style engine. The MUI team recommends styled / sx to customize the component styles.
Read more >
[RFC] v5 styling solution · Issue #22342 · mui/material-ui
This RFC is a proposal for changing the styling solution of Material-UI in v5. TL:DR; the core team proposes we go with emotion...
Read more >
Material UI 5 - the easiest way to migrate from makeStyles to ...
It relies on @emotion/css which is different from @emotion/react . Mui depends on @emotion/react; No mention of how to prioritize one class over ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found