Phosphor Icons

1,512 icons, each in six hand-drawn weights

Official site
MIT License1,512 icons@phosphor-icons/react

Overview

Phosphor Icons gives each of its 1,512 icons six weights (thin, light, regular, bold, fill and duotone), selected with a single weight prop. Unlike Lucide or Tabler, Phosphor does not use SVG strokes: every weight is a separately drawn filled outline on a 256×256 canvas. The weights end up better balanced than a stroke slider would make them, but line thickness is limited to those four line weights.

At a Glance

Version examined
@phosphor-icons/react 2.1.10
Icons in the package
1,512 × 6 weights
Icons available in Icony
1,512 (plus the Filled page)
Canvas
256×256 viewBox
Drawing model
Filled outlines only (fill="currentColor"), no strokes
Default size
1em (follows the surrounding font size)
Rendered House SVG (regular)
387 bytes (248 gzipped)
License
MIT

Design language: weights, not strokes

A rendered Phosphor icon has viewBox="0 0 256 256", fill="currentColor" and no stroke attributes at all. What looks like a line is the space between two filled contours. For House, each weight is a different path: thin, light, regular and bold move the contours apart by different amounts, fill is a solid shape, and duotone stacks a background shape at opacity="0.2" under the regular outline.

You can read the line weights straight from the House paths by comparing the outer and inner wall contours: thin is 8 units thick, light 12, regular 16 and bold 24. On a 256-unit canvas rendered at 24px that is roughly 0.75px, 1.1px, 1.5px and 2.25px. Regular therefore matches the 1.5px line of Heroicons Outline, not the 2px default of Lucide and Tabler.

Measured on House, the rendered SVG is 427 bytes for thin, 436 for light, 387 for regular, 414 for bold, 324 for fill and 521 for duotone. The large canvas lets Phosphor use whole-number coordinates (M219.31,108.68l-80-80…) and gentle 8- to 16-unit corner radii, which gives the set its friendly, slightly rounded feel.

So there is no continuous stroke slider. Icony’s stroke control, for example, maps its 0.5–4 range onto Phosphor weights: 1 or below becomes thin, up to 1.75 becomes light, up to 2.5 becomes regular, and anything higher becomes bold. Duotone is left out of that mapping because it is a different style, not a heavier line.

Strengths and weaknesses

  • Every icon has every weight. You can use light icons in body content, bold icons in a toolbar and fill for selected states without mixing libraries.
  • Duotone gives a two-tone look using only currentColor and opacity, so it still follows your text color and dark mode.
  • IconContext sets defaults once, so you don’t repeat props on every icon.
  • Each icon costs more. Its definition file carries all six weights: defs/House.es.js is 2,662 bytes (772 gzipped), even if you only render regular. That is roughly double what a single Lucide icon costs.
  • There is no fine stroke control. If your design system specifies a 1.25px line, Phosphor cannot match it exactly.
  • The default size is 1em. Icons silently change size when the parent font size changes, so set size or an IconContext default.

Situations where Phosphor is a poor fit

  • You ship hundreds of icons on a single route on a tight bundle budget. A stroke set with one style per module is lighter.
  • Your design tokens define stroke width as an exact value that must match other line art.
  • You need very specialized or brand icons in bulk; Tabler’s catalog is much larger.

Phosphor vs. Lucide

At 24px, Phosphor regular is lighter than Lucide’s default: its lines are 1.5px against Lucide’s 2px. Set Lucide to strokeWidth={1.5} and they match closely, but the construction still differs.

Lucide lets you pick any stroke value and keeps one small module per icon. Phosphor offers fewer choices, but each weight is drawn by hand, so small counters and joins stay open at bold weights where a thickened stroke would clog. If you need solid states, Phosphor wins outright, because Lucide has no fill style.

Naming differs too. Phosphor uses descriptive nouns (House, MagnifyingGlass, Gear), not actions (Home, Search, Settings). Search by object, not by function.

Installation gotchas

  • Use the scoped @phosphor-icons/react package. The older phosphor-react package is the previous generation of the library; do not install both.
  • The default entry uses React context, so in the Next.js App Router it only works inside client components. For server components, import from @phosphor-icons/react/ssr, which renders without context (and therefore ignores IconContext).
  • Every icon is exported twice, as House and HouseIcon. Use the …Icon form if the short name clashes with one of your components.
  • The alt prop renders a <title> inside the SVG. Phosphor does not add aria-hidden, so set it on decorative icons.
  • For right-to-left layouts, mirrored flips the icon with transform="scale(-1, 1)". Use it for arrows and chat bubbles, not for icons with text or clocks.
// app/page.tsx — a server component in the Next.js App Router
import { House } from '@phosphor-icons/react/ssr';

export default function Page() {
  return <House size={24} weight="bold" aria-hidden="true" />;
}

License: MIT, across all six weights

Phosphor is MIT-licensed, and all six weights (thin, light, regular, bold, fill, duotone) ship under that one license, so switching weights never changes your obligations. Keep the license notice with the code you distribute; no visible credit is required in your product.

Key Features

  • Six weights per icon: thin, light, regular, bold, fill, duotone
  • Each weight drawn separately on a 256×256 canvas
  • IconContext sets default size, color and weight for a subtree
  • Separate /ssr entry for React Server Components
  • mirrored prop for right-to-left layouts
  • MIT license

Installation

npm install @phosphor-icons/react

Usage Example

Basic React usage with Phosphor Icons

'use client';
import { IconContext, House, MagnifyingGlass, Gear } from '@phosphor-icons/react';

export function Toolbar() {
  return (
    // Defaults for every Phosphor icon below
    <IconContext.Provider value={{ size: 20, weight: 'light', color: 'currentColor' }}>
      <House aria-hidden="true" />
      <MagnifyingGlass weight="bold" aria-hidden="true" />
      <Gear weight="duotone" aria-hidden="true" />
    </IconContext.Provider>
  );
}

Best For

Design systems with a clear weight hierarchyConsumer and mobile-style web appsIllustrative UI where duotone adds depthProducts that need outline and filled states for every icon

Common Questions

Why doesn’t strokeWidth do anything on Phosphor icons?

There is no stroke. Phosphor draws lines as filled shapes, so thickness is chosen with weight instead.

Does importing one weight tree-shake the others?

No. Each icon’s weights live together in one definition map, so all six ship with the icon. The cost is paid per icon you import, not for the whole library.

What is the difference between this page and Phosphor Filled?

Same package, same icons. This page covers the weight system as a whole. The Filled page is about the fill weight: how it is drawn and how to use solid icons well.

Explore Phosphor Icons in Icony

Icony has 1,512 icons from Phosphor Icons. Browse them, change their color and size, and download PNG or SVG for free.

Open in Icony

Related Libraries

Related Guides