Change the Heroicons SVG stroke width in React
By Flavio Copes
How to change the stroke width of Heroicons in a React app, by overriding stroke-width with CSS on the svg path or passing strokeWidth to the component.
To render Heroicons with a thinner line in React, pass a strokeWidth prop to the outline icon component. On the first 1.0 releases that prop did nothing, and a CSS rule on the SVG path was the way. Both are below.
Here’s how I found out.
I was using Heroicons in a Next.js app and they conveniently package the icons as React components.
One thing I wanted to do was customize the stroke width, so they rendered thinner.
I looked how to do that within the JSX, maybe with a prop, but I couldn’t find a way.
I could import the SVG directly from the site, but I liked the React components approach.
For some reason I assumed setting a global CSS property directly didn’t work, as it was hardcoded in the SVG, but it actually worked:
svg path {
stroke-width: 1;
}
Why does this work?
At the time (@heroicons/react 1.0.1) the outline icons shipped with stroke-width="2" hardcoded on their path element. That’s what I thought would win.
But in SVG, attributes like stroke-width are presentation attributes, and they sit at the very bottom of the CSS cascade. Any matching CSS rule beats them, no matter how low its specificity.
So a plain svg path selector is enough to override the value baked into the icon.
You can use decimal values too. stroke-width: 0.8 renders an even thinner line.
The prop works now
Since version 1.0.2 the components put strokeWidth on the svg element and spread your props after it, so the prop I was looking for exists. With the current 2.x release:
import { BellIcon } from '@heroicons/react/24/outline'
<BellIcon strokeWidth={1} className="size-6" />
The 2.x outline icons default to 1.5, so 1 is visibly thinner. Decimals work here too.
The CSS rule still works with 2.x, and it’s handy when you want every icon in a component tree thinner without touching each one.
Scope the selector
The rule above targets every SVG path on the page. That includes logos, illustrations, and any other icon set you use. You probably don’t want that.
A class keeps the change contained:
.icon-thin path {
stroke-width: 1;
}
The components forward props to the underlying svg element, so you can pass className directly:
<PencilIcon className='icon-thin' />
Now only the icons you mark get the thinner stroke.
Watch out for solid icons
Heroicons come in two sets: outline and solid.
Only the outline icons are drawn with strokes. The solid ones are filled shapes, so strokeWidth / stroke-width has no effect on them.
If you apply this technique and nothing changes, check which set you imported. Switching to the outline variant fixes it.
Want me to talk about your product? You can sponsor this site.