CtrlK
BlogDocsLog inGet started
Tessl Logo
PluginPublic

likethemammal/emotion-required

Enforce Emotion (@emotion/styled and @emotion/react) as the only styling library; forbid styled-components usage.

1.61x
Quality

97%

Does it follow best practices?

Impact

92%

1.61x

Average score across 4 eval scenarios

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files
name:
emotion-required
description:
Enforce Emotion (@emotion/styled and @emotion/react) as the only styling library when writing or modifying styled components, .styles.js files, or any CSS-in-JS in this codebase. Forbid styled-components imports even though the package is present as a legacy dependency. Activates on tasks involving styled.x usage, css template literals, theme provider setup, .styles.js file creation, or hover/active state styling.
metadata:
{"category":"standards","area":"styling","status":"stable","version":"0.1.0","related":"hsl-preferred-over-hex,xxxCSS-suffix-for-shared-snippets,polished-for-state-hover"}

Emotion required

Rule

All styled components and CSS-in-JS in this codebase use Emotion:

  • styled from @emotion/styled
  • css from @emotion/react

Do 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.

Imports

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

State transforms (hover / active)

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.

Theme & global styles

  • Theme is provided through the wrapped StylingProviders at @codebase/core/components/providers/StylingProviders — it composes Emotion's ThemeProvider, WebFontProvider, and the project's GlobalStyles.
  • Never reach for ThemeProvider from styled-components or instantiate Emotion's ThemeProvider directly. Always go through StylingProviders.

File location

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.

Forbidden

Don'tUse 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 mathpolished's darken / lighten / transparentize

Edge cases

  • Third-party components with their own theming: components from 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.
  • SSR: @emotion/server is already wired through the Next.js setup. Don't add custom SSR style extraction for styled-components.
  • Generated styled types: Nx generators are pre-configured for Emotion (nx.json → "style": "@emotion/styled"). When creating a new lib/component via nx g, this is automatic — don't override it.

References

  • Good examples — canonical patterns from Button, CardGrid, EmptyButtonCSS, and Page.styles.js.
  • Bad examples — common wrong shapes the agent will reach for if not told otherwise.
  • Rationale — why Emotion, why styled-components stays out, and what would change this rule.
Workspace
likethemammal
Visibility
Public
Created
Last updated
Source
CLI
Repository
No repository linked. Set repository in the plugin manifest, or publish from a GitHub Action to verify it.
Badge
likethemammal/emotion-required badge