Convert Figma logo to code with AI

rustwasm logogloo

A modular toolkit for building fast, reliable Web applications and libraries with Rust and WASM

1,889
156
1,889
97

Top Related Projects

31,806

Rust / Wasm framework for creating reliable and efficient web applications

3,842

A Rust framework for creating web apps

3,458

A standard library for the client-side Web

Facilitating high-level interactions between Wasm modules and JavaScript

📦✨ your favorite rust -> wasm workflow tool!

18,846

Build fast web applications with Rust.

Quick Overview

Gloo is a modular toolkit for building fast and reliable Web applications with Rust and WebAssembly. It provides a collection of libraries that simplify common tasks in web development, such as DOM manipulation, event handling, and AJAX requests, while leveraging Rust's performance and safety features.

Pros

  • Improves performance of web applications by utilizing Rust and WebAssembly
  • Provides a modular approach, allowing developers to use only the components they need
  • Offers type-safe bindings to Web APIs, reducing runtime errors
  • Seamlessly integrates with existing JavaScript ecosystems

Cons

  • Steeper learning curve for developers not familiar with Rust
  • Limited ecosystem compared to more established JavaScript frameworks
  • May require additional build steps and tooling setup
  • Performance gains might be less noticeable for simple applications

Code Examples

  1. Creating an element and appending it to the body:
use gloo::utils::document;
use wasm_bindgen::JsCast;

let p = document()
    .create_element("p")
    .unwrap()
    .dyn_into::<web_sys::HtmlElement>()
    .unwrap();
p.set_inner_text("Hello, Gloo!");
document().body().unwrap().append_child(&p).unwrap();
  1. Adding an event listener to a button:
use gloo::events::EventListener;
use web_sys::HtmlElement;

let button: HtmlElement = // ... obtain button element
let listener = EventListener::new(&button, "click", move |_event| {
    web_sys::console::log_1(&"Button clicked!".into());
});
  1. Making an HTTP request using Gloo's futures:
use gloo::net::http::Request;

let response = Request::get("https://api.example.com/data")
    .send()
    .await
    .unwrap();
let json: serde_json::Value = response.json().await.unwrap();
web_sys::console::log_1(&format!("Received data: {:?}", json).into());

Getting Started

To start using Gloo in your Rust WebAssembly project:

  1. Add Gloo to your Cargo.toml:

    [dependencies]
    gloo = "0.8"
    
  2. Import and use Gloo modules in your Rust code:

    use gloo::utils::document;
    use gloo::events::EventListener;
    use gloo::net::http::Request;
    
    // Your application code here
    
  3. Build your project with wasm-pack build and integrate the resulting WebAssembly module into your web application.

Competitor Comparisons

31,806

Rust / Wasm framework for creating reliable and efficient web applications

Pros of Yew

  • More comprehensive framework for building client-side web apps
  • Provides a component-based architecture similar to React
  • Offers a rich ecosystem with additional libraries and tools

Cons of Yew

  • Steeper learning curve due to its more complex architecture
  • Potentially larger bundle sizes for smaller applications
  • May be overkill for simple web interactions

Code Comparison

Yew example:

use yew::prelude::*;

#[function_component(App)]
fn app() -> Html {
    let counter = use_state(|| 0);
    let onclick = {
        let counter = counter.clone();
        Callback::from(move |_| counter.set(*counter + 1))
    };

    html! {
        <div>
            <button {onclick}>{ "+1" }</button>
            <p>{ *counter }</p>
        </div>
    }
}

Gloo example:

use gloo::events::EventListener;
use wasm_bindgen::JsCast;
use web_sys::{Element, HtmlElement};

let document = web_sys::window().unwrap().document().unwrap();
let button: Element = document.create_element("button").unwrap();
button.set_inner_html("+1");
let p: Element = document.create_element("p").unwrap();
p.set_inner_html("0");

EventListener::new(&button, "click", move |_event| {
    let count: i32 = p.inner_html().parse().unwrap();
    p.set_inner_html(&(count + 1).to_string());
}).forget();
3,842

A Rust framework for creating web apps

Pros of Seed

  • Higher-level framework for building web applications
  • Provides a more opinionated structure and architecture
  • Includes built-in state management and routing capabilities

Cons of Seed

  • Less flexible for low-level DOM manipulation
  • Steeper learning curve for developers new to Rust and web development
  • More limited ecosystem compared to Gloo's broader approach

Code Comparison

Seed example:

#[update]
fn increment(model: &mut Model) {
    model.counter += 1;
}

#[view]
fn view(model: &Model) -> Node<Msg> {
    button![model.counter, ev(Ev::Click, |_| Msg::Increment)]
}

Gloo example:

let button = document.create_element("button")?;
button.set_inner_html(&format!("Count: {}", count));
button.add_event_listener(move |_: Event| {
    count += 1;
    button.set_inner_html(&format!("Count: {}", count));
});

Seed provides a more declarative approach with built-in state management, while Gloo offers lower-level control over DOM manipulation. Seed is better suited for larger applications with complex state management needs, whereas Gloo is more flexible for integrating with existing JavaScript libraries or creating custom components.

3,458

A standard library for the client-side Web

Pros of stdweb

  • More mature and established project with a longer history
  • Provides a higher-level abstraction for DOM manipulation
  • Offers a wider range of built-in JavaScript bindings

Cons of stdweb

  • Less actively maintained compared to gloo
  • Larger bundle sizes due to more comprehensive bindings
  • May have more overhead for simple use cases

Code Comparison

stdweb example:

use stdweb::web::document;
use stdweb::web::IParentNode;

fn main() {
    let element = document().query_selector("#my-element").unwrap();
    element.set_text_content("Hello from stdweb!");
}

gloo example:

use gloo_utils::document;
use wasm_bindgen::JsCast;

fn main() {
    let element = document().get_element_by_id("my-element").unwrap();
    element.dyn_ref::<web_sys::HtmlElement>().unwrap().set_inner_text("Hello from gloo!");
}

Both stdweb and gloo are Rust libraries for WebAssembly development, providing bindings to web APIs. stdweb offers a more comprehensive set of bindings and a higher-level abstraction, while gloo focuses on a more modular approach with lower-level bindings. gloo is part of the rustwasm organization and is more actively maintained, making it a better choice for new projects. stdweb may be preferred for existing projects or those requiring extensive DOM manipulation.

Facilitating high-level interactions between Wasm modules and JavaScript

Pros of wasm-bindgen

  • More comprehensive and lower-level bindings for Rust-WASM interop
  • Wider adoption and community support
  • Supports generating TypeScript definitions

Cons of wasm-bindgen

  • Steeper learning curve for beginners
  • More verbose code for simple use cases
  • Requires additional setup and configuration

Code Comparison

wasm-bindgen:

#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

gloo:

use gloo_utils::format::JsValueSerdeExt;

pub fn greet(name: &JsValue) -> JsValue {
    format!("Hello, {}!", name.as_string().unwrap()).into()
}

Summary

wasm-bindgen provides more comprehensive bindings and wider adoption, but can be more complex for simple use cases. gloo offers a higher-level abstraction, making it easier for beginners but potentially limiting for advanced scenarios. wasm-bindgen is better suited for large-scale projects with complex interop requirements, while gloo shines in smaller projects or when rapid development is prioritized. The choice between the two depends on the specific needs of the project and the developer's familiarity with Rust and WebAssembly concepts.

📦✨ your favorite rust -> wasm workflow tool!

Pros of wasm-pack

  • Focused specifically on packaging and publishing Rust-generated WebAssembly
  • Provides a streamlined workflow for creating and managing wasm projects
  • Integrates well with npm for easy distribution of wasm modules

Cons of wasm-pack

  • More limited in scope compared to gloo's broader ecosystem
  • Less flexibility for low-level wasm operations and browser API interactions
  • Smaller community and fewer extensions/plugins available

Code Comparison

wasm-pack example:

#[wasm_bindgen]
pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

gloo example:

use gloo_utils::document;

let element = document().create_element("div")?;
element.set_inner_html("Hello, World!");

Summary

wasm-pack is a specialized tool for packaging and publishing Rust-generated WebAssembly, offering a streamlined workflow for wasm projects. It integrates well with npm but has a more limited scope compared to gloo.

gloo, on the other hand, provides a broader ecosystem of tools and utilities for working with WebAssembly and browser APIs. It offers more flexibility for low-level wasm operations and has a larger community, but may require more setup for simple packaging tasks.

Choose wasm-pack for straightforward wasm packaging and publishing, or gloo for more comprehensive wasm development with broader browser integration capabilities.

18,846

Build fast web applications with Rust.

Pros of Leptos

  • Full-featured web framework with reactive state management and server-side rendering
  • Integrates well with existing Rust ecosystems and tools
  • Offers a more opinionated and structured approach to building web applications

Cons of Leptos

  • Steeper learning curve for developers new to reactive programming concepts
  • Less flexibility compared to Gloo's low-level approach
  • Smaller community and ecosystem compared to more established frameworks

Code Comparison

Leptos example:

#[component]
fn Counter(cx: Scope, initial_value: i32) -> impl IntoView {
    let (count, set_count) = create_signal(cx, initial_value);
    view! { cx,
        <button on:click=move |_| set_count.update(|count| *count += 1)>
            "Count: {count}"
        </button>
    }
}

Gloo example (using web-sys):

use gloo_events::EventListener;
use web_sys::{Element, HtmlButtonElement};

let button: HtmlButtonElement = // ... obtain button element
let mut count = 0;
let listener = EventListener::new(&button, "click", move |_event| {
    count += 1;
    button.set_text_content(Some(&format!("Count: {}", count)));
});

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Gloo

A toolkit for building fast, reliable Web applications and libraries with Rust and Wasm.

What?

Gloo is a collection of libraries, and those libraries provide ergonomic Rust wrappers for browser APIs. web-sys/js-sys are very difficult/inconvenient to use directly so gloo provides wrappers around the raw bindngs which makes it easier to consume those APIs. This is why it is called a "toolkit", instead of "library" or "framework".

Background

In the Rust and WebAssembly working group's 2019 roadmap, we chose to deliberately cultivate our library ecosystem by building a modular toolkit:

Collaborating on a Modular Toolkit

The idea of building [high-level libraries] in a modular way that will allow others in the community to put the components together in a different way is very exciting to me. This hopefully will make the ecosystem as a whole much stronger.

In particular I’d love to see a modular effort towards implementing a virtual DOM library with JSX like syntax. There have been several efforts on this front but all have seemed relatively monolithic and “batteries included”. I hope this will change in 2019.

— Ryan Levick in Rust WebAssembly 2019

Don't create branded silos. Branding might perhaps be useful to achieve fame. But if we truly want Rust's Wasm story to succeed we should think of ways to collaborate instead of carving out territory.

— Yoshua Wuyts in Wasm 2019

In 2018, we created foundational libraries like js-sys and web-sys. In 2019, we should build modular, high-level libraries on top of them, and collect the libraries under an umbrella toolkit crate for a holistic experience. This toolkit and its libraries will make available all the batteries you want when targeting Wasm.

Building a greenfield Web application? Use the whole toolkit to hit the ground running. Carefully crafting a tiny Wasm module and integrating it back into an existing JavaScript project? Grab that one targeted library you need out from the toolkit and use it by itself.

Gloo is this modular toolkit.

Goals

  • Support both whole Web applications and small, targeted libraries: Gloo, and the collection of utility crates that make up its toolkit, should help you be productive if you are writing a green-field web application with Rust and Wasm. And it should also help you be productive if you are writing a small, targeted Wasm library that will be integrated into an existing JavaScript application.

  • Cultivate the Rust and Wasm library ecosystem: We want to use Gloo as a forcing function for creating and sharing the building blocks of Web development. The kinds of libraries that any framework or high-level library would need to build. We want to explicitly disentangle these libraries and make them available for sharing across the whole ecosystem.

  • Modular Toolkit, not Framework: Gloo should be a loose collection of utility crates that can be used individually, or all together. Gloo doesn't assume that it "owns" the whole Webpage, that it controls the Wasm start function, etc. This lack of assumptions enables reaching more use cases (such as surgically replacing a hot code path from JS) than monolithic frameworks can. Wherever possible, Gloo should prefer interfaces over implementations, so that different implementations with different approaches are swap-able.

  • Fast: Let's leverage Rust's zero-cost abstractions, and design with performance in mind, to show everyone how fast the Web can be ;)

  • Reliable: Every crate should be thoroughly tested. Headless browser tests. Quickcheck tests. Using the type system to make whole classes of bugs impossible.

  • Small: Small code size for faster page loads. No accidentally pulling in all of the panicking and formatting infrastructure. Users shouldn't have to make a trade off between using Gloo libraries and having small Wasm binaries.

  • Idiomatic: We want to build Rust-y APIs, that feel natural to use. The Web's APIs were not designed for the Rust language, and you can feel the impedance mismatch every now and then. Let's correct that, bridge the gap, and make libraries that are a joy to use.

Example

This example uses gloo::events for adding event listeners and gloo::timers for creating timeouts. It creates a <button> element and adds a "click" event listener to it. Whenever the button is clicked, it starts a one second timeout, which sets the button's text content to "Hello from one second ago!".

use gloo::{events::EventListener, timers::callback::Timeout};
use wasm_bindgen::prelude::*;

pub struct DelayedHelloButton {
    button: web_sys::Element,
    on_click: events::EventListener,
}

impl DelayedHelloButton {
    pub fn new(document: &web_sys::Document) -> Result<DelayedHelloButton, JsValue> {
        // Create a `<button>` element.
        let button = document.create_element("button")?;

        // Listen to "click" events on the button.
        let button2 = button.clone();
        let on_click = EventListener::new(&button, "click", move |_event| {
            // After a one second timeout, update the button's text content.
            let button3 = button2.clone();
            Timeout::new(1_000, move || {
                button3.set_text_content(Some("Hello from one second ago!"));
            })
            .forget();
        });

        Ok(DelayedHelloButton { button, on_click })
    }
}

Get Involved!

Want to help us build Gloo? Check out CONTRIBUTING.md!