@andrilla/react-sf
v1.0.0
Published
SF Symbols for React
Readme
React SF Symbols
A complete library of SF Symbols written for React.
What's Included
There are 6,411 symbols in this library, all of which include nine weights.
Installation
deno add @andrilla/react-sfnpx jsr add @andrilla/react-sfpnpm add jsr:@andrilla/react-sfbunx jsr add @andrilla/react-sfyarn add jsr:@andrilla/react-sfUsage
Symbols are exported as default exports due to many of the symbols' names beginning with numbers, or the Number symbol being a reserved name. This means you can choose a name that works for you, but the path is the exact same as in SF Symbols.
import SquareAndPencil from 'react-sf/square.and.pencil'
export function MyComponent() {
return (
<div>
<SquareAndPencil />
</div>
)
}Props
Each symbol is a standard <svg> with the option to choose one of nine weights with the weight prop.
Weights
ultralightthinlightregularmediumsemiboldboldheavyblack
Recommended CSS
So far, this CSS is the easiest way to use the symbols, in my opinion, but I am certainly open to suggestions.
/* Since symbols are intended to be used alongside text,
using currentColor for fill and stroke is a sensible default */
svg {
fill: currentColor;
stroke: currentColor;
stroke-width: 0;
}
/* Very often, these symbols represent actions
and are used in buttons and links. These defaults
properly align the symbol with the text. */
a,
button {
&:has(> svg) {
display: flex;
align-items: center;
justify-content: center;
gap: calc(var(--spacing) * 2);
}
}Ownership
All symbols are created and owned by Apple Inc. and are subject to their terms of use. Only symbols that Apple allows for SVG template export are included in this library.
Frequently Asked Questions
Why not use a single component with a prop to select the icon?
There are 57,699 SVGs in this library. Using a single component would cause a few negative side-effects:
- Performance: Loading all symbols at once would significantly increase initial load time
- Build size: Including all symbols in one component would result in much larger bundle sizes
- TypeScript: Types would be too bulky, making it so slow it would render the types unusable
- Tree shaking: Individual imports allow unused symbols to be completely removed during bundling
Why aren't all sizes (small, medium, and large) included?
Although in a Swift app development environment, having access to all three sizes can be beneficial, in a web environment, the size of an SVG's viewbox is somewhat irrelevant as the visual size scales easily with CSS. Using only one of the sizes also adds a significant benefit in use and performance, since there are only 57,699 SVGs (which is still a very large amount) instead of 173,097.
Will this library ever include the animations from SF Symbols?

Although I would love to include animations at some point, I currently have no idea how adding the animations might work programmatically. There are so many symbols to handle, many with slightly different animations separated by parts and layers that are not included directly in the SVG templates Apple provides. If you have any ideas on how to programmatically separate the single path SVGs into unique paths per part and, ideally, layer, then please let me know.
You may find the built-in Tailwind CSS animations sufficient for most use cases. If not, there are other libraries that you can use to give you a lot of utility, such as Animate.css (a phenomenal, simple, CSS-only solution) or Anime.js (a fast and versatile JavaScript library to animate anything).
Will this library ever include the various color modes in SF Symbols?
Just like with the animations, due to the nature of the SVGs being a single path, creating the hierarchical, palette, or multicolor modes is not possible. Even if we could separate the paths, the uniqueness of each symbol would make it difficult to programmatically apply the correct color to each path. I'm open to suggestions to make this work, though, because it would be invaluable.
Will this library ever offer a gradient mode?
That is a goal. Implementing gradients should be fairly simple, but I want to make sure it's done the best way possible, for ease-of-use and performance. I haven't come up with a great solution for using custom colors with gradients yet, either, and I think this may be important, as fill colors are often best matched to branding, rather than a predefined set of colors. Not to mention, predefining a set of colors would potentially add a lot of bulk to the library.
