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>
}
}
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>
}
}
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>
}
}
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>
}
}
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>
}
}
Getting Started
cargo install cargo-leptos
cargo leptos new --git https://github.com/leptos-rs/start
cargo leptos watch
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)