@smbdy/icons-react
v0.3.0
Published
Tree-shakeable React icon components for web3 assets
Maintainers
Readme
@smbdy/icons-react
Tree-shakeable React icon components for web3 assets. Built on top of @smbdy/icons.
Install
npm i @smbdy/icons-reactPeer dependency: react ^18 || ^19
Icon Component
The main <Icon> component resolves an alias and renders the matching icon. Frequently used icons are bundled eagerly; others are lazy-loaded via React.lazy with a smooth fade-in.
import { Icon } from '@smbdy/icons-react'
<Icon value="eth" />
<Icon value="eth" mono />
<Icon value="eth" size={48} />
<Icon value="wbnb" /> {/* resolves alias -> bnb */}
<Icon value={1} /> {/* chain ID -> ethereum */}
<Icon value="metamask" type="brand" /> {/* constrain lookup to one namespace */}Props
| Prop | Type | Default | Description |
| ---------- | ------------------------------- | ----------- | -------------------------------------------- |
| value | string \| number | required | Token symbol, chain name, chain ID, or alias |
| type | 'token' \| 'chain' \| 'brand' | auto | Explicitly disambiguate overlapping ids |
| mono | boolean | false | Render the mono (currentColor) variant |
| size | number \| string | 32 | Width and height |
| fallback | ReactNode | placeholder | Rendered while loading or when unknown |
Plus all standard SVGProps<SVGSVGElement> — except ref: <Icon> renders
different root elements depending on the internal path (eager, lazy,
fallback), so a ref has no reliable target and is rejected at the type
level. The direct-import components render a single
<svg> root and forward refs properly.
IconProvider
Without a provider, an unresolved <Icon> renders the placeholder (or your
fallback) and never makes a network request. Mount the provider only when
you want the runtime GitHub fallback.
import { IconProvider } from '@smbdy/icons-react'
;<IconProvider enableFallback branch="v3.0.0">
<App />
</IconProvider>enableFallback is opt-in (defaults to false). When you turn it on,
pin branch to the published tag of @smbdy/icons-react you have
installed — leaving it on the default ("main") means two installs of the
same npm version can render different content depending on when they
fetch. The provider emits a one-time dev warning if you forget.
Why opt-in?
The fallback can fetch from raw.githubusercontent.com at runtime. That
introduces a runtime dependency that isn't visible at install time, leaks
viewed-asset metadata to GitHub, and — with branch: 'main' — produces
version-skewed content. Apps that want any of those tradeoffs must say so
explicitly. Apps that don't get a deterministic bundle by default.
Direct Imports
Import individual icon components for maximum tree-shaking.
import { EthIcon } from '@smbdy/icons-react/tokens'
import { EthereumIcon } from '@smbdy/icons-react/chains'
import { MetamaskIcon } from '@smbdy/icons-react/brands'
;<EthIcon mono size={24} />The per-icon components accept the same mono / size props as <Icon>
and forward refs to their <svg> root.
Choosing <Icon> vs Direct Imports
| You know the icon… | Use | What ships |
| ------------------ | ----------------------------- | --------------------------------------------------------------------------- |
| at build time | <EthIcon /> (direct import) | Only that icon's SVG — production builds tree-shake the rest of the barrel |
| only at runtime | <Icon value={...} /> | The resolver + popular icons eagerly; everything else lazy, per-icon chunks |
Rules of thumb:
- Static UI (a header logo, a fixed "supported networks" row): direct imports. Smallest output, SSR-/RSC-friendly, ref-forwarding.
- Dynamic values (user balances, API-driven token lists):
<Icon>. A handful of popular icons render instantly from the eager bundle; the long tail lazy-loads its own small chunk and fades in over a placeholder. - Importing one icon does not pull in its neighbors — single-icon
imports are guarded by a CI fixture that fails if a second icon's path
data leaks into the bundle. (One nuance: an icon's combined component
imports both its
fullandmonoart; if you only ever render one variant of a build-time-known icon, that's still two small SVGs.)
SSR, Next.js, and React Server Components
All entry points render under react-dom/server without a DOM. What differs
is the client boundary:
@smbdy/icons-reactand/compatare client components — the published files carry"use client", so in the Next.js App Router you can use<Icon>/<Web3Icon>directly inside Server Components without writing a wrapper. Eager icons SSR their full SVG markup; lazy icons SSR the colored placeholder and swap in the real icon after hydration (no layout shift — the placeholder is the layout anchor)./tokens,/chains,/brands, and/framesare directive-free pure components: rendered inside a Server Component they emit static SVG with zero client JavaScript and zero hydration cost. Prefer them for SEO-critical or above-the-fold icons.@smbdy/icons(core) is plain data —getTokenSvg()/getMeta()work anywhere (Node, edge runtimes, workers) and are handy in Route Handlers ornext/ogimage generation.
For custom SSR servers: renderToString/renderToPipeableStream need no
special setup. The lazy fade-in styles are injected client-side in an
insertion effect, so server markup is deterministic across renders.
Production checklist
- Leave the GitHub fallback off (the default) unless you accept a
runtime
raw.githubusercontent.comdependency — and if you enable it, pinbranchto your installed version tag (see IconProvider). - Icons known at build time → direct imports.
monoicons inheritcurrentColor— setcoloron a parent (or the icon itself) rather thanfill.- Adding icons to the library? See
CONTRIBUTING — every asset is a
full/mono/metadata triplet validated bypnpm validate.
Frames
Wrap icons in decorative frames (e.g. staked asset badges).
import { FrameWrapper } from '@smbdy/icons-react/frames'
import { Icon } from '@smbdy/icons-react'
;<FrameWrapper frame="stk" size={48}>
<Icon value="eth" />
</FrameWrapper>Available frames: a, stk, stkwa, wa
v1 Compatibility
The Web3Icon component provides a migration path from @bgd-labs/react-web3-icons.
import { Web3Icon } from '@smbdy/icons-react/compat'
<Web3Icon symbol="ETH" />
<Web3Icon chainId={1} />
<Web3Icon symbol="ETH" mono />
<Web3Icon symbol="ETH" assetTag="stk" />Import Paths
| Path | Exports |
| --------------------------- | --------------------------- |
| @smbdy/icons-react | Icon, IconProvider |
| @smbdy/icons-react/tokens | Individual token components |
| @smbdy/icons-react/chains | Individual chain components |
| @smbdy/icons-react/brands | Individual brand components |
| @smbdy/icons-react/frames | FrameWrapper |
| @smbdy/icons-react/compat | Web3Icon |
