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

@seij/common-ui-icons

v0.1.3

Published

This package provides a controlled, extensible, and bundle-friendly icon system for frontend applications.

Readme

@seij/common-ui-icons

This package provides a controlled, extensible, and bundle-friendly icon system for frontend applications.

Its goal is not to expose an icon library, but to expose a stable icon contract that decouples:

  • applications from icon providers (FluentUI, SVGs, others),
  • frontend from backend serialization,
  • usage from implementation.

Problem Statement

In many applications, icons are imported directly from UI libraries (e.g. FluentUI). This creates several structural issues:

  • Icon providers leak everywhere in the codebase.
  • It is impossible to track or govern icon usage.
  • Migrating away from a provider becomes costly.
  • Multiple icon sets cannot be mixed cleanly.
  • Backend-driven UIs cannot safely reference icons.
  • Central registries break tree-shaking and inflate bundles.

This package addresses all of these problems explicitly.

Core Principles

1. Icons are intentions, not assets

Applications never choose where an icon comes from.
They choose what the icon means.

Examples:

  • "add"
  • "delete"
  • "user"
  • "search"

These names form a closed, versioned contract.

2. The contract is frontend-owned and backend-consumed

The backend serializes icon names as strings in DTOs. It does not know about FluentUI, SVGs, or components.

The frontend validates and resolves these strings against its own contract.

3. No global imports, no central switch

Any implementation that imports all icons in one place:

  • breaks tree-shaking,
  • bundles unused icons,
  • couples everything together.

Each icon must live in its own ES module.

4. Resolution is explicit and controlled

Icons are resolved:

  • only through this package,
  • only via known keys,
  • only through a single component.

Applications are not allowed to import icon providers directly.

Architecture

Icon Contract

export const iconNames = ["add", "delete", "user", "search"] as const;
export type IconName = (typeof iconNames)[number];

This is the public API.

  • Closed set
  • Traceable
  • Versionable
  • Serializable

Icon Implementations (isolated)

Each icon is implemented in its own module.

See add.tsx for example.

Icons may come from:

  • FluentUI
  • custom SVGs
  • other libraries

This choice is invisible to consumers.

Loader Mapping (not components)

A Loader maps icons names to dynamic import.

Why loaders:

  • preserves tree-shaking,
  • allows code-splitting,
  • avoids global imports,
  • keeps the contract closed.

A preload function is available to prevent flickering. See comments on the function to know the use cases.

Component

See Icon.tsx

  • imports nothing concrete,
  • only routes to a loader,
  • enforces the contract.
  • uses Suspense with a Placeholder to have deterministic positionning.

Backend integration

This is an example.

type MenuItemDto = { label: string; icon?: string };

The backend sends a string key, nothing more.

In the frontend, decode icon with parseIconName then display icon:

function MenuItem({ dto }: { dto: MenuItemDto }) {
  const iconName = parseIconName(dto.icon);

  return (
    <>
      {iconName && <Icon name={iconName} />}
      {dto.label}
    </>
  );
}

Just after you get the DTOs it's a best practise to use preload

Application-Specific Icons

Applications must not extend the global icon contract.

Two cases:

  • Purely local icons: Stay inside the application as local components.
  • Reusable, product-level icons: Are explicitly promoted into this package by:
    • adding a new contract key,
    • choosing an implementation,
    • documenting usage.

This friction is intentional and healthy.

Governance and Tooling

Recommended enforcement:

  • ESLint rule forbidding direct imports from icon providers.
  • No dynamic registration or plugin system.
  • No fallback magic.

All icons must go through this package.

Explicit Trade-offs

  • Uses React.lazy and Suspense.
  • Slight runtime indirection.
  • Intentional friction when adding icons.

What you gain:

  • clean bundling,
  • provider independence,
  • backend compatibility,
  • traceability,
  • long-term maintainability.

Summary

This system treats icons as a domain language, not as UI assets.

Once that shift is accepted:

  • FluentUI becomes an implementation detail, also SVG or others
  • multiple icon sets coexist safely,
  • backend-driven UIs work naturally,
  • bundles stay minimal,
  • migrations become mechanical.