silkenweb 0.4.0

A library for building web apps
Documentation

Silkenweb

tests crates.io Documentation MIT/Apache-2 licensed Discord

A library for building reactive web apps.

Features

  • No VDOM. Fine grained reactivity using signals to minimize DOM API calls.
  • Uses plain Rust syntax rather than a macro DSL.
  • Routing.
  • Tauri support
  • Server side rendering with hydration, and compile time pre-rendering.
  • Downcasts Js objects for you, where the type is known at compile time. For example, button().on_click(...) passes your event handler a web_sys::HtmlInputElement and a web_sys::MouseEvent.

Example: A Simple Counter

use futures_signals::signal::{Mutable, SignalExt};
use silkenweb::{elements::html::*, prelude::*, value::Sig};

fn main() {
    let count = Mutable::new(0);
    let count_text = count.signal().map(|i| format!("{}", i));
    let inc = move |_, _| {
        count.replace_with(|i| *i + 1);
    };

    let app = div()
        .child(button().on_click(inc).text("+"))
        .child(p().text(Sig(count_text)));

    mount("app", app);
}

Quick Start

rustup target add wasm32-unknown-unknown
cargo install --locked trunk
cd examples/counter
trunk serve --open

Design Tradeoffs

No VDOM

There are potential performance advantages to using a signals based approach, as you're telling the compiler explicitly what the dependencies within your app are, at compile time. With a simple VDOM based approach, you have to figure out what changed at runtime. The tradeoff here is slightly more complex code when using a signals based approach.

What tends to happen in practice is that VDOM based approaches will add some mechanism so that every time someting changes, your app doesn't need to completely re-render the VDOM. This inevitably adds some complexity to VDOM based approaches.

No Macro DSL

There are many advantages to using plain Rust syntax:

  • No macro DSL to learn.
  • Code completion with rust-analyser.
  • The documentation is structured in a familiar manner, courtesy of rustdoc.
  • Code formatting with rustfmt.
  • Excellent compiler errors, courtesy of rustc.
  • Use Rust's well thought out, composable abstractions. Need control flow in your components? Use if, match, dyn traits, or whatever else Rust provides.

There's nothing to stop a macro DSL being built on top of Silkenweb, to complement the builder APIs.

The advantage of using a macro DSL is that syntax is tailored to defining document structure. Rust syntax is fairly well suited to this, so it's not much of a benefit in reality.

Learning

Pre Built Examples