Skip to content

n1ght-hunter/igloo

Repository files navigation

Igloo Logo

Igloo: WebAssembly Plugin System for Iced

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.

Overview

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

Architecture

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│  Host App       │    │  WIT Definitions │    │  Guest Plugin   │
│  (Iced)         │◄──►│  (Interface)     │◄──►│  (WASM)         │
│                 │    │                  │    │                 │
│ PluginManager   │    │ • Elements       │    │ • State         │
│ MessageManager  │    │ • Messages       │    │ • View Logic    │
│ Resource Tables │    │ • Components     │    │ • Event Handlers│
└─────────────────┘    └──────────────────┘    └─────────────────┘

Project Structure

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

Features

  • 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

Getting Started

Prerequisites

  • Rust and rustup installed
  • mise installed

Setup

  1. Clone the repository:
git clone <repository-url>
cd igloo
  1. Install required Rust target:
just setup
# or manually:
rustup target add wasm32-wasip2
  1. Build and run the example:
just run

Creating a Plugin

  1. Create a new Rust library with crate-type = ["cdylib"]
  2. Add igloo_guest as a dependency
  3. 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);
  1. Compile to WASM:
cargo build --target wasm32-wasip2 --release

Loading Plugins in Host

use 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")?;

Development

Building

  • Build all components: cargo build
  • Build for WASM target: cargo build --target wasm32-wasip2
  • Run example: just run
  • Generate bindings: just gen

Acknowledgments

  • Iced - GUI framework
  • Wasmtime - WebAssembly runtime
  • wit-bindgen - Interface generation
  • WebAssembly Component Model specification

License

Licensed under either of

at your option.

Contribution

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.

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages