DEV Community

Alex Spinov
Alex Spinov

Posted on

Leptos Has a Free API: Build Full-Stack Web Apps in Rust

What if your web framework had Rust's type safety, compiled to WebAssembly, AND had server functions like Next.js? Meet Leptos.

What Is Leptos?

Leptos is a full-stack web framework for Rust. It compiles to WebAssembly for the client and runs natively on the server. You get:

  • Fine-grained reactivity (like Solid.js, not like React)
  • Server functions (like Next.js server actions)
  • SSR + hydration
  • Type-safe routing
  • Compile-time checking for everything

The Syntax

use leptos::*;

#[component]
fn Counter() -> impl IntoView {
    let (count, set_count) = create_signal(0);

    view! {
        <button on:click=move |_| set_count.update(|n| *n += 1)>
            "Count: " {count}
        </button>
    }
}
Enter fullscreen mode Exit fullscreen mode

If you know React + Rust, you can read this immediately. The view! macro looks like JSX. Signals work like Solid.js. But it's all type-checked at compile time.

Server Functions

#[server(GetUsers)]
pub async fn get_users() -> Result<Vec<User>, ServerFnError> {
    let users = sqlx::query_as::<_, User>("SELECT * FROM users")
        .fetch_all(&pool)
        .await?;
    Ok(users)
}

#[component]
fn UserList() -> impl IntoView {
    let users = create_resource(|| (), |_| get_users());

    view! {
        <Suspense fallback=move || view! { <p>"Loading..."</p> }>
            {move || users.get().map(|data| view! {
                <ul>
                    {data.unwrap().into_iter().map(|user| view! {
                        <li>{user.name}</li>
                    }).collect_view()}
                </ul>
            })}
        </Suspense>
    }
}
Enter fullscreen mode Exit fullscreen mode

The #[server] macro means this function runs on the server, but you call it from the client like a normal function. Type-safe across the network boundary.

Why Leptos

1. Performance — WASM is 10-100x faster than JavaScript for computation-heavy tasks.

2. Type safety — If it compiles, the client-server contract is correct. No runtime type errors.

3. Fine-grained reactivity — Like Solid.js: only the exact DOM nodes that changed update. No virtual DOM.

4. One language — Rust on server AND client. Share types, validation, business logic.

5. Binary size — A Leptos counter app compiles to ~30KB WASM. A React counter ships ~170KB JS.

cargo install cargo-leptos
cargo leptos new --git leptos-rs/start
cargo leptos watch
Enter fullscreen mode Exit fullscreen mode

Building high-performance web apps? Check out my developer tools or email spinov001@gmail.com.

Top comments (0)