Leptos
Build fast web applications with Rust.
README
Leptos
- ```rust
- use leptos::*;
- #[component]
- pub fn SimpleCounter(initial_value: i32) -> impl IntoView {
- // create a reactive signal with the initial value
- let (value, set_value) = create_signal(initial_value);
- // create event handlers for our buttons
- // note that `value` and `set_value` are `Copy`, so it's super easy to move them into closures
- let clear = move |_| set_value(0);
- let decrement = move |_| set_value.update(|value| *value -= 1);
- let increment = move |_| set_value.update(|value| *value += 1);
- // create user interfaces with the declarative `view!` macro
- view! {
- <div>
- <button on:click=clear>Clear</button>
- <button on:click=decrement>-1</button>
- // text nodes can be quoted or unquoted
- <span>"Value: " {value} "!"</span>
- <button on:click=increment>+1</button>
- </div>
- }
- }
- // we also support a builder syntax rather than the JSX-like `view` macro
- #[component]
- pub fn SimpleCounterWithBuilder(initial_value: i32) -> impl IntoView {
- use leptos::html::*;
- let (value, set_value) = create_signal(initial_value);
- let clear = move |_| set_value(0);
- let decrement = move |_| set_value.update(|value| *value -= 1);
- let increment = move |_| set_value.update(|value| *value += 1);
- // the `view` macro above expands to this builder syntax
- div().child((
- button().on(ev::click, clear).child("Clear"),
- button().on(ev::click, decrement).child("-1"),
- span().child(("Value: ", value, "!")),
- button().on(ev::click, increment).child("+1")
- ))
- }
- // Easy to use with Trunk (trunkrs.dev) or with a simple wasm-bindgen setup
- pub fn main() {
- mount_to_body(|| view! {
- <SimpleCounter initial_value=3 />
- })
- }
- ```
About the Framework
Leptos is a full-stack, isomorphic Rust web framework leveraging fine-grained reactivity to build declarative user interfaces.
What does that mean?
- Isomorphic: Leptos provides primitives to write isomorphic server functions, i.e., functions that can be called with the “same shape” on the client or server, but only run on the server. This means you can write your server-only logic (database requests, authentication etc.) alongside the client-side components that will consume it, and call server functions as if they were running in the browser, without needing to create and maintain a separate REST or other API.
- Web: Leptos is built on the Web platform and Web standards. The router is designed to use Web fundamentals (like links and forms) and build on top of them rather than trying to replace them.
- Framework: Leptos provides most of what you need to build a modern web app: a reactive system, templating library, and a router that works on both the server and client side.
- Fine-grained reactivity: The entire framework is built from reactive primitives. This allows for extremely performant code with minimal overhead: when a reactive signal’s value changes, it can update a single text node, toggle a single class, or remove an element from the DOM without any other code running. (So, no virtual DOM overhead!)
- Declarative: Tell Leptos how you want the page to look, and let the framework tell the browser how to do it.
nightly Note
Most of the examples assume you’re using nightly version of Rust and the nightly feature of Leptos. To use nightly Rust, you can either set your toolchain globally or on per-project basis.
To set nightly as a default toolchain for all projects (and add the ability to compile Rust to WebAssembly, if you haven’t already):
- ```
- rustup toolchain install nightly
- rustup default nightly
- rustup target add wasm32-unknown-unknown
- ```
If you'd like to use nightly only in your Leptos project however, add [rust-toolchain.toml](https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file) file with the following content:
- ```toml
- [toolchain]
- channel = "nightly"
- targets = ["wasm32-unknown-unknown"]
- ```
The nightly feature enables the function call syntax for accessing and setting signals, as opposed to .get() and .set(). This leads to a consistent mental model in which accessing a reactive value of any kind (a signal, memo, or derived signal) is always represented as a function call. This is only possible with nightly Rust and the nightly feature.