Using Lucide via Cargo, npm or lucide.dev in Any Project
MorpheusIcons works with any icon library from Cargo crates, npm, or lucide.dev. Start with the Rust crate icondata, or load SVGs from npm packages like lucide-static and fetch them from a CDN.
1. Using Lucide in Rust via Cargo (icondata)
Using the icondata Rust crate or lucide.dev site SVGs
A
Option A: Using the icondata Crate (Lucide, Heroicons, Tabler for Rust)
In Rust, the popular icondata crate packages Lucide, Heroicons, Tabler, and Phosphor icons into Rust constants:
# Cargo.toml
[dependencies]
icondata = "0.4"
morpheusicons = "0.1"
Pass icondata path data directly into MorpheusIcons:
use icondata::{LuSun, LuMoon}; // Lucide icons from icondata crate
use morpheusicons::prelude::*;
fn main() {
// icondata provides SVG path string in .data field
let sun_path = LuSun.data;
let moon_path = LuMoon.data;
let mut controller = MorphController::from_sources(
&sun_path,
&moon_path,
SpringConfig::BOUNCY,
).unwrap();
controller.set_target(1.0); // Morph to Moon!
controller.update(0.016);
}
B
Option B: Copying Directly from lucide.dev
- Open lucide.dev/icons
- Search for any icon (for example
play,pause,sun) - Click Copy SVG, or save the
.svgfile into your project - Pass it through
icon_from_svgto convert the full SVG
use morpheusicons::icons::svg_extract::icon_from_svg;
use morpheusicons::prelude::*;
// Load the .svg files saved straight from lucide.dev
let play_svg = icon_from_svg(include_str!("../assets/lucide/play.svg")).unwrap();
let pause_svg = icon_from_svg(include_str!("../assets/lucide/pause.svg")).unwrap();
let mut controller = MorphController::from_sources(&play_svg, &pause_svg, SpringConfig::SNAPPY).unwrap();
2. Using Lucide from npm in JavaScript / Web Apps
Integrating lucide-static or Lucide CDN with MorpheusIcons WebAssembly
A
Option A: Using the lucide-static npm Package
Install the official lucide-static package in your web project (Vite, Next.js, Webpack, etc.):
npm install lucide-static
Then import Lucide icon paths and feed them directly into MorpheusIcons:
import init, { WasmMorphController } from './pkg/morpheusicons.js';
// Import raw SVG strings from lucide-static in Vite/Webpack
import sunSvg from 'lucide-static/icons/sun.svg?raw';
import moonSvg from 'lucide-static/icons/moon.svg?raw';
await init();
// Extract path d="..." string or pass path directly
const sunPath = "M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8z";
const moonPath = "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9z";
// Create WASM controller (startPath, targetPath, springPreset)
const controller = new WasmMorphController(sunPath, moonPath, "bouncy");
// Trigger morph animation to Moon (t=1.0)
controller.morphToEnd();
// Animation frame loop (60fps)
function animate(dtSeconds) {
const isAnimating = controller.update(dtSeconds);
// Set calculated continuous SVG path
document.getElementById('icon-path').setAttribute('d', controller.currentSvgPath());
if (isAnimating) requestAnimationFrame(animate);
}
B Option B: Fetching Lucide Icons Dynamically from CDN (unpkg / jsDelivr)
No build tools required! You can fetch any icon dynamically from Lucide's CDN:
// Fetch raw SVG files for any Lucide icon directly from unpkg CDN
const [sunSvg, moonSvg] = await Promise.all([
fetch('https://unpkg.com/lucide-static@latest/icons/sun.svg').then(r => r.text()),
fetch('https://unpkg.com/lucide-static@latest/icons/moon.svg').then(r => r.text())
]);
// Extract d="..." attribute using simple regex
const extractD = (svg) => svg.match(/d="([^"]+)"/)?.[1] || "";
const controller = new WasmMorphController(
extractD(sunSvg),
extractD(moonSvg),
"gentle"
);
GUI Framework Integration Examples
Ready-to-copy code snippets for GPUI, egui, Iced, Leptos, Dioxus & WASM
GPUI (Zed Editor Framework)
feature = "gpui"use gpui::*;
use morpheusicons::integrations::gpui::MorphIcon;
use morpheusicons::prelude::*;
struct AppView {
morph_ctrl: MorphController,
}
impl Render for AppView {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
div()
.flex()
.items_center()
.justify_center()
.child(
MorphIcon::new(&self.morph_ctrl)
.size(px(32.0))
.stroke_color(rgb(0x16a34a))
.stroke_width(2.0)
)
}
}
egui Immediate-Mode UI
feature = "egui"use egui::Ui;
use morpheusicons::integrations::egui::show_morph_icon;
use morpheusicons::prelude::*;
fn draw_icon(ui: &mut Ui, ctrl: &MorphController) {
show_morph_icon(ui, ctrl, 36.0, egui::Color32::from_rgb(22, 163, 74));
}
Leptos Reactive Web Components
feature = "leptos"use leptos::*;
use morpheusicons::integrations::leptos::MorpheusIcon;
use morpheusicons::prelude::*;
#[component]
pub fn PlayPauseButton() -> impl IntoView {
let (progress, set_progress) = create_signal(0.0);
view! {
<button on:click=move |_| set_progress.update(|p| *p = 1.0 - *p)>
<MorpheusIcon
source=Icon::Play
target=Icon::Pause
progress=progress
config=SpringConfig::BOUNCY
size=32.0
/>
</button>
}
}