# How to Customize the Icon Registry with Custom SVG Icons in Astryx

> Learn how to customize the Astryx icon registry by registering your own custom SVG icons using React Server Components and client-side code.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-14

---

**You can customize Astryx’s icon registry by calling `registerIcons()` with a mapping of semantic names to React SVG nodes, which overrides the defaults defined in [`defaultIcons.tsx`](https://github.com/facebook/astryx/blob/main/defaultIcons.tsx) and works in both React Server Components and client-side code.**

Astryx (facebook/astryx) provides a global icon registry that maps semantic names like `close`, `menu`, and `search` to React nodes. By default, this registry is populated with lightweight inline SVGs located in [`packages/core/src/Icon/defaultIcons.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Icon/defaultIcons.tsx). To replace these defaults or add new icon names, you register custom icons through the `registerIcons` helper exported from [`packages/core/src/Icon/globalIconRegistry.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Icon/globalIconRegistry.tsx).

## Understanding the Global Icon Registry

The registry lives at module-level in [`globalIconRegistry.tsx`](https://github.com/facebook/astryx/blob/main/globalIconRegistry.tsx) and contains no `use client` directive, making it safe to use in React Server Components (RSC) as well as client components. It stores a plain JavaScript object that maps `IconName` keys to `ReactNode` values.

When you call `registerIcons(customIcons)`, the function merges your definitions into the global registry. Later calls overwrite earlier entries for the same name, allowing you to layer multiple icon packs or theme-specific overrides.

## Creating Custom Icon Definitions

Define a plain object that conforms to the `IconRegistry` type (or `Partial<IconRegistry>` for selective overrides). Each key must be a member of the `IconName` union type, and each value should be an inline `<svg>` element.

```tsx
// src/custom-icons.tsx
import type { IconRegistry } from '@astryxdesign/core/Icon/globalIconRegistry';

export const customIcons: Partial<IconRegistry> = {
  // Override an existing semantic name
  menu: (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      width="1em"
      height="1em"
      aria-hidden
    >
      <path d="M4 6h16M4 12h16M4 18h16" />
    </svg>
  ),

  // Add a brand-specific icon
  logo: (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      viewBox="0 0 48 48"
      fill="currentColor"
      width="1em"
      height="1em"
      aria-hidden
    >
      <path d="M24 4L4 44h40L24 4z" />
    </svg>
  ),
};

```

## Registering Icons at Application Startup

Call `registerIcons()` once in your root layout or a top-level provider component that runs before other Astryx components render. This ensures the custom icons are available throughout the component tree.

```tsx
// src/app/root-layout.tsx
import { registerIcons } from '@astryxdesign/core/Icon';
import { customIcons } from '@/custom-icons';

// Register once before any components render
registerIcons(customIcons);

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return <>{children}</>;
}

```

Because the registry is a plain object, you can safely call `registerIcons` multiple times to merge different icon packs. The last registration wins for any duplicate keys.

## Using Custom Icons in Components

Once registered, all components using the `<Icon>` component or the `getIcon` helper will resolve your custom SVGs automatically. Unregistered names fall back to the built-in defaults from [`defaultIcons.tsx`](https://github.com/facebook/astryx/blob/main/defaultIcons.tsx).

```tsx
import { Icon } from '@astryxdesign/core/Icon';

export function Header() {
  return (
    <header>
      {/* Renders the custom "menu" SVG defined above */}
      <Icon name="menu" size="large" />
    </header>
  );
}

```

To retrieve an icon programmatically as a React node:

```tsx
import { getIcon } from '@astryxdesign/core/Icon';

const customLogo = getIcon('logo'); // Returns the ReactNode from customIcons

```

## Advanced: Extending IconName Types

If you add brand-specific icons (like `logo` in the example above) that are not part of the default `IconName` union, you can extend the type in your own type definition for TypeScript autocomplete, or cast the key as `any` if strict typing is not required.

## Summary

- **Register once** using `registerIcons()` from [`packages/core/src/Icon/globalIconRegistry.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Icon/globalIconRegistry.tsx) before rendering dependent components.
- **Provide inline SVGs** as React nodes mapped to semantic `IconName` keys in a `Partial<IconRegistry>` object.
- **Override selectively** by including only the keys you want to replace; unregistered names fall back to [`defaultIcons.tsx`](https://github.com/facebook/astryx/blob/main/defaultIcons.tsx).
- **Merge multiple packs** by calling `registerIcons` repeatedly—later calls overwrite earlier entries.
- **Access anywhere** via the `<Icon>` component or `getIcon()` helper, with full support for React Server Components.

## Frequently Asked Questions

### Can I use the custom icon registry in React Server Components?

Yes. The registry in [`globalIconRegistry.tsx`](https://github.com/facebook/astryx/blob/main/globalIconRegistry.tsx) lives at module-level and contains no `use client` directive, so it works in both React Server Components and client-side code without hydration issues.

### How do I reset the icon registry to its default state?

Import `resetIcons` from [`packages/core/src/Icon/globalIconRegistry.tsx`](https://github.com/facebook/astryx/blob/main/packages/core/src/Icon/globalIconRegistry.tsx) and call it to restore the original mappings from [`defaultIcons.tsx`](https://github.com/facebook/astryx/blob/main/defaultIcons.tsx). This is useful for testing or when switching themes dynamically.

### What happens if I register an icon name that already exists?

Later calls to `registerIcons` overwrite earlier entries for the same key. Because the registry is a plain JavaScript object, you can layer multiple icon packs by calling `registerIcons` multiple times, with the last registration taking precedence.

### Do I need to import my custom icons in every component?

No. Once you call `registerIcons` in your root layout or provider, the mappings are available globally. Any component using `<Icon name="..." />` or `getIcon()` will automatically resolve the custom SVGs without additional imports.