If you're using a built-in components like div or span and you want to allow the user to customize the styles via some props.

const MyComponent = styled('div')(({ bgColor }) => ({
  backgroundColor: bgColor,
}));

When you're using it like this:

<MyComponent bgColor='red'>

The prop is passed to the real element in the DOM tree as attribute:

And react will complain, something like:

Warning: React does not recognize the `bgColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `bgcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element.

This is why shouldForwardProp exists, to prevent styling props from being passed down and create invalid attribute:

const MyComponent = styled('div', {
  shouldForwardProp: (props) => props !== 'bgColor',
})(({ bgColor }) => ({
  backgroundColor: bgColor,
}));
Answer from NearHuscarl on Stack Overflow
🌐
Medium
medium.com › @darwish.saja › fixing-shouldforwardprop-warnings-in-styled-components-v6-2b288eaa9fcc
Fixing shouldForwardProp Warnings in Styled Components v6 🛠 | by Saja Darwish | Medium
April 14, 2025 - This is a valid custom React prop but is not a valid HTML attribute. If you meant to render a custom attribute, spell it as lowercase `isNav` instead. If you accidentally passed it from a parent component, remove it from the DOM element. This happens when props end up leaking into the DOM. Styled Components v5 used to handle this quietly for us. But in v6, shouldForwardProp is no longer provided by default.
🌐
DEV Community
dev.to › sarahscode › props-are-not-forever-preventing-props-from-being-passed-to-the-dom-with-styled-components-v5-1-l47
Props Are Not Forever: Preventing Props From Being Passed to the DOM with styled-components v5.1 - DEV Community
November 23, 2020 - I recently discovered (thanks to ... and how I plan to use it. shouldForwardProp is a config option that determines if a given prop should be forwarded to the DOM....
🌐
GitHub
github.com › styled-components › styled-components › issues › 4251
StyleSheetManager `shouldForwardProp` does not prevent prop forwarding · Issue #4251 · styled-components/styled-components
January 15, 2024 - styled-components: it looks like an unknown prop "someProp" is being sent through to the DOM, which will likely trigger a React console error. If you would like automatic filtering of unknown props, you can opt-into that behavior via ...
Author   charlie-zv
🌐
Emotion
emotion.sh › docs › styled
Emotion – Styled Components
The as prop is only used by styled ... and forwarded for components. To change this, you can pass a custom shouldForwardProp which returns true for 'as' to forward it or returns false for 'as' to use it and not forward it....
🌐
styled-components
styled-components.com › docs › faqs
styled-components
If you haven't migrated your styling to use transient props ($prefix), you might notice React warnings about styling props getting through to the DOM in v6. To restore the v5 behavior, use StyleSheetManager: import isPropValid from '@emotion/is-prop-valid'; import { StyleSheetManager } from 'styled-components'; function MyApp() { return ( <StyleSheetManager shouldForwardProp={shouldForwardProp}> {/* other providers or your application's JSX */} </StyleSheetManager> ) } // This implements the default behavior from styled-components v5 function shouldForwardProp(propName, target) { if (typeof target === "string") { // For HTML elements, forward the prop if it is a valid HTML attribute return isPropValid(propName); } // For other elements, forward all props return true; }
🌐
GitHub
github.com › emotion-js › emotion › issues › 900
shouldForwardProp in styled component · Issue #900 · emotion-js/emotion
October 8, 2018 - I added { shouldForwardProp: isPropValid } to my styled components in react native to prevent the prop isColored from being forwarded.
Author   timomeh
🌐
GitHub
github.com › styled-components › styled-components › issues › 3541
shouldForwardProp for Transient Props · Issue #3541 · styled-components/styled-components
August 1, 2021 - interface ButtonAttrs { $isCompact?: boolean; } const Button = styled.button<ButtonAttrs>` padding: ${p => p.$isCompact ? '0.5em' : '1em'}; `; const ScaledDownButton = styled(Button).withConfig({ shouldForwardProp: (prop, defaultValidatorFn) => prop !== '$isCompact' && defaultValidatorFn(prop), })<ButtonAttrs>` font-size: ${p => p.$isCompact ?
Author   itayganor
Find elsewhere
🌐
Lightrun
lightrun.com › answers › emotion-js-emotion-shouldforwardprop-in-styled-component
shouldForwardProp in styled component
I added { shouldForwardProp: isPropValid } to my styled components in react native to prevent the prop isColored from being forwarded.
Top answer
1 of 5
62

Yes!

The most basic example of the above would look like this in MUI v5:

const Div = styled("div")(({ primary }) => ({
  backgroundColor: primary ? "palevioletred" : "white",
  color: primary ? "white" : "palevioletred"
}));


render(
  <section>
    <Div>Normal</Div>
    <Div primary>Primary!</Div>
  <section>
);

However, as the React docs say:

The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

So MUI gave us the shouldForwardProp option to tell MUI whether it "should forward the prop" to the root node or not. The above example would look like this using that prop:

const Div = styled("div", {
  shouldForwardProp: (prop) => prop !== "primary"
})(({ primary }) => ({
  backgroundColor: primary ? "palevioletred" : "white",
  color: primary ? "white" : "palevioletred"
}));

render(
  <section>
    <Div>Normal</Div>
    <Div primary>Primary!</Div>
  <section>
);

Explanation

The second argument to the styled function is an options object, one of the things it accepts is shouldForwardProp, which as the docs say, "Indicates whether the prop should be forwarded to the Component". So to remove the unknown prop warning from the console, we tell it not to pass our custom prop to the DOM element with shouldForwardProp: (prop) => prop !== "primary". Now we destructure this prop in the function call that returns our custom styles, and use it in those styles like we would any other function.

If you want to use the global theme styles here as well, just destructure it along with your custom prop(s), ie ({ primary, otherProp, thirdProp, theme }).

Working codesandbox.

MUI v5 styled API docs

2 of 5
31

Here is a fully-working MUI v5 TypeScript example where you can pass custom properties to a styled component:

import React from 'react';
import { Button, styled, Typography } from '@mui/material';

const PREFIX = 'NimbusButton';
const classes = {
    root: `${PREFIX}-root`,
    button: `${PREFIX}-button`
};

interface RootProps {
    textColor?: 'primary' | 'secondary';
    buttonTextColor?: 'primary' | 'secondary';
}

const Root = styled('div', {
    shouldForwardProp: (prop) => prop !== 'textColor' && prop !== 'buttonTextColor',
    name: 'MyThemeComponent',
    slot: 'Root'
})<RootProps>(({ theme, textColor, buttonTextColor }) => ({
    [`& .${classes.root}`]: {
        color: textColor ? theme.palette.primary.main : theme.palette.secondary.main
    },
    [`& .${classes.button}`]: {
        color: buttonTextColor ? theme.palette.primary.main : theme.palette.secondary.main
    }
}));

type OwnProps = {
    textColor: 'primary' | 'secondary';
    buttonTextColor: 'primary' | 'secondary';
    text?: string;
    buttonText: string;
};

const CustomStyledButton: React.FC<OwnProps> = (props) => {
    const { textColor, buttonTextColor, text, buttonText } = props;
    return (
        <Root className={classes.root} textColor={textColor} buttonTextColor={buttonTextColor}>
            {text && <Typography variant={'body1'}>{text}</Typography>}
            <Button className={classes.button}>{buttonText}</Button>
        </Root>
    );
};

export default CustomStyledButton;
🌐
jsDocs.io
jsdocs.io › package › styled-components
styled-components@6.3.5 - jsDocs.io
January 16, 2026 - ForwardedAsTarget extends StyledTarget<R> | void = void · >( props: PolymorphicComponentProps<R, BaseProps, AsTarget, ForwardedAsTarget> ): React.JSX.Element; interface ShouldForwardProp<R extends Runtime> {} (prop: string, elementToBeCreated: StyledTarget<R>): boolean; interface Styled< R extends Runtime, Target extends StyledTarget<R>, OuterProps extends object, OuterStatics extends object = BaseObject ·
🌐
Fabrizio Duroni
fabrizioduroni.it › blog › post › 2025 › 01 › 03 › styled-component-transient-props-type-mapped-type-typescript
Styled Components: create a type to define transient props based on the props interface of another component
January 3, 2025 - Transient props and shouldForwardProp are styled components API let you filter out props that should not be passed to the underlying React node or DOM element.
🌐
MUI
mui.com › system › styled
styled() - MUI System
The utility can be used as a replacement for emotion's or styled-components' styled() utility. It aims to solve the same problem, but also provides the following benefits: It uses a default theme if no theme is available in React context. It supports the theme's styleOverrides and variants to be applied, based on the name applied in the options (can be skipped). It adds support for the the sx prop (can be skipped). It adds by default the shouldForwardProp option (that can be overridden), taking into account: ownerState, theme, sx, and as.
🌐
GitHub
github.com › styled-components › styled-components › issues › 4071
v6: using `styled(Component)` results in `looks like an unknown prop is being sent through to the DOM` · Issue #4071 · styled-components/styled-components
July 2, 2023 - styled-components: it looks like an unknown prop "message" is being sent through to the DOM, which will likely trigger a React console error. If you would like automatic filtering of unknown props, you can opt-into that behavior via ...
Author   zackheil
Top answer
1 of 2
1

In all the APIs that you've used here, you've used them incorrectly. I've annotated the mistakes you've made in this TS Playground link. But I'll add it here as well -

// original
const Thing = styled.div<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

const Thing2 = styled(
  'div',
  // The function takes only one argument so can't take BASE_CONFIG
  // BASE_CONFIG 
)<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

const Thing3 = styled
  .div<{
    isSmallContainer: boolean;
  }>(({ isSmallContainer }) => ({
    // padding: isSmallContainer ? 12 : '16px 32px',
    // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
    padding: isSmallContainer ? "12px" : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }))
  // Not Supported by API
  // .withConfig(BASE_CONFIG);

const Thing4 = styled
  .div<{
    isSmallContainer: boolean;
  }>
  // .withConfig(BASE_CONFIG) Cannot call a generic
  (({ isSmallContainer }) => ({
    // padding: isSmallContainer ? 12 : '16px 32px',
    // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
    padding: isSmallContainer ? "12px" : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }));

const Thing5 = styled("div")
// .withConfig(BASE_CONFIG) // The params are incorrect
.withConfig({ shouldForwardProp: (prop) => prop === "isSmallContainer" ? false : true })
// Already called styled with `div` argument, no need to call again
// .div<{
//   isSmallContainer: boolean;
// }>
<{isSmallContainer: boolean}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));
2 of 2
0
const BASE_IGNORED_PROPS: Array<string | number | symbol> = [
  'isSmallContainer',
];

const BASE_CONFIG: StyledConfig<
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  StyledComponentPropsWithRef<React.ComponentType<any>>
> = {
  shouldForwardProp: (
    prop: string | number | symbol,
    defaultValidatorFn: (prop: string | number | symbol) => boolean
  ) => !BASE_IGNORED_PROPS.includes(prop) && defaultValidatorFn(prop),
};

const Thing = styled.div(({ theme }) => ({
  flex: '0 1 100%',
}));

const ThingInner = styled(Flex).withConfig(BASE_CONFIG)<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  width: '100%',
  padding: isSmallContainer ? 12 : 32,
  paddingBottom: 0,
}));
🌐
Styled-system
styled-system.com › guides › removing-props-from-html
Styled System
import styled from '@emotion/styled' import shouldForwardProp from '@styled-system/should-forward-prop' import { space, color } from 'styled-system' const Box = styled('div', { shouldForwardProp, })(space, color) Unfortunately, Styled Components does not currently support an API to control which props are forwarded to the HTML element. If you'd like to see support for this, please leave a comment on their long-running issue: ... If you're a fan of using the css prop, you can easily control which props are forwarded to the HTML element, just like in any other React component.
🌐
DEV Community
dev.to › mochafreddo › handling-react-warnings-filtering-props-in-styled-components-3233
Handling React Warnings: Filtering Props in Styled Components - DEV Community
June 17, 2024 - .withConfig: This method allows you to configure the styled component. shouldForwardProp: This function filters out the isActive prop, preventing it from being passed to the DOM element.
🌐
GitHub
github.com › styled-components › styled-components › issues › 3427
shouldForwardProp before each styled component? · Issue #3427 · styled-components/styled-components
March 10, 2021 - Hey guys, I'm using styled-components with Next.js (SSR) + babel plugin. I need to pass additional settings to the styled components by withConfig method: const Comp = styled('div').withConfig({ shouldForwardProp: (prop, defaultValidatorFn) => !['hidden'].includes(prop) && defaultValidatorFn(prop), }).attrs({ className: 'foo' })` color: red; &.foo { text-decoration: underline; } `;
Author   marcin-piechaczek
Top answer
1 of 3
20

Use Transient props

TL;DR just prefix your attriibute with $ sign. example $borderColor, $black, $any, $attribute.

If you want to prevent props meant to be consumed by styled components from being passed to the underlying React node or rendered to the DOM element, you can prefix the prop name with a dollar sign ($), turning it into a transient prop.

// typescript example
const BaseButton = styled(Button)<{ $borderColor: string }>`
    border-color: ${({ $borderColor }): string => $borderColor};
`;

// js
const BaseButton = styled(Button)`
    border-color: ${({$borderColor}) => $borderColor}
`;
// usage
<BaseButton $borderColor="red">Button</BaseButton>

2nd method

Checkout shouldForwardProp

const Comp = styled('div').withConfig({
  shouldForwardProp: (prop, defaultValidatorFn) =>
      !['hidden'].includes(prop)
      && defaultValidatorFn(prop),
}).attrs({ className: 'foo' })`
  color: red;
  &.foo {
    text-decoration: underline;
  }
`;

render(
  <Comp hidden draggable="true">
    Drag Me!
  </Comp>
);
2 of 3
2

Your existing code was already right, but react gave you two options :

1) use lower case than snake-case

2) remove the attribute from DOM (you took this approach)

From the code I can see that you need the prop borderColor, but in the custom styling, you separated the props

({borderColor,... rest}) => <Button {...rest} />

You removed the border Color prop but you try to access in styled props the next line.

Instead try to rename the prop to bordercolor if you want warning to go away or just ignore warning.