TSS-React: Type-Safe CSS-in-JS with Emotion

4.9.20 · active · verified Tue Apr 21

tss-react is a robust CSS-in-JS solution providing a type-safe API inspired by `react-jss`, but built on top of Emotion. It offers seamless integration with Material UI, supports Next.js App and Page Router environments (though not Server Components due to dynamic style generation), and enables dynamic style generation based on component props and states using plain CSS. Currently at version 4.9.20, it receives frequent patch and minor updates, indicating active development and maintenance. Key differentiators include its strong typing, a JSS-like API for developers familiar with it, the ability to isolate styles from JSX for cleaner component structures, and features like arbitrary specificity increase and a type-safe equivalent of JSS's nested selectors. It is presented as an advantageous replacement for `@material-ui v4 makeStyles` and `react-jss`, providing a maintained solution for dynamic styling with a minimal impact on bundle size.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define and use dynamic styles with `makeStyles` and `useStyles` hooks, passing props to generate conditional styles, and accessing theme properties. It also shows basic `cx` utility usage.

import React from 'react';
import { makeStyles } from 'tss-react';

interface MyComponentProps {
  variant?: 'primary' | 'secondary';
  isActive?: boolean;
}

const useStyles = makeStyles<MyComponentProps>()(
  (theme, { variant, isActive }) => ({
    container: {
      padding: '16px',
      backgroundColor: variant === 'primary' ? 'lightblue' : 'lightgray',
      borderRadius: '8px',
      border: isActive ? '2px solid blue' : 'none',
      '&:hover': {
        boxShadow: '0px 0px 8px rgba(0,0,0,0.2)'
      }
    },
    title: {
      color: theme.palette?.primary?.main || 'navy',
      fontSize: '24px',
      marginBottom: '8px'
    },
    description: {
      color: 'darkslategray',
      fontSize: '16px'
    }
  })
);

function MyComponent({ variant = 'primary', isActive = false }: MyComponentProps) {
  const { classes, cx, theme } = useStyles({ variant, isActive });

  return (
    <div className={cx(classes.container, { 'active-state': isActive })}>
      <h2 className={classes.title}>Hello from TSS-React!</h2>
      <p className={classes.description}>This component demonstrates dynamic styling with props and Emotion theme access.</p>
      <p>Current theme primary color: {theme.palette?.primary?.main || 'N/A'}</p>
    </div>
  );
}

// To run this, you'd typically wrap it in an Emotion `ThemeProvider`
// and a Material-UI `ThemeProvider` if using `@mui/material`.
// Example usage:
// function App() {
//   const muiTheme = createTheme({
//     palette: { primary: { main: '#1976d2' } }
//   });
//   return (
//     <MuiThemeProvider theme={muiTheme}>
//       <EmotionThemeProvider theme={muiTheme}>
//         <MyComponent variant="secondary" isActive={true} />
//       </EmotionThemeProvider>
//     </MuiThemeProvider>
//   );
// }

export default MyComponent;

view raw JSON →