Introducing maple, a VDOM-less fine grained reactive web framework running in WASM

GitHub repository: lukechu10/maple: A reactive DOM library for Rust in WASM (github.com)

After discovering solid js, I wondered how feasible it would be to write such a framework in Rust. After two days of hacking around, here is the result!

It allows fine-grained reactivity to the DOM with no virtual DOM layer whatsoever! The reactivity system is based on signals and subscribes/dependents. For ergonomics, dependencies on signals are automatically detected. Here is an example:

let (state, set_state) = create_signal(0);
create_effect(move || {
    println!("The state changed. New value: {}", state());
});  // prints "The state changed. New value: 0" (note that the effect is always executed at least 1 regardless of state changes)

set_state(1); // prints "The state changed. New value: 1"
set_state(2); // prints "The state changed. New value: 2"
set_state(3); // prints "The state changed. New value: 3"

Creating DOM nodes is accomplished with the template! proc-macro. When a signal is used inside the template! macro, create_effect is implicitly called and the is DOM updated whenever the value changes.

If you look at some of the examples in the README, you will find that the API is quite similar to that of React hooks. Unlike React hooks, however, the actual function is only executed once and it is the effects that are executed multiple times. This means that the template! macro can generate real DOM nodes and it is the code inside create_effect that is executed multiple times to update the DOM.

Disclaimer:

The library is currently very WIP and very feature incomplete. For instance, it is not possible to access the Event object inside event listeners (it works on master branch now), nor is it possible to get references to DOM nodes without manually creating them outside of the template! macro. This makes it impossible to create, say, TodoMVC without a workaround because it would be impossible to get the text of the input field.

If you are willing to help out, please head over to the GitHub repository. Feedback, issues and PRs are welcome!

3 Likes

This is amazing! Solid is one of my favourite libraries and I've always wanted to see it implemented in Rust. One suggestion: you can mark mod internal with #[doc(hidden)] so it doesn't show up in the documentation.

1 Like

Done! Thanks for catching that.

1 Like