76 releases

0.7.0-preview2 Apr 29, 2024
0.6.11 Apr 10, 2024
0.6.9 Mar 4, 2024
0.5.4 Nov 28, 2023
0.0.19 Nov 27, 2022

#1664 in Web programming

Download history 7009/week @ 2024-01-24 6342/week @ 2024-01-31 6852/week @ 2024-02-07 7171/week @ 2024-02-14 7448/week @ 2024-02-21 8712/week @ 2024-02-28 8736/week @ 2024-03-06 7029/week @ 2024-03-13 8728/week @ 2024-03-20 8809/week @ 2024-03-27 9042/week @ 2024-04-03 8949/week @ 2024-04-10 9425/week @ 2024-04-17 8706/week @ 2024-04-24 7342/week @ 2024-05-01 6814/week @ 2024-05-08

33,834 downloads per month
Used in 120 crates (7 directly)

MIT license

405KB
8K SLoC

The reactive system for the Leptos Web framework.

Fine-Grained Reactivity

Leptos is built on a fine-grained reactive system, which means that individual reactive values (“signals,” sometimes known as observables) trigger the code that reacts to them (“effects,” sometimes known as observers) to re-run. These two halves of the reactive system are inter-dependent. Without effects, signals can change within the reactive system but never be observed in a way that interacts with the outside world. Without signals, effects run once but never again, as there’s no observable value to subscribe to.

Here are the most commonly-used functions and types you'll need to build a reactive system:

Signals

  1. Signals: create_signal, which returns a (ReadSignal, WriteSignal tuple, or create_rw_signal, which returns a signal RwSignal without this read-write segregation.
  2. Derived Signals: any function that relies on another signal.
  3. Memos: create_memo, which returns a Memo.
  4. Resources: create_resource, which converts an async Future into a synchronous Resource signal.
  5. Triggers: create_trigger, creates a purely reactive Trigger primitive without any associated state.

Effects

  1. Use create_effect when you need to synchronize the reactive system with something outside it (for example: logging to the console, writing to a file or local storage)
  2. The Leptos DOM renderer wraps any [Fn] in your template with create_effect, so components you write do not need explicit effects to synchronize with the DOM.

Example

use leptos_reactive::*;

// creates a new reactive runtime
// this is omitted from most of the examples in the docs
// you usually won't need to call it yourself
let runtime = create_runtime();
// a signal: returns a (getter, setter) pair
let (count, set_count) = create_signal(0);

// calling the getter gets the value
// can be `count()` on nightly
assert_eq!(count.get(), 0);
// calling the setter sets the value
// can be `set_count(1)` on nightly
set_count.set(1);
// or we can mutate it in place with update()
set_count.update(|n| *n += 1);

// a derived signal: a plain closure that relies on the signal
// the closure will run whenever we *access* double_count()
let double_count = move || count.get() * 2;
assert_eq!(double_count(), 4);

// a memo: subscribes to the signal
// the closure will run only when count changes
let memoized_triple_count = create_memo(move |_| count.get() * 3);
// can be `memoized_triple_count()` on nightly
assert_eq!(memoized_triple_count.get(), 6);

// this effect will run whenever `count` changes
create_effect(move |_| {
    println!("Count = {}", count.get());
});

// disposes of the reactive runtime
runtime.dispose();

Dependencies

~3.5–8.5MB
~155K SLoC