Is your feature request related to a problem? Please describe.
Currently, there are no guidelines regarding the use of icons in Aurora. As a result, icons are imported and rendered in several different ways throughout the codebase.
While these approaches are functionally equivalent, they introduce unnecessary decisions for developers and make the codebase less predictable. When adding a new icon, it is not always clear which pattern should be used, and different conventions continue to spread over time.
Describe the solution you'd like
Defining a standard approach would improve consistency, reduce cognitive overhead during development and code reviews, and make icon usage easier to understand for new contributors.
As an initial improvement, Aurora could adopt a single convention for importing and rendering icons, such as importing SVGs as React components using the ?react suffix.
This would provide a consistent authoring experience and remove ambiguity around how icons should be used within the codebase.
However, we may take this a step further.
Aurora's long-term goal is not only consistency but also extensibility.
One of the recurring pain points in Volto is that customization often requires shadowing components. Replacing a single icon may require copying an entire component into an add-on, introducing duplicated code and creating maintenance overhead. When multiple add-ons shadow the same component, customization becomes increasingly difficult and dependent on add-on ordering.
Rather than treating icons as implementation details, Aurora could expose them as a first-class extension point with a clear separation between icon semantics and icon presentation.
Proposal: Icon System with Core Vocabulary and Icon Packs
Aurora could ship a dedicated @plone/icons package containing a complete, immutable core icon set, representing the semantic icon vocabulary used throughout the system.
Icons would be consumed through a central <Icon /> component:
Core icons are immutable by default and define the canonical semantic meaning of icon names within Aurora. Add-ons cannot override these core definitions directly. Add-ons are meant to extend what already exists, not swap out the core.
Instead, add-ons may contribute additional icons under their own namespaces:
config.registerIcon('myAddon.searchFilter', SearchFilterIcon);
config.registerIcon('workflow.specialStep', SpecialStepIcon);
This ensures that add-ons can extend the icon system without risking conflicts or unintended overrides of core semantics.
To support visual customization and theming, Aurora introduces the concept of icon packs. An icon pack is a complete mapping of core icon names to visual implementations and represents a deliberate design decision at the application level.
Internally, Aurora registers the default icon pack:
config.registerIconPack(coreIconPack);
Projects may then choose to set a registered icon pack in the addon registry:
module.exports = {
addons: [],
iconPack: 'myIconPack'
};
The active icon pack defines how core icons are rendered, while add-on icons remain unaffected and are always available under their own namespaces.
Usage remains consistent throughout the application:
<Icon name="search" />
<Icon name="workflow.specialStep" />
The benefit is a single, predictable system for icon usage across Aurora: no shadowing of components, no accidental overrides from add-ons, and a clear separation between semantic meaning (core icon names) and visual representation (icon packs).
This model also enables safe theming: integrators can adopt different icon packs without modifying Aurora core or introducing component duplication, while add-ons remain composable and self-contained.
This way, integrators can always be certain that there are no side effects regarding icon overrides when adding new add-ons, unless they explicitly make the choice to mark an add-on as icon pack.
Most importantly, this aligns icon customization with Aurora's broader philosophy: extensibility through well-defined boundaries rather than implicit overrides, shadowing, or ordering-dependent behavior.
Describe alternatives you've considered
A much simpler approach would be to simply use and document a singular convention for use of icons, such as importing them as React components using the ?react suffix. However, if an icon must be replaced, there would be no way but to shadow the component.
The proposal can also be simplified. Leave out the @plone/icons package, put the Icon component in an existing add-on and allow registration using the config. However, what if one, or even two add-ons re-register an existing icon? At this point, we are going to have to worry about add-on ordering again. It's also possible the icon re-registration is an unwanted side effect of an add-on we would have to deal with. An icon pack would define one source of truth.
Additional context
Some screenshots of the different variations we currently have to render icons:

Is your feature request related to a problem? Please describe.
Currently, there are no guidelines regarding the use of icons in Aurora. As a result, icons are imported and rendered in several different ways throughout the codebase.
While these approaches are functionally equivalent, they introduce unnecessary decisions for developers and make the codebase less predictable. When adding a new icon, it is not always clear which pattern should be used, and different conventions continue to spread over time.
Describe the solution you'd like
Defining a standard approach would improve consistency, reduce cognitive overhead during development and code reviews, and make icon usage easier to understand for new contributors.
As an initial improvement, Aurora could adopt a single convention for importing and rendering icons, such as importing SVGs as React components using the
?reactsuffix.This would provide a consistent authoring experience and remove ambiguity around how icons should be used within the codebase.
However, we may take this a step further.
Aurora's long-term goal is not only consistency but also extensibility.
One of the recurring pain points in Volto is that customization often requires shadowing components. Replacing a single icon may require copying an entire component into an add-on, introducing duplicated code and creating maintenance overhead. When multiple add-ons shadow the same component, customization becomes increasingly difficult and dependent on add-on ordering.
Rather than treating icons as implementation details, Aurora could expose them as a first-class extension point with a clear separation between icon semantics and icon presentation.
Proposal: Icon System with Core Vocabulary and Icon Packs
Aurora could ship a dedicated
@plone/iconspackage containing a complete, immutable core icon set, representing the semantic icon vocabulary used throughout the system.Icons would be consumed through a central
<Icon />component:Core icons are immutable by default and define the canonical semantic meaning of icon names within Aurora. Add-ons cannot override these core definitions directly. Add-ons are meant to extend what already exists, not swap out the core.
Instead, add-ons may contribute additional icons under their own namespaces:
This ensures that add-ons can extend the icon system without risking conflicts or unintended overrides of core semantics.
To support visual customization and theming, Aurora introduces the concept of icon packs. An icon pack is a complete mapping of core icon names to visual implementations and represents a deliberate design decision at the application level.
Internally, Aurora registers the default icon pack:
Projects may then choose to set a registered icon pack in the addon registry:
The active icon pack defines how core icons are rendered, while add-on icons remain unaffected and are always available under their own namespaces.
Usage remains consistent throughout the application:
The benefit is a single, predictable system for icon usage across Aurora: no shadowing of components, no accidental overrides from add-ons, and a clear separation between semantic meaning (core icon names) and visual representation (icon packs).
This model also enables safe theming: integrators can adopt different icon packs without modifying Aurora core or introducing component duplication, while add-ons remain composable and self-contained.
This way, integrators can always be certain that there are no side effects regarding icon overrides when adding new add-ons, unless they explicitly make the choice to mark an add-on as icon pack.
Most importantly, this aligns icon customization with Aurora's broader philosophy: extensibility through well-defined boundaries rather than implicit overrides, shadowing, or ordering-dependent behavior.
Describe alternatives you've considered
A much simpler approach would be to simply use and document a singular convention for use of icons, such as importing them as React components using the
?reactsuffix. However, if an icon must be replaced, there would be no way but to shadow the component.The proposal can also be simplified. Leave out the
@plone/iconspackage, put theIconcomponent in an existing add-on and allow registration using the config. However, what if one, or even two add-ons re-register an existing icon? At this point, we are going to have to worry about add-on ordering again. It's also possible the icon re-registration is an unwanted side effect of an add-on we would have to deal with. An icon pack would define one source of truth.Additional context
Some screenshots of the different variations we currently have to render icons: