The IconProvider component is a context provider that allows you to pass an
object of icon instances to your application, merged with the 76 icons Once UI
ships built in.An icon is anything that renders an SVG and needs no props — Once UI never
passes any. So icons from react-icons,
lucide, heroicons, or a component you wrote yourself all satisfy it. The
registry is typed structurally, so no icon library appears in your app's types
because of Once UI.
Simple setup
Wrap your app with IconProvider and pass it the icons as props.
Advanced setup
You can create a separate file for all icons, for example icons.ts. We also recommend using a Providers component to wrap your app.
Type-checking your own names
IconName is a union of the built-in names, and Icon accepts nothing else.
Registering icons at runtime does not by itself teach TypeScript about them, so
extend the union by merging into IconLibraryOverrides:Deriving the interface from the object means the two cannot drift: add an icon
to the registry and its name type-checks immediately, remove one and every use
of it becomes a build error.Two things to avoid. Do not annotate the registry as
Record<string, IconType> — that widens the keys to string, which collapses
IconName and lets every typo through. And do not list the names by hand; the
list will fall out of date.
Default icons
Overwrite the default icons used in Once UI components (for example the chevron in the Select component) by providing new icons with the same keys to the IconProvider.
Icon component
The Icon component is a wrapper around icon instances to control their size and color. We recommend
inserting icons through this component.
useIcons
useIcons() returns the merged icon library — the defaults plus whatever the
nearest IconProvider added. Use it when you need to resolve a name to a
component yourself; for rendering, prefer
Icon, which does this for you.Unlike the other context hooks, useIcons() does not throw outside a provider —
it returns the default library, so a component that only needs built-in icons
works with no provider in the tree.
const { icons } = useIcons();
const known = Object.keys(icons);
// Fall back rather than rendering nothing for an unregistered name.
<Icon name={known.includes(name) ? name : "info"} />