Igloo is a modular plugin system for GUI applications, built with Rust, Iced, and the WebAssembly Component Model. It enables dynamic loading of UI components as secure, sandboxed WebAssembly plugins, making it easy to extend and customize desktop applications.
Igloo lets you:
-
Build desktop GUIs with plugins written in Rust or other WASM-compatible languages
-
Use WIT (WebAssembly Interface Types) for type-safe host/guest communication
-
Run plugins in a secure, isolated environment
-
Host Application: An Iced-based GUI application that manages and renders WebAssembly plugins
-
Guest Plugins: WebAssembly components that define UI elements and behavior
-
WIT (WebAssembly Interface Types): For type-safe communication between host and guest
-
Component Model: For secure, sandboxed plugin execution
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Host App │ │ WIT Definitions │ │ Guest Plugin │
│ (Iced) │◄──►│ (Interface) │◄──►│ (WASM) │
│ │ │ │ │ │
│ PluginManager │ │ • Elements │ │ • State │
│ MessageManager │ │ • Messages │ │ • View Logic │
│ Resource Tables │ │ • Components │ │ • Event Handlers│
└─────────────────┘ └──────────────────┘ └─────────────────┘
igloo/
├── crates/
│ ├── igloo_host/ # Host library for managing WASM plugins
│ └── igloo_guest/ # Guest library for creating WASM plugins (plugin authors)
├── plugins/
│ └── js/ # JavaScript plugin support (experimental)
├── examples/
│ └── rust_host/ # Example host application
├── wit/ # WebAssembly Interface Type definitions
└── justfile # Build automation
- Type-Safe Plugin Communication: WIT-based interfaces for host/guest messaging
- Rich UI Components: Buttons, text, containers, layouts, and more
- Message Passing: Bidirectional communication between host and plugins
- Resource Management: Efficient handling of UI elements across WASM boundary
- Plugin Isolation: Secure sandboxed execution of plugin code
- Multi-Language Support: Rust, JavaScript (experimental), and more
- Rust and rustup installed
- mise installed
- Clone the repository:
git clone <repository-url>
cd igloo- Install required Rust target:
just setup
# or manually:
rustup target add wasm32-wasip2- Build and run the example:
just run- Create a new Rust library with
crate-type = ["cdylib"] - Add
igloo_guestas a dependency - Implement the required traits:
use igloo_guest::*;
#[derive(Debug, Clone)]
pub enum MyMessage {
ButtonPressed,
// ... other messages
}
pub struct MyPlugin {
counter: u32,
}
impl MyPlugin {
pub fn new() -> Self {
Self { counter: 0 }
}
pub fn update(&mut self, message: MyMessage) {
match message {
MyMessage::ButtonPressed => {
self.counter += 1;
}
}
}
pub fn view(&self) -> Element {
column![
text!("Count: {}", self.counter),
button("Click me").on_press(MyMessage::ButtonPressed)
].into()
}
}
impl igloo_guest::Application<MyPlugin, MyMessage> for MyPlugin {
fn new() -> Self
where
Self: Sized,
{
MyPlugin::new()
}
fn view(&self) -> Element<MyMessage> {
self.view()
}
fn update(&mut self, message: MyMessage) {
self.update(message);
}
}
// Export the plugin
igloo_guest::export_guest!(MyPlugin, MyMessage);- Compile to WASM:
cargo build --target wasm32-wasip2 --releaseuse test_host::plugin_manager::PluginManager;
let mut plugin_manager = PluginManager::new()?;
plugin_manager.add_plugin_from_file("my-plugin", "path/to/plugin.wasm")?;
// In your update loop:
plugin_manager.plugin_update("my-plugin", message)?;
// In your view:
let plugin_view = plugin_manager.plugin_view("my-plugin")?;- Build all components:
cargo build - Build for WASM target:
cargo build --target wasm32-wasip2 - Run example:
just run - Generate bindings:
just gen
- Iced - GUI framework
- Wasmtime - WebAssembly runtime
- wit-bindgen - Interface generation
- WebAssembly Component Model specification
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
