Skip to content
Tech News
← Back to articles

Topcoat: The full full-stack framework for Rust

read original more articles
Why This Matters

Topcoat introduces a full-stack Rust framework that simplifies web app development by enabling server-rendered components with client reactivity, eliminating the need for separate API layers and complex client-side code. Its approach enhances productivity and reduces boilerplate, making Rust more accessible for full-stack development. As an early-stage project, it offers innovative features that could influence future web frameworks, though it is subject to change.

Key Takeaways

Topcoat

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 :: { Router , RouterBuilderDiscoverExt , page } , view :: { component , view } , } ; # [ tokio :: main ] async fn main ( ) { topcoat :: start ( Router :: builder ( ) . discover ( ) . build ( ) ) . await . unwrap ( ) ; } # [ page ( "/" ) ] async fn home ( ) -> Result { view ! { <! DOCTYPE html> <html> <body> hello ( name : "World" ) </body> </html> } } # [ component ] async fn hello ( name : & str ) -> Result { view ! { <h1> "Hello, " ( name ) "!" </h1> } }

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. <button @click=$ ( |_e| open . set ( !open . get ( ) ) ) > "What is Topcoat?" </button> <p : hidden=$ ( !open . get ( ) ) > "A fullstack Rust framework." </p> }

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:

... continue reading