npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cdx-ui/icons

v0.0.1-alpha.15

Published

Cross-platform icon library for CDX UI, built on [Material Symbols](https://fonts.google.com/icons) (outlined style, weight 400, optical size 24). Renders via `react-native-svg` and targets iOS, Android, and Web from a single codebase.

Readme

@cdx-ui/icons

Cross-platform icon library for CDX UI, built on Material Symbols (outlined style, weight 400, optical size 24). Renders via react-native-svg and targets iOS, Android, and Web from a single codebase.

~3,800+ Material Symbols icons with outlined/filled variants, plus support for custom SVGs.

Installation

pnpm add @cdx-ui/icons

Peer dependencies

| Package | Version | | ------------------ | ----------------------------------- | | react | ^18.2.0 \|\| ^19.0.0 | | react-native | >=0.76.0 (optional) | | react-native-svg | ^13.0.0 \|\| ^14.0.0 \|\| ^15.0.0 |

Usage

import { Home, Favorite, Settings } from '@cdx-ui/icons';

// Outlined (default)
<Home size={24} color="blue" />

// Filled variant
<Favorite size={24} color="red" filled />

// Toggle between variants
<Home filled={isActive} />

Each icon is a forwardRef component that accepts all standard SvgProps plus the props below.

Props

| Prop | Type | Default | Description | | -------------------- | ------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | size | number \| string | 24 | Sets both width and height. | | color | string | 'currentColor' | Fill color applied to the icon. | | filled | boolean | false | Renders the filled variant when true. Falls back to outlined if no filled data exists. | | accessibilityLabel | string | — | When provided, the icon becomes informative (accessible={true}, accessibilityRole="image"). When omitted, the icon is decorative by default. | | data-testid | string | — | Forwarded to the root <Svg> element for testing. |

All other props are spread onto the root <Svg> element, including standard React Native accessibility props.

Naming conventions

Every icon is available under three export patterns:

| Pattern | Example | Use case | | ---------- | ---------- | ----------------------------------------------- | | PascalCase | Home | Primary import | | Suffixed | HomeIcon | Avoids collision with your own Home component | | Prefixed | CdxHome | Namespace when mixing multiple icon libraries |

import { Home } from '@cdx-ui/icons';
import { HomeIcon } from '@cdx-ui/icons';
import { CdxHome } from '@cdx-ui/icons';

Aliases

Icons can have metadata-driven aliases defined in icon-metadata.json. Aliases let you reference the same underlying icon under alternative names — useful for legacy compatibility, domain-specific terminology, or aligning with names used by other icon sets. The generation script produces alias re-exports alongside the standard exports, so aliases are zero-cost at runtime.

Each entry in icon-metadata.json maps a base icon name (matching its SVG filename) to an array of aliases. An alias can be a plain string or an object with deprecated: true and a deprecationReason to flag names that should be migrated away from.

// icon-metadata.json
{
  "home": {
    "aliases": [
      "house",
      {
        "name": "old-home-icon",
        "deprecated": true,
        "deprecationReason": "Renamed to Home",
      },
    ],
  },
  "settings": {
    "aliases": ["gear", "preferences"],
  },
}

The config above produces the following behavior:

  • House, HouseIcon, and CdxHouse all resolve to the Home icon
  • Gear and Preferences resolve to the Settings icon
  • OldHomeIcon resolves to Home but shows a @deprecated Renamed to Home JSDoc warning in your editor, nudging consumers toward the canonical name
import { House } from '@cdx-ui/icons'; // alias → Home
import { Gear } from '@cdx-ui/icons'; // alias → Settings
import { OldHomeIcon } from '@cdx-ui/icons'; // deprecated alias → Home (editor warning)

Aliases that collide with an existing base icon name are silently skipped during generation to avoid duplicate exports.

Accessibility

Icons are decorative by default — hidden from assistive technology when no accessibilityLabel is provided. This is the correct behavior for icons next to text labels or inside labeled containers.

// Decorative (default) — screen readers skip this
<Home size={20} color={theme.colors.icon} />

// Informative — screen readers announce "Home, image"
<Home size={20} accessibilityLabel="Home" />

| Scenario | What to do | | --------------------------------- | ----------------------------------------------------------------- | | Icon next to a text label | Leave as default (decorative) | | Icon inside a labeled Button | Leave as default — the button's label covers it | | Standalone icon conveying meaning | Add accessibilityLabel describing the icon's purpose in context | | Icon-only button | Label the Pressable wrapper, not the icon |

Cross-platform behavior:

  • iOS (VoiceOver): Announced as "{label}, image"
  • Android (TalkBack): Announced as "{label}, graphic"
  • Web (React Native Web): Renders role="img" + aria-label

React Native >=0.76 aliases aria-label to accessibilityLabel, so either prop works.

For full details, see 08-accessibility.md.

Custom icons

Place custom SVGs in icons/custom/. The generation script reads from both icons/material/outlined/ and icons/custom/, so custom icons are treated identically to Material Symbols icons.

  • Use {name}.svg for the outlined variant
  • Optionally add {name}-fill.svg for a filled variant
  • Custom icons should use viewBox="0 -960 960 960" for consistency, or the generation script will use the SVG's own viewBox

Development

Downloading Material Symbols SVGs

SVGs are fetched directly from the Google Fonts CDN by a custom download script (scripts/download-icons.ts). The script queries Google's metadata API for the active icon list, then downloads only the outlined style (weight 400, opsz 24) with both fill states. Downloaded SVGs are not checked into git.

pnpm --filter @cdx-ui/icons download-icons

This downloads ~7,600 SVGs (~3,800 icons × 2 fill states) to icons/material/outlined/. Pass --clean to re-download from scratch instead of skipping existing files.

Generating icon components

The generation script (scripts/generate-icons.ts) reads SVGs from both icons/material/outlined/ and icons/custom/, parses them with svgson, and writes TypeScript files to src/icons/ and src/aliases/.

pnpm --filter @cdx-ui/icons generate

Generated files include:

  • src/icons/{name}.ts — one file per icon with both outlined and filled path data
  • src/icons/index.ts — barrel export of all icons
  • src/aliases/aliases.ts — metadata-driven legacy name mappings
  • src/aliases/suffixed.ts{Name}Icon exports for every icon and alias
  • src/aliases/prefixed.tsCdx{Name} exports for every icon and alias

Each generated icon file includes a base64-encoded @preview JSDoc tag, so hovering over an icon import in your editor shows a visual preview.

Building

pnpm --filter @cdx-ui/icons build

This runs clean -> generate -> bob build. Output goes to lib/ with three targets:

  • lib/commonjs/ — CJS modules
  • lib/module/ — ESM modules
  • lib/typescript/ — per-file .d.ts declarations

The package is compiled by react-native-builder-bob, consistent with all other workspace packages. Metro resolves the react-native field (src/index.ts) during development, so rebuilding is only needed for publishing or non-Metro consumers.

Package structure

icons/
├── icons/
│   ├── material/outlined/     # Downloaded SVGs (not checked in)
│   └── custom/                # Hand-authored custom SVGs
├── scripts/
│   ├── download-icons.ts      # Downloads outlined SVGs from Google Fonts CDN
│   └── generate-icons.ts      # SVG → TypeScript generation script
├── src/
│   ├── icons/                 # Generated icon components
│   ├── aliases/               # Generated alias re-exports
│   ├── createCdxIcon.ts       # Factory function
│   ├── defaultAttributes.ts   # SVG defaults (viewBox, fill)
│   ├── types.ts               # TypeScript types
│   └── index.ts               # Main entry point
├── icon-metadata.json         # Alias and deprecation metadata
├── package.json
├── tsconfig.json
└── tsconfig.build.json

src/icons/ and src/aliases/ contain generated files (gitignored except for .gitkeep sentinels).

Architecture

The package follows the patterns established by lucide-react-native, adapted for Material Symbols. Key differences:

  • Fill-based icons — Material Symbols icons use fill exclusively (no stroke attributes). The color prop maps to fill.
  • 960x960 coordinate systemviewBox="0 -960 960 960" instead of Lucide's 0 0 24 24. The size prop controls rendered dimensions; the viewBox handles internal coordinates.
  • Outlined/filled variants — Each icon bundles both variants via the filled prop, modeling Material Symbols' fill axis. This halves the export count vs. separate components.
  • Decorative by default — Icons are hidden from assistive technology unless accessibilityLabel is provided.
  • OTA compatibilitychildDefaultAttributes explicitly sets fill on every child SVG element, working around an inheritance bug in CodePush/expo-updates.

For the full research and design rationale, see docs/research/lucide-react-native/.