Enforce Emotion (@emotion/styled and @emotion/react) as the only styling library; forbid styled-components usage.
95
97%
Does it follow best practices?
Impact
92%
1.61xAverage score across 4 eval scenarios
Passed
No known issues
All styled components and CSS-in-JS in this codebase use Emotion:
styled from @emotion/styledcss from @emotion/reactDo not use styled-components, even though the package appears in package.json ("styled-components": "5.3.5") as a legacy dependency. New code must not import from styled-components.
The canonical pair:
import styled from '@emotion/styled';
import { css } from '@emotion/react';Both are commonly used in the same file: styled.x for components, css template literals for reusable CSS chunks that get composed into styled blocks (see the XxxCSS-suffix convention).
For programmatic color manipulation (darken on hover, lighten on active, alpha adjustments), use polished, not chroma-js:
import { darken } from 'polished';Canonical pattern for state-driven backgrounds:
const getButtonBackground = (background) => {
const hover = darken(0.03, background);
const active = darken(0.05, background);
return css`
background: ${background};
&:hover { background: ${hover}; }
&:active { background: ${active}; }
`;
};Reference: libs/core/src/components/general/Button/Button.component.js.
StylingProviders at @codebase/core/components/providers/StylingProviders — it composes Emotion's ThemeProvider, WebFontProvider, and the project's GlobalStyles.ThemeProvider from styled-components or instantiate Emotion's ThemeProvider directly. Always go through StylingProviders.Styled exports live in <Component>.styles.js siblings to the implementation. Reusable CSS chunks shared across multiple styled blocks use the <Name>CSS suffix (e.g. EmptyButtonCSS) — usually colocated with the styled-component file that owns the base style.
| Don't | Use instead |
|---|---|
import styled from 'styled-components' | import styled from '@emotion/styled' |
import { css } from 'styled-components' | import { css } from '@emotion/react' |
import { keyframes } from 'styled-components' | import { keyframes } from '@emotion/react' |
import { ThemeProvider } from 'styled-components' | import StylingProviders from '@codebase/core/components/providers/StylingProviders' |
styled.div.attrs({...}) (styled-components API) | Pass props through <Div {...rest}/> and read them inside the template literal |
chroma-js for hover/active math | polished's darken / lighten / transparentize |
react-tippy or react-konva may use their own style systems internally — that's fine. The rule applies only to our CSS-in-JS, not to the third-party library's internals.@emotion/server is already wired through the Next.js setup. Don't add custom SSR style extraction for styled-components.nx.json → "style": "@emotion/styled"). When creating a new lib/component via nx g, this is automatic — don't override it.Button, CardGrid, EmptyButtonCSS, and Page.styles.js.styled-components stays out, and what would change this rule.