DEV Community

Alex Spinov
Alex Spinov

Posted on

Leptos Has a Free API You're Not Using

Leptos is a Rust web framework with fine-grained reactivity. It compiles to WebAssembly for the frontend and runs on the server — same language, same types, full-stack.

The Free APIs You're Missing

1. Signals — Fine-Grained Reactivity

use leptos::*;

#[component]
fn Counter() -> impl IntoView {
    let (count, set_count) = create_signal(0);
    let doubled = move || count.get() * 2;

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

2. Server Functions — Type-Safe RPC

#[server(GetUser)]
async fn get_user(id: String) -> Result<User, ServerFnError> {
    let user = db::find_user(&id).await?;
    Ok(user)
}

#[component]
fn UserProfile() -> impl IntoView {
    let user = create_resource(|| (), |_| get_user("123".to_string()));
    view! {
        <Suspense fallback=move || view! { <p>"Loading..."</p> }>
            {move || user.get().map(|u| view! { <h1>{u.name}</h1> })}
        </Suspense>
    }
}
Enter fullscreen mode Exit fullscreen mode

3. Actions — Form Handling Without JS

#[server(CreatePost)]
async fn create_post(title: String, content: String) -> Result<(), ServerFnError> {
    db::create_post(&title, &content).await?;
    Ok(())
}

#[component]
fn PostForm() -> impl IntoView {
    let create = create_server_action::<CreatePost>();
    view! {
        <ActionForm action=create>
            <input type="text" name="title"/>
            <textarea name="content"/>
            <button type="submit">"Create"</button>
        </ActionForm>
    }
}
Enter fullscreen mode Exit fullscreen mode

Works without JavaScript. Progressive enhancement built in.

4. Islands Architecture — Partial Hydration

#[island]
fn InteractiveWidget() -> impl IntoView {
    let (active, set_active) = create_signal(false);
    view! {
        <button on:click=move |_| set_active.update(|a| *a = !*a)>
            {move || if active.get() { "Active" } else { "Inactive" }}
        </button>
    }
}
Enter fullscreen mode Exit fullscreen mode

Only island components ship JavaScript. Static content stays as HTML.

5. Streaming SSR — Progressive Rendering

#[component]
fn Dashboard() -> impl IntoView {
    let stats = create_resource(|| (), |_| fetch_stats());
    let recent = create_resource(|| (), |_| fetch_recent());

    view! {
        <h1>"Dashboard"</h1>
        <Suspense fallback=|| "Loading stats...">
            {move || stats.get().map(|s| view! { <StatsWidget data=s/> })}
        </Suspense>
        <Suspense fallback=|| "Loading recent...">
            {move || recent.get().map(|r| view! { <RecentList items=r/> })}
        </Suspense>
    }
}
Enter fullscreen mode Exit fullscreen mode

Getting Started

cargo install cargo-leptos
cargo leptos new --git https://github.com/leptos-rs/start
cargo leptos watch
Enter fullscreen mode Exit fullscreen mode

Need data from any website delivered as clean JSON? I build production web scrapers that handle anti-bot, proxies, and rate limits. 77 scrapers running in production. Email me: Spinov001@gmail.com

Check out my awesome-web-scraping list for the best scraping tools and resources.

Top comments (0)