← all posts

2026-08-05

One binary to serve them all

The architecture of this site: Leptos SSR, Axum, SQLite and Markdown in a single deployable Rust binary.

This whole site: server, UI, database access, content pipeline: compiles to one binary plus a folder of static assets. Here is the shape of it.

The stack

  • Leptos 0.8 with server-side rendering; the same components compile to WASM for client-side hydration
  • Axum as the HTTP layer, with Leptos routes mounted on it
  • SQLite through sqlx, with migrations run automatically at startup
  • Markdown files in content/, seeded into the database on boot and rendered with pulldown-cmark

Why SQLite and Markdown?

Markdown is a great authoring format; a database is a great serving format. So content is written as .md files (versioned in git) and upserted into SQLite at startup. The site only ever reads from the database: which means a future admin section can write straight to it, no redeploy needed.

Server functions

Leptos server functions make the client/server split almost invisible:

#[server]
pub async fn get_posts() -> Result<Vec<PostMeta>, ServerFnError> {
    let pool = expect_context::<sqlx::SqlitePool>();
    // runs only on the server; the client gets a typed fetch call
}

On the server this queries SQLite directly; in the browser the same call becomes a fetch to an auto-generated endpoint. One function signature, zero API boilerplate.