# dioxus-iconify

> CLI tool for vendoring [Iconify](https://icon-sets.iconify.design/) icons (material, lucid, heroicons,....) in Dioxus projects

[![Crates.io](https://img.shields.io/crates/v/dioxus-iconify.svg)](https://crates.io/crates/dioxus-iconify)
[![License](https://img.shields.io/crates/l/dioxus-iconify)
](LICENSE)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/davidB/dioxus-iconify/total)

Use any of the **275,000+ icons** from [Iconify](https://iconify.design) in your Dioxus applications with a simple CLI tool. Icons are generated at build time as Rust source code, eliminating runtime dependencies.

## ✨ Features

- 🎨 **275k+ Icons**: Access icons from Material Design, Heroicons, FontAwesome, Lucide, and [200+ other icon sets](https://icon-sets.iconify.design/)
- 🦀 **Type-Safe**: Generated as Rust const values, checked at compile time
- 📦 **Zero Runtime Dependencies**: No need to depend on this crate at compile time and runtime - only Dioxus
- 🗂️ **Well Organized**: Icons grouped by collection in separate files
- 🎯 **Fully Customizable**: Override any SVG attribute (size, color, stroke, etc.)
- 💾 **Git-Friendly**: Generated code is committed to your repository
- ⚡ **CLI-Based**: Simple `add` command inspired by shadcn-ui and dioxus components

## 🚀 Quick Start

### Installation

```bash
cargo install dioxus-iconify

# via cargo-binstall
cargo binstall dioxus-iconify

# brew (mac & linux)
brew install davidB/tap/dioxus-iconify

# via mise (cli or configuration file)
mise install "ubi:davidB/dioxus-iconify"

# curl + bash script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/davidB/dioxus-iconify/releases/download/latest/dioxus-iconify-installer.sh | sh
```

### Usage

0. **Choose your icons** on [Iconify - home of open source icons](https://icon-sets.iconify.design/)

1. **Add icons to your project**:

```bash
# Add single icon
dioxus-iconify add mdi:home

# Add multiple icons
dioxus-iconify add mdi:home mdi:account heroicons:arrow-left

# Specify custom output directory
dioxus-iconify --output src/components/icons add lucide:settings
```

2. **Use in your Dioxus components**:

```rust
use dioxus::prelude::*;

mod icons;
use icons::Icon;
use icons::mdi;

fn App() -> Element {
    rsx! {
        div {
            // Basic usage
            Icon { data: mdi::Home }

            // Custom size
            Icon {
                data: mdi::Home,
                width: "32",
                height: "32",
            }

            // Custom color and style
            Icon {
                data: mdi::Home,
                fill: "blue",
                class: "icon-class",
            }
        }
    }
}
```

## 📚 How It Works

### The Problem

Existing Dioxus icon libraries typically bundle all icons in the crate, leading to:

- Large dependency sizes
- Slower compile times
- Including icons you don't use

### The Solution

`dioxus-iconify` takes inspiration from [shadcn-ui](https://ui.shadcn.com/): instead of shipping icons as a dependency, it **generates the icon code directly in your project**.

### What Gets Generated

When you run `dioxus-iconify add mdi:home heroicons:arrow-left`, it creates:

```
src/icons/
├── mod.rs         # Icon component + IconData struct + module declarations
├── mdi.rs         # Material Design Icons: Home, ...
└── heroicons.rs   # Heroicons: ArrowLeft, ...
```

**src/icons/mod.rs**:

```rust
// Auto-generated by dioxus-iconify - DO NOT EDIT

use dioxus::prelude::*;

#[derive(Clone, Copy)]
pub struct IconData {
    pub name: &'static str,
    pub body: &'static str,
    pub view_box: &'static str,
    pub width: &'static str,
    pub height: &'static str,
}

#[component]
pub fn Icon(
    data: IconData,
    #[props(extends = GlobalAttributes)]
    attributes: Vec<Attribute>,
) -> Element {
    rsx! {
        svg {
            view_box: "{data.view_box}",
            width: "{data.width}",
            height: "{data.height}",
            ..attributes,
            dangerous_inner_html: "{data.body}",
        }
    }
}

pub mod mdi;
pub mod heroicons;
```

**src/icons/mdi.rs**:

```rust
// Auto-generated by dioxus-iconify - DO NOT EDIT
// Collection: mdi

use super::IconData;

pub const Home: IconData = IconData {
    name: "mdi:home",
    body: r#"<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>"#,
    view_box: "0 0 24 24",
    width: "24",
    height: "24",
};
```

## 🎨 Icon Customization

The `Icon` component uses Dioxus 0.7's `extends = GlobalAttributes` pattern, allowing you to override any SVG attribute:

```rust
Icon {
    data: mdi::Home,
    // Size
    width: "48",
    height: "48",

    // Color
    fill: "currentColor",
    stroke: "#000000",
    stroke_width: "2",

    // CSS
    class: "my-icon hover:text-blue-500",
    style: "margin: 1rem;",

    // Accessibility
    aria_label: "Home icon",
    role: "img",

    // Any other SVG attribute...
}
```

## 🔍 Finding Icons

Browse available icons at:

- [Iconify Icon Sets](https://icon-sets.iconify.design/)
- [Icônes](https://icones.js.org/)

Icon names follow the format `collection:icon-name`:

- `mdi:home` - Material Design Icons
- `heroicons:arrow-left` - Heroicons
- `lucide:settings` - Lucide
- `fa:github` - Font Awesome
- `simple-icons:rust` - Simple Icons

## 📖 CLI Commands

### `add`

Add icons to your project:

```bash
dioxus-iconify add <icon>...

# Examples
dioxus-iconify add mdi:home
dioxus-iconify add mdi:home mdi:account heroicons:arrow-left
dioxus-iconify --output src/components/icons add lucide:settings
```

### `init`

Initialize the icons directory (creates `mod.rs`):

```bash
dioxus-iconify init
```

### Coming Soon

- `remove` - Remove icons from your project
- `list` - List all generated icons
- `update` - Re-fetch and update all icons

## 🆚 Comparison with Other Solutions

| Feature          | dioxus-iconify | Embedded Libraries | SVG Files |
| ---------------- | -------------- | ------------------ | --------- |
| Icon Count       | 275,000+       | Limited            | Manual    |
| Uptodate Icons   | ✅             | Depends            | Manual    |
| Dependency Size  | 0 (CLI only)   | Large              | 0         |
| Type Safety      | Mixed          | ✅                 | ❌        |
| Customization    | Full           | Limited            | Full      |
| Fixes/workaround | Full           | Take time          | Full      |
| Offline Support  | ✅ (committed) | ✅                 | ✅        |
| Updates          | CLI command    | Crate update       | Manual    |

Some Embedded libraries of icons for dioxus:
[dioxus-free-icons](https://crates.io/crates/dioxus-free-icons),
[dioxus-material-icons](https://crates.io/crates/dioxus-material-icons),
[dioxus-heroicons](https://crates.io/crates/dioxus-heroicons),
...

[Search Results for 'dioxus icons' - crates.io: Rust Package Registry](https://crates.io/search?q=dioxus%20icons)

## 💡 Tips

1. **Commit generated code**: The `src/icons/` directory should be committed to version control
2. **Customize the Icon component**: It's generated in your project, so modify it if needed
3. **Use with Tailwind**: Icon colors work with Tailwind's `text-*` classes via `currentColor`
4. **Organization**: Icons are automatically grouped by collection in separate files

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 🙏 Acknowledgments

- [Dioxus](https://dioxuslabs.com/) - The amazing Rust UI framework
- [Iconify](https://iconify.design/) - For providing the amazing icon API and collections

### For inspiration

- [shadcn-ui](https://ui.shadcn.com/) - For inspiration on the CLI-based generation approach
- [Dioxus Components](https://dioxuslabs.com/components) - Like shadcn but for dioxus
- [iconmate](https://github.com/Blankeos/iconmate) - For similar ideas in the TypeScript ecosystem

## 📚 Resources

- [Iconify Documentation](https://iconify.design/docs/)
- [Dioxus Documentation](https://dioxuslabs.com/learn/)
- [Browse Icons](https://icon-sets.iconify.design/)
