Context
Navigation entries, KPI tiles, banners and buttons all show an icon. The v3 proposals and the template imported an icon component into each declaration (import { Icons } from "@stackra/ui/icons", then
icon: Icons.Receipt). That ties every declaration to one icon library and one renderer, and it puts a
component import into a file that is otherwise data. A declaration is read by gen, by the manifest and by
the web and native clients, and none of them needs a component to do so.
Decision
- A declaration references an icon only by its
IconName, a string. No declaration imports an icon component. Examples arenavigation: { group, icon: "receipt", order: 20 }andd.kpi("revenue").icon("banknote"). IconNameis a string union. It is generated from Lucide 1.54.0, which is pinned, and it adds the Stackra aliases. It is exported from@stackra/icons/contracts.@stackra/uiresolves a name to a drawing on each platform:lucide-reacton the web andlucide-react-nativeon native. The map from names to drawings is the only place that knows the library. Swapping the library changes that map in@stackra/iconsand nothing else.- Gen validates every icon name used in a declaration against
IconName, and emits a registry of the names that the build uses. A bundle holds the drawings of the used names only. - A member’s own icons, in its
assets/icons/folder, join the set under the namespace form<namespace>::<name>, for examplebilling::invoice. They follow the asset rules of ADR 0234, and an override of one replaces the file whole (ADR 0306 rule 4). - The package is
@stackra/iconsin the design-system category (ADR 0302). It has acontractsentry, which holds the name union, and a platform entry per renderer.
Consequences
- A declaration is data that every target reads the same way. A reviewer sees the name and nothing else.
- A name that does not exist fails at gen, so a typo does not render an empty square.
- The icon library can change in one file, and the bundle size follows the names used.
- The
Icons.*form in the earlier proposals and the template is not used. The template is converted in the template pass (STA-344).
Enforcement
- planned — gen validation of icon names against
IconName, and the used-names registry. The work item is not yet open in Linear. - planned — the
@stackra/iconspackage, which is not built yet (ADR 0302 places it, and its work item follows the design-system build).