Icons
bestax-bulma supports these icon libraries out of the box: Font Awesome, Material Design Icons, Ionicons, Google Material Icons, and Material Symbols. Font Awesome is the default when no library prop is set.
create-bestaxThe Quick Start installer prompts you to pick an icon library (or none) and handles the install, CSS import, and any needed ConfigProvider wiring automatically. Use the manual steps below if you're adding icons to an existing project or want to switch libraries later.
Font Awesome
Font Awesome is the default icon library — no library prop required.
Install:
- pnpm
- npm
- yarn
- bun
pnpm add @fortawesome/fontawesome-free
npm install @fortawesome/fontawesome-free
yarn add @fortawesome/fontawesome-free
bun add @fortawesome/fontawesome-free
Import:
Add this to your main application file (e.g., main.tsx or App.tsx):
import '@fortawesome/fontawesome-free/css/all.min.css';
Usage:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function FontAwesomeExample() { return ( <Button color="primary"> <Icon name="user" aria-hidden="true" /> <span>Profile</span> </Button> ); }
Variants (Font Awesome styles):
- Solid (default):
<Icon name="user" /> - Regular:
<Icon name="user" variant="regular" /> - Brands:
<Icon name="github" variant="brands" /> - Light, Duotone, and Thin are also available via the
variantprop.
The library prop defaults to "fa" (Font Awesome). You only need to set it when using another library, e.g., library="mdi".
Material Design Icons
Material Design Icons (MDI) is a comprehensive icon library that follows Google's Material Design guidelines.
Install:
- pnpm
- npm
- yarn
- bun
pnpm add @mdi/font
npm install @mdi/font
yarn add @mdi/font
bun add @mdi/font
Import:
Add this to your main application file (e.g., main.tsx or App.tsx):
import '@mdi/font/css/materialdesignicons.min.css';
Usage:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function MaterialIconExample() { return ( <Button color="primary"> <Icon library="mdi" name="home" aria-hidden="true" /> <span>Home</span> </Button> ); }
Ionicons
Ionicons is a modern icon library designed specifically for web, iOS, Android, and desktop apps. The library now uses web components for better performance and loading.
Install:
- pnpm
- npm
- yarn
- bun
pnpm add ionicons@^8.0.13
npm install ionicons@^8.0.13
yarn add ionicons@^8.0.13
bun add ionicons@^8.0.13
Import:
Ionicons v8 uses web components that are automatically loaded in your documentation examples.
Setup for Your Application:
For your own application, you need to import the ionicons ES module. Add this to your main application file (e.g., index.js, App.js, or main.tsx):
// Import ionicons as ES module - this will auto-register the web components
import 'ionicons/dist/ionicons/ionicons.esm.js';
Alternative Setup (CDN):
You can also load ionicons via CDN by adding this script tag to your HTML. Ionicons v8 ships
only an ES module build, so no nomodule fallback script is needed:
<script
type="module"
></script>
Usage:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function IoniconExample() { return ( <Button color="info"> <Icon library="ion" name="settings" aria-hidden="true" /> <span>Settings</span> </Button> ); }
Available Icon Variants:
Ionicons v8 provides these variants for most icons:
import { Icon, Columns, Column, Block } from '@allxsmith/bestax-bulma'; function IoniconVariants() { return ( <Columns isVCentered> <Column isNarrow textAlign="centered"> <Icon library="ion" name="heart" aria-hidden="true" /> <Block textSize="7" mt="1"> Default </Block> </Column> <Column isNarrow textAlign="centered"> <Icon library="ion" name="heart-outline" aria-hidden="true" /> <Block textSize="7" mt="1"> Outline </Block> </Column> <Column isNarrow textAlign="centered"> <Icon library="ion" name="heart-sharp" aria-hidden="true" /> <Block textSize="7" mt="1"> Sharp </Block> </Column> </Columns> ); }
Ionicons v8 uses modern web components instead of CSS fonts. This provides:
- Better performance: Only loads icons that are actually used
- Smaller bundle size: No need to include entire font files
- SVG-based rendering: Crisp icons at any size
- Automatic loading: Icons load dynamically as needed
Web components are automatically registered in documentation examples, so no additional setup is required.
Ionicons v8 simplified the naming convention:
- Default (filled):
heart,settings,home - Outline:
heart-outline,settings-outline,home-outline - Sharp:
heart-sharp,settings-sharp,home-sharp
The old iOS/MD prefixes (ios-heart, md-heart) are no longer used in v8.
You can also pass the variant separately — <Icon library="ion" name="heart" variant="outline" /> is equivalent to <Icon library="ion" name="heart-outline" />.
Google Material Icons
Google's official Material Icons library provides the core set of Material Design icons.
Install:
- pnpm
- npm
- yarn
- bun
pnpm add material-icons
npm install material-icons
yarn add material-icons
bun add material-icons
Import:
Add this to your main application file (e.g., main.tsx or App.tsx):
// Default import (includes all styles)
import 'material-icons';
// Or import the base CSS file
import 'material-icons/iconfont/material-icons.css';
SASS Import:
@import 'material-icons/iconfont/material-icons.scss';
Selective Imports (for smaller bundle size):
// Import only specific styles you need
import 'material-icons/iconfont/filled.css'; // Default filled style
import 'material-icons/iconfont/outlined.css'; // Outlined style
import 'material-icons/iconfont/round.css'; // Round style
import 'material-icons/iconfont/sharp.css'; // Sharp style
import 'material-icons/iconfont/two-tone.css'; // Two-tone style
Usage:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function GoogleMaterialIconExample() { return ( <Button color="success"> <Icon library="material-icons" name="home" aria-hidden="true" /> <span>Home</span> </Button> ); }
Available Icon Styles:
The Google Material Icons library includes different styles that can be used via variant:
import { Icon, Columns, Column } from '@allxsmith/bestax-bulma'; function MaterialIconStyles() { return ( <Columns isVCentered> <Column isNarrow> <Icon library="material-icons" name="account_circle" color="danger" /> </Column> <Column isNarrow> <Icon library="material-icons" name="account_circle" variant="outlined" color="danger" /> </Column> <Column isNarrow> <Icon library="material-icons" name="account_circle" variant="round" color="danger" /> </Column> <Column isNarrow> <Icon library="material-icons" name="account_circle" variant="sharp" color="danger" /> </Column> </Columns> ); }
- Default (Filled): Standard filled icons (default, no
variantneeded) - Outlined:
variant="outlined" - Round:
variant="round" - Sharp:
variant="sharp"
For a complete list of available icons and detailed usage instructions, visit the material-icons package documentation.
Material Symbols
The newest icon library from Google, offering more comprehensive icon coverage and modern design.
Install:
- pnpm
- npm
- yarn
- bun
pnpm add material-symbols
npm install material-symbols
yarn add material-symbols
bun add material-symbols
Import:
Add this to your main application file (e.g., main.tsx or App.tsx):
// Default import (includes all styles)
import 'material-symbols';
SASS Import:
@import 'material-symbols';
Selective Imports (for smaller bundle size):
// Import only specific styles you need
import 'material-symbols/outlined.css'; // Outlined style (most common)
import 'material-symbols/rounded.css'; // Rounded style
import 'material-symbols/sharp.css'; // Sharp style
Usage:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function MaterialSymbolExample() { return ( <Button color="warning"> <Icon library="material-symbols" name="home" aria-hidden="true" /> <span>Home</span> </Button> ); }
Available Symbol Styles:
Material Symbols come in several styles. The default import includes all of them, but you can import selectively:
import { Icon, Columns, Column } from '@allxsmith/bestax-bulma'; function MaterialSymbolStyles() { return ( <> <Columns isVCentered> <Column size={2} textWeight="bold"> Outlined: </Column> <Column isNarrow> <Icon library="material-symbols" name="delete" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="settings" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="grade" size="large" features="is-size-1" /> </Column> </Columns> <Columns isVCentered> <Column size={2} textWeight="bold"> Rounded: </Column> <Column isNarrow> <Icon library="material-symbols" name="delete" variant="rounded" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="settings" variant="rounded" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="grade" variant="rounded" size="large" features="is-size-1" /> </Column> </Columns> <Columns isVCentered> <Column size={2} textWeight="bold"> Sharp: </Column> <Column isNarrow> <Icon library="material-symbols" name="delete" variant="sharp" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="settings" variant="sharp" size="large" features="is-size-1" /> </Column> <Column isNarrow> <Icon library="material-symbols" name="grade" variant="sharp" size="large" features="is-size-1" /> </Column> </Columns> </> ); }
- Outlined: Default style (no
variantneeded) - Rounded:
variant="rounded" - Sharp:
variant="sharp"
Material Symbols is Google's newer icon system with:
- More comprehensive icon coverage
- Better optical sizing and variable font support
- Consistent design across all platforms
- Recommended for new projects
For a complete list of available symbols and detailed usage instructions, visit the material-symbols package documentation.
If you haven't started your project yet, pnpm create bestax@latest will wire up any of these icon libraries for you. See the Quick Start.
Icon-Only Buttons
Every button example above pairs its icon with visible text. When the icon is the whole label — a toolbar or a card action with no room for words — the accessible name has to come from somewhere else, because there is no text for a screen reader to announce.
Put the name on the Button with aria-label, and leave the Icon hidden from assistive technology, as it is whenever it has no ariaLabel:
import { Button, Icon } from '@allxsmith/bestax-bulma'; function IconOnlyExample() { return ( <Button color="danger" aria-label="Delete item"> <Icon name="trash" aria-hidden="true" /> </Button> ); }
The two attributes do different jobs, and only the first one names the button:
aria-labelon theButtonis the accessible name. It takes precedence over anything inside the button, so it alone supplies the name a screen reader reads out (alongside the "button" role and any state, which come from the element itself). Make it name the action ("Delete item"), not the picture ("Trash icon").aria-hiddenon theIcondoes not change that name. It keeps the icon out of the accessibility tree entirely, so assistive technology never exposes a stray node when moving through the page element by element. AnIconwith noariaLabelrenders it on its own, so writing it out, as these examples do, changes nothing. Correct decorative markup, not part of the naming.
Leave the aria-label off and the button has no name at all, since the only thing inside it is a hidden icon. Don't fix that with the Icon's ariaLabel: it would name the picture, not the action.
The same pattern applies to every library on this page. Only the library prop and the icon name change:
import { Button, Buttons, Icon } from '@allxsmith/bestax-bulma'; function IconOnlyLibraries() { return ( <Buttons> <Button color="primary" aria-label="Edit profile"> <Icon library="mdi" name="pencil" aria-hidden="true" /> </Button> <Button color="info" aria-label="Open settings"> <Icon library="ion" name="settings" aria-hidden="true" /> </Button> <Button color="success" aria-label="Add to favorites"> <Icon library="material-icons" name="favorite" aria-hidden="true" /> </Button> </Buttons> ); }
When the button already has visible text, the icon is decorative and needs only aria-hidden — no aria-label on the button, since the visible text is already the name. Adding aria-hidden there stops the default "icon" label being announced next to the word it duplicates.
See Button Accessibility and the Icon API for the full prop lists.
Choosing the Right Icon Library
| Library | Icons Count | File Size | Best For |
|---|---|---|---|
| Font Awesome | 2,000+ | ~75KB | General purpose, most popular |
| Material Design Icons | 7,000+ | ~50KB | Material Design projects |
| Ionicons v8 | 1,300+ | Dynamic | Modern web components, mobile |
| Google Material Icons | 1,100+ | ~45KB | Official Google Material Design |
| Material Symbols | 2,500+ | ~55KB | Modern Material Design projects |
Icon Name References
- Font Awesome: fontawesome.com/icons
- Material Design Icons: materialdesignicons.com
- Ionicons v8: ionicons.com • NPM Package
- Google Material Icons: fonts.google.com/icons • NPM Package
- Material Symbols: fonts.google.com/icons • NPM Package
Next Steps
- Learn about Icon component props: Icon API
- Explore IconText component: IconText API
- Browse CSS variations: CSS Variations