tokio-rs/topcoat: A batteries-included framework for building web apps · GitHub

🔥 Explore this awesome post from Hacker News 📖

📂 **Category**:

✅ **What You’ll Learn**:

The full full-stack framework for Rust

Topcoat is a modular, batteries-included Rust framework for building fullstack apps. It prioritizes simplicity and productivity. See the Getting started guide to set up a new project.

Early-stage and experimental. Expect breaking changes.

use topcoat::{
    Result,
    router::💬,
    view::
    signal open = false;

    // Runs entirely in the browser; no server round-trip.
    <button @click=$(,
};

#[tokio::main]
async fn main()  open.set(!open.get()))>"What is Topcoat?"
    

:hidden=$(!open.get())>"A fullstack Rust framework."

#[page("https://github.com/")] async fn home() -> Result { view! 💬 } #[component] async fn hello(name: &str) -> Result { view! { } }

What makes Topcoat different

Client reactivity without the boilerplate

Topcoat renders all markup on the server: components can be async and query the database directly, eliminating all the traditional boilerplate needed for a separate API layer. Interactivity does not have to cost a round-trip, though. A $(...) expression is ordinary type-checked Rust that Topcoat evaluates on the server for the initial render and also translates to JavaScript, so it re-runs instantly in the browser. No wasm bundle, no client build step:

view! {
    signal open = false;

    // Runs entirely in the browser; no server round-trip.
    
    

:hidden=$(!open.get())>"A fullstack Rust framework."

}

When an update does need the server, like fresh search results, mark the component as a #[shard]. Topcoat re-renders it on the server whenever one of its $(...) arguments changes and swaps the new HTML in place:

Powerful, unsurprising HTML templates

The view! macro stays true to HTML and Rust. Use familiar Rust control flow as part of your templates:

Use the topcoat fmt CLI command to automatically format view! snippets (and other macros) across your codebase.

Topcoat can optionally infer your route tree from your app’s module structure (without a build step):

src/
|-- app.rs              -> /            (and the root  layout)
`-- app/
    |-- about.rs        -> /about
    |-- _marketing.rs                  (layout, no URL segment)
    |-- _marketing/
    |   `-- pricing.rs  -> /pricing
    |-- posts.rs        -> /posts
    |-- posts/
    |   `-- id.rs       -> /posts/{post_id}
    `-- api/
        `-- health.rs   -> GET /api/health

The bundler scans your compiled binary for asset! calls, copies (or even downloads) every file into a local asset directory, and allows Topcoat to serve them efficiently with aggressive browser caching.

const FERRIS: Asset = asset!("./ferris.png");

view! { (FERRIS)> }

Topcoat also ships with utilities for web fonts and icons, as well as easy integrations for Fontsource (Google Fonts) and Iconify.

Built-in Tailwind support

Enabled the tailwind feature to integrate Tailwind into your project effortlessly:

view! { "stylesheet" href=(topcoat::tailwind::stylesheet!())> }

Start here

Rendering

Routing

  • Router: pages, layouts, and API routes; manual and auto-discovered.
  • Module-based routing: derive the route table from your module tree.

Working with requests

  • Request context (Cx): the value pages, layouts, and components read from.
  • App context: share long-lived values across requests, keyed by type.
  • Memoization: #[memoize] for per-request caching and fan-out dedup.
  • Functions, not middlewares: the recommended way to model auth and other request-scoped concerns.
  • Cookies: read and write the request cookie jar, with signed, encrypted, and prefixed cookies.
  • Sessions: bring-your-own-storage session authentication: login/logout lifecycle, sliding expiration, and token rotation.

Asset system

  • Assets: declare assets in Rust, serve them with content-hashed URLs.
  • Fonts: bundle and serve web fonts.
  • Icons: download Iconify icon sets or declare your own.

Client reactivity

  • The runtime: signals, $(...) expressions, @ event handlers, and : bind attributes.
  • Expressions: the dual Rust/JavaScript expression language and its vocabulary.
  • Procedures: async server functions callable from the browser.
  • Shards: components that re-render on the server when their arguments change.

Third-party integrations

  • Tailwind: Tailwind CSS without Node, wired into the asset pipeline.
  • htmx: drive partial HTML swaps from the server with request/response header helpers.

{💬|⚡|🔥} **What’s your take?**
Share your thoughts in the comments below!

#️⃣ **#tokiorstopcoat #batteriesincluded #framework #building #web #apps #GitHub**

🕒 **Posted on**: 1784368808

🌟 **Want more?** Click here for more info! 🌟

By

Leave a Reply

Your email address will not be published. Required fields are marked *