Skip to main content

Migration from Stitches

We decided that we need to migrate from Stitches. Stitches is no longer maintained and it is blocking us on the path of staying up to date with Next.js and the new React Server Components.

Migration target

CSS Modules (with SCSS) & CVA.

Guidelines

Create a new <<MyComponent>>.module.scss file in the same folder as the file with Stitches implementation. Import global mixins from ~/modules/design-system@v2/utils/mixins. Migrate all Stitches components to SCSS and remove the original Styled Components file.

If there were any props used for styling purposes, you need to refactor the dynamic behavior to CSS classes and use Class Variance Authority. The Variant API should be almost identical to Stitches. The only work needed is to map your CSS classes instead.

If the component used Stitches Responsive API, then it gets a little bit more complicated as this was an exclusive API made by Stitches.

You need to create a new class and implement all specific responsive styles and then use this CSS class on your component. If the pattern gets reused plenty of times, you can utilize SCSS Mixins to centralize some CSS bits and share them across the application. If more flexibility is needed, you can combine these mixins and implement some component presets. An example of such an approach can be seen on the new Title component presets (/src/modules/design-system@v2/components/Title/presets/).

General UI components

These components were usually customized or extended via styled(MyUIComponent). These cases also need more attention during the migration. Because there might be specificity issues and the styles could not be applied as you would expect. So whenever you will be refactoring such a component which is also extended, make sure you also check the extended use case.

Targeting Selectors outside of CSS Module

You need to use the :global() functionality to target classnames defined outside of the CSS module, you are in.

Example

// HTML Hierarchy
// <body className="light">
// ...
// <button className={classes.myButton}>

// MyButton.module.scss

// ❌ incorrect approach
.myButton {
// ...
color: white;
background-color: black;

body.light & {
color: black;
background-color: white;
}
}

// ✅ correct approach
.myButton {
// ...
color: white;
background-color: black;

:global(body.light) & {
color: black;
background-color: white;
}
}

Interpolation of SCSS function in definition of custom CSS Variables

// pxToRem is a SCSS function to convert values in pixels to rems.

margin-bottom: pxToRem(32px); // ✅ works as expected; will produce: margin-bottom: 2rem;

--size: pxToRem(32px); // ❌ will produce --size: pxToRem(32px);
--size: #{pxToRem(32px)}; // ✅ will produce --size: 2rem;

  • Add more useful guidelines as we progress in the migration