Est. MMXXVI · A Tokio Project

TheTopcoatFramework

The full full-stack framework for Rust.

Server-rendered, reactive web apps, written entirely in Rust. No WebAssembly bundle, no separate API layer, no client build step. Sensible outerwear for any weather.

This dial is a Topcoat signal. It changes the weather in your browser, with no trip to the server.

I

A first fitting

Hello, world, in one file.

A page is an async function. A component is an async function. Both return markup from the view! macro, and components are called from markup with named arguments.

Because everything renders on the server, a component can query your database directly. There is no API layer to write between your data and your HTML.

use topcoat::{
    Result,
    context::Cx,
    router::{module_router, page},
    view::{View, component, view},
};

#[tokio::main]
async fn main() {
    topcoat::start(module_router!().build()).await.unwrap();
}

#[page]
async fn home(cx: &Cx) -> Result<impl View> {
    Ok(view! {
        <!DOCTYPE html>
        <html>
            <body>
                hello(name: "World")
            </body>
        </html>
    })
}

#[component]
async fn hello(cx: &Cx, name: &str) -> Result<impl View> {
    Ok(view! { <h1>"Hello, " (name) "!"</h1> })
}
II

Letters patent

What makes Topcoat different.

No. 1

Reactivity without boilerplate

Write browser interactions as type-checked Rust. Topcoat translates them to JavaScript, so a toggle never waits on the server.

No. 2

Shards

Mark a component as a shard and it re-renders on the server whenever its inputs change, swapping fresh HTML into the page.

No. 3

Honest templates

The view! macro is plain HTML with Rust's own if, for, and match. The topcoat fmt command formats it for you.

No. 4

Routes from modules

Lay out your modules and Topcoat infers the route tree, layouts included, without a build step.

No. 5

Components you own

Topcoat UI is a Tailwind component library inspired by shadcn/ui. Components are copied into your project, so you can change anything.

No. 6

Assets, fonts, and icons

Declare files with asset! and they are bundled with content-hashed names. Fontsource fonts and Iconify icons are built in.

No. 7

Locality of behavior

Components load their own data and check their own permissions through the request context. Memoization keeps repeated work cheap.

No. 8

Batteries included

Cookies, sessions, mail, localization, and Tailwind without Node. Plus integrations for htmx, Alpine AJAX, and Datastar.

III

Specimens

Examples from the workshop floor.

A $(...) expression is ordinary, type-checked Rust. Topcoat runs it on the server for the first render and translates it to JavaScript, so it re-runs instantly in the browser.

#[component]
async fn faq(cx: &Cx) -> Result<impl View> {
    let open = signal(cx, || false);

    Ok(view! {
        // Runs entirely in the browser; no server round-trip.
        <button @click=$(|_e| open.set(!open.get()))>"What is Topcoat?"</button>
        <p :hidden=$(!open.get())>"A full-stack Rust framework."</p>
    })
}
IV

Getting started

Out of the rain in six commands.

  1. Install the command-line tool. It creates apps, runs the development server, and bundles assets. It needs Rust 1.99 or newer.
  2. Create an app. The recommended setup includes routing, the browser runtime, Tailwind, Topcoat UI, icons, fonts, and a to-do example backed by SQLite.
  3. Create the database tables, then start the development server. It rebuilds and refreshes the page when you save.
  4. Open http://127.0.0.1:3000 and start editing src/app.rs.
cargo install topcoat-clitopcoat new my-app --recommendedcd my-appcargo run -- toasty migration generatecargo run -- toasty migration applytopcoat dev

Read the full getting started guide, or browse the API documentation.

V

On the drafting table

Planned for future seasons.

  • Static export
  • Validations
  • Authentication
  • Background jobs
  • Deeper Toasty integration
  • More Topcoat UI components
  • Image optimization
  • Markdown support
  • Islands

Have an idea? Open an issue.

VI

Inquiries

Questions frequently put to the tailor.