phosphor-vector-icons
v0.1.6
Published
Font-based Phosphor icon renderer for React web + React Native.
Maintainers
Readme
phosphor-vector-icons 
Font-based Phosphor icon renderer for React web and React Native, using a unified API:
import { Icon } from "phosphor-vector-icons";
<Icon
name="user"
size={32}
color="red"
weight="fill"
/>The icon glyph is selected at runtime via a generated glyphMap.json (no per-icon imports).
Installation
npm install phosphor-vector-iconsUsage
import { Icon } from "phosphor-vector-icons";
export function Example() {
return <Icon name="user" size={24} color="black" weight="regular" />;
}Weights
Supported weights:
thinlightregularboldfillduotone
By default every weight is available. Call configure once at app startup to choose which weights the component resolves. A weight outside that list falls back to Regular when Regular is included, otherwise to the first configured weight. Import a weight entry to include only that TTF in the compiled bundle.
import { Icon, configure } from "phosphor-vector-icons";
configure({ weights: ["regular"] });
export function Example() {
return <Icon name="user" size={24} color="black" />;
}configure({ weights: ["regular", "fill"] });On the web, configure injects @font-face rules for the resolved weight. The root import still references every TTF. In Expo, require only the files you register:
import { configure, FONT_FAMILY } from "phosphor-vector-icons";
import * as Font from "expo-font";
configure({ weights: ["regular"] });
Font.useFonts({
[FONT_FAMILY.regular]: require("phosphor-vector-icons/fonts/Phosphor-Regular.ttf")
});To omit unused TTF files from the compiled JS bundle, import a weight entry instead of the root package:
import { Icon } from "phosphor-vector-icons/regular";Backend-driven payloads
Your backend can send:
{
"icon": "user",
"weight": "regular"
}Then render it without importing individual icons:
import { Icon } from "phosphor-vector-icons";
type Payload = { icon: string; weight: "thin" | "light" | "regular" | "bold" | "fill" | "duotone" };
export function BackendIcon({ payload }: { payload: Payload }) {
return <Icon name={payload.icon as any} weight={payload.weight} size={24} color="black" />;
}If the icon name is unknown at runtime, the component renders null (no crash).
Architecture (data flow)
The rendering pipeline is:
name -> glyphMap -> unicode char -> font glyph -> rendered <Icon />
Concretely:
- A generator reads the latest Phosphor SVGs from
@phosphor-icons/core. - It builds TTF fonts (per weight) and a
glyphMap.jsonmapping icon names to codepoints. - The runtime components look up
glyphMap[name], convert the codepoint to a Unicode character, and render that character using the matching font family.
Scripts
Generate committed artifacts (fonts + glyphMap + IconName.ts):
pnpm generate-iconsRun tests:
pnpm testContributor examples
Run the package in a real app from this repo (after pnpm install and pnpm build):
pnpm generate-icons # if fonts are missing
pnpm build
# React web (Vite)
pnpm dev:react
# Expo / React Native
pnpm dev:expoOr from the example folders:
pnpm --filter phosphor-icons-react-example dev
pnpm --filter phosphor-icons-expo-example startpackages/react/example— Vite apppackages/react-native/example— Expo app (expo-fontloads the TTFs)
