Type safe CSS-in-JS API heavily inspired by react-jss
npx @tessl/cli install tessl/npm-tss-react@4.9.0TSS-React is a type-safe CSS-in-JS solution built on top of Emotion that provides dynamic style generation for React applications. It offers seamless integration with MUI, Next.js support, and maintains JSX readability while eliminating CSS priority conflicts. With minimal bundle impact (~5kB minzipped alongside MUI), it serves as a modern replacement for @material-ui makeStyles and react-jss.
npm install tss-react@emotion/react, @emotion/cache, @emotion/serialize, @emotion/utilsreact (^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0), @types/react, @emotion/react (^11.4.1)@mui/material (^5.0.0 || ^6.0.0 || ^7.0.0), @emotion/server (^11.4.0)Factory Functions:
import { createTss, createMakeStyles, createWithStyles, createMakeAndWithStyles } from "tss-react";Pre-configured Instances:
import { tss, useStyles } from "tss-react";Types and Utilities:
import type { Tss, Css, Cx, CSSObject, CSSInterpolation, CxArg } from "tss-react";
import { GlobalStyles, keyframes, TssCacheProvider } from "tss-react";MUI Integration:
import { tss, makeStyles, withStyles, useStyles } from "tss-react/mui";Next.js Integration:
import { NextAppDirEmotionCacheProvider } from "tss-react/next/appDir";
import { createEmotionSsrAdvancedApproach } from "tss-react/next/pagesDir";DSFR Integration:
import { tss, useStyles } from "tss-react/dsfr";CSS Utilities:
import { createCssAndCx, createUseCssAndCx } from "tss-react/cssAndCx";Compatibility Mode:
import { createTss, createMakeStyles, createWithStyles } from "tss-react/compat";
import { makeStyles, withStyles } from "tss-react/mui-compat";CommonJS:
const { createTss, tss, useStyles } = require("tss-react");import { tss } from "tss-react";
// Simple component styling
const useStyles = tss.create({
root: {
backgroundColor: "red",
color: "white",
padding: 16
},
button: {
fontSize: 18,
"&:hover": {
backgroundColor: "darkred"
}
}
});
function MyComponent() {
const { classes } = useStyles();
return (
<div className={classes.root}>
<button className={classes.button}>Click me</button>
</div>
);
}TSS-React is built around several key architectural components:
createTss() creates customized TSS instances with context and plugin supportFoundation functionality for creating type-safe, dynamic styles. The TSS system provides chainable methods for adding parameters, names, and nested selectors.
function createTss<Context>(params: {
useContext: () => Context;
usePlugin?: UsePlugin<Context, any>;
}): { tss: Tss<Context, {}, never, {}, never> };
interface Tss<Context, Params, RuleNameSubsetReferencableInNestedSelectors, PluginParams, ExcludedMethod> {
create<RuleName extends string>(
cssObjectByRuleNameOrGetCssObjectByRuleName: CssObjectByRuleNameOrGetCssObjectByRuleName<Context, Params, RuleNameSubsetReferencableInNestedSelectors, RuleName>
): UseStyles<Context, Params, RuleName, PluginParams>;
withParams<NewParams extends Record<string, unknown>>(): Tss<Context, NewParams, RuleNameSubsetReferencableInNestedSelectors, PluginParams, ExcludedMethod | "withParams">;
withName(name: string | Record<string, unknown>): Tss<Context, Params, RuleNameSubsetReferencableInNestedSelectors, PluginParams, ExcludedMethod | "withName">;
}React hook-based styling API compatible with Material-UI v4 patterns. Provides theme integration and dynamic style generation.
function createMakeStyles<Theme>(params: {
useTheme: () => Theme;
cache?: EmotionCache;
}): {
makeStyles<Params = void>(params?: { name?: string; uniqId?: string }): (
cssObjectByRuleNameOrGetCssObjectByRuleName: CSSObjectByRuleName | ((theme: Theme, params: Params) => CSSObjectByRuleName)
) => (params: Params) => { classes: Record<string, string>; cx: Cx; css: Css; theme: Theme };
TssCacheProvider: React.ComponentType<{ children: ReactNode }>;
};Higher-order component pattern for injecting styles into React components. Supports both function and class components with full TypeScript integration.
function createWithStyles<Theme>(params: {
useTheme: () => Theme;
cache?: EmotionCache;
}): {
withStyles<Component, Props, CssObjectByRuleName>(
Component: Component,
cssObjectByRuleNameOrGetCssObjectByRuleName: CssObjectByRuleName | ((theme: Theme, props: Props, classes: Record<string, string>) => CssObjectByRuleName)
): ComponentType<Props>;
};Specialized integration for Material-UI applications with theme support and style overrides compatibility.
// Pre-configured MUI instances
const tss: Tss<{ theme: Theme }, {}, never, MuiThemeStyleOverridesPluginParams, never>;
const makeStyles: MakeStylesFunction<Theme>;
const withStyles: WithStylesFunction<Theme>;
const useStyles: UseStyles<{ theme: Theme }, {}, string, MuiThemeStyleOverridesPluginParams>;
function useMuiThemeStyleOverridesPlugin(params: {
classes: Record<string, string>;
theme: MuiThemeLike;
muiStyleOverridesParams?: MuiThemeStyleOverridesPluginParams;
css: Css;
cx: Cx;
name?: string;
}): Record<string, string>;Server-side rendering utilities for Next.js applications supporting both App Router and Pages Router patterns.
// App Router support
function NextAppDirEmotionCacheProvider(props: NextAppDirEmotionCacheProviderProps): JSX.Element;
interface NextAppDirEmotionCacheProviderProps {
options: Omit<OptionsOfCreateCache, "insertionPoint"> & { prepend?: boolean };
CacheProvider?: React.Provider<EmotionCache>;
children: ReactNode;
}
// Pages Router support
function createEmotionSsrAdvancedApproach(
options: Omit<OptionsOfCreateCache, "insertionPoint"> & { prepend?: boolean },
CacheProvider?: Function
): {
withAppEmotionCache<AppComponent>(App: AppComponent): AppComponent;
augmentDocumentWithEmotionCache(Document: NextComponentType): void;
};Low-level CSS generation and class manipulation utilities for advanced use cases.
function createCssAndCx(params: { cache: EmotionCache }): {
css: Css;
cx: Cx;
};
function createUseCssAndCx(params: {
useCache: () => EmotionCache;
}): {
useCssAndCx(): { css: Css; cx: Cx };
};
function mergeClasses<T extends string, U extends string>(
classesFromUseStyles: Record<T, string>,
classesOverrides: Partial<Record<U, string>> | undefined,
cx: Cx
): Record<T, string> & Partial<Record<Exclude<U, T>, string>>;Global CSS injection and animation keyframe support built on Emotion primitives.
function GlobalStyles(props: { styles: CSSInterpolation }): JSX.Element;
function keyframes(template: TemplateStringsArray, ...args: CSSInterpolation[]): string;
function keyframes(...args: CSSInterpolation[]): string;French Government Design System integration with dark mode detection. Provides pre-configured TSS instance with theme context.
// Pre-configured DSFR instances with dark mode context
const tss: Tss<{ isDark: boolean }, {}, never, {}, never>;
const useStyles: UseStyles<{ isDark: boolean }, {}, string, {}>;Compatibility layer providing alternative withStyles implementation for specific use cases and migration scenarios.
function createMakeAndWithStyles<Theme>(params: {
useTheme: () => Theme;
cache?: EmotionCache;
}): {
makeStyles: MakeStylesFunction<Theme>;
withStyles: WithStylesFunction<Theme>;
TssCacheProvider: React.ComponentType<{ children: ReactNode }>;
};React context provider for managing Emotion cache instances across the component tree. Ensures proper style injection and cache isolation.
/**
* React context provider for Emotion cache
* Ensures proper CSS-in-JS style injection and hydration
*/
function TssCacheProvider(props: {
children: ReactNode;
}): JSX.Element;Usage Examples:
import { TssCacheProvider } from "tss-react";
import createCache from "@emotion/cache";
// Basic usage with default cache
function App() {
return (
<TssCacheProvider>
<MyAppComponents />
</TssCacheProvider>
);
}
// Custom cache configuration
const customCache = createCache({
key: "my-app",
prepend: true, // Insert styles at beginning of head
speedy: process.env.NODE_ENV === "production"
});
function AppWithCustomCache() {
return (
<TssCacheProvider value={customCache}>
<MyAppComponents />
</TssCacheProvider>
);
}
// SSR setup with cache provider
import { CacheProvider } from "@emotion/react";
function ServerApp({ cache }: { cache: EmotionCache }) {
return (
<CacheProvider value={cache}>
<TssCacheProvider>
<MyAppComponents />
</TssCacheProvider>
</CacheProvider>
);
}interface CSSObject extends CSSObject_base {
label?: string;
}
interface Css {
(template: TemplateStringsArray, ...args: CSSInterpolation[]): string;
(...args: CSSInterpolation[]): string;
}
type Cx = (...classNames: CxArg[]) => string;
type CxArg =
| string
| number
| boolean
| undefined
| null
| { [className: string]: boolean | undefined | null };
type CSSInterpolation = CSSObject | string | number | false | null | undefined;