topcoat README

The project's README from github.com/tokio-rs/topcoat. As one markdown file: README.md.

Topcoat

The full full-stack framework for Rust

Crates.io Docs.rs MIT licensed Build Status Discord chat

Topcoat is a modular, batteries-included Rust framework for building full-stack apps. It prioritizes simplicity and productivity. See Learn Topcoat to get started, or the Roadmap for what's coming next.

Early-stage and experimental. Expect breaking changes.

use topcoat::{
    Result,
    router::{Router, RouterBuilderDiscoverExt, page},
    view::{View, component, view},
};

#[tokio::main]
async fn main() {
    topcoat::start(Router::builder().discover().build()).await.unwrap();
}

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

#[component]
async fn hello(name: &str) -> Result<impl View> {
    Ok(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:

#[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>
    })
}

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:

#[component]
async fn search(cx: &Cx) -> Result<impl View> {
    let query = signal(cx, String::new);

    Ok(view! {
        <input @input=$(|e: Event| query.set(e.target.value))>

        // Updates as the user types.
        search_results(query: $(query.get()))
    })
}

#[shard]
async fn search_results(cx: &Cx, query: String) -> Result<impl View> {
    Ok(view! {
        <ul>
            // Your own server-side code, like a database query:
            for product in search_products(cx, &query).await? {
                <li>(product.name)</li>
            }
        </ul>
    })
}

Powerful, unsurprising HTML templates

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

view! {
    <nav>
        for item in nav_items {
            <a
                href=(item.url)
                if item.url == current_path {
                    aria-current="page"
                    class="active"
                }
            >
                (item.label)
            </a>
        }
    </nav>
}

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

Module-based routing

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

src/
|-- app.rs              -> /            (and the root <html> 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

Premade components you can edit

Topcoat UI is a component library based on Tailwind inspired by shadcn/ui. Components are copied into your project via the topcoat ui CLI command, meaning you can freely change their design and functionality to fit your use case:

#[component]
async fn delete_card() -> Result<impl View> {
    Ok(view! {
        card(
            card_header(
                card_title("Delete workspace")
                card_description(
                    "This permanently removes the workspace and all of its data."
                )
            )
            card_footer(
                attrs: attributes! { class="justify-end" },
                button(variant: ButtonVariant::Ghost, "Cancel")
                button(variant: ButtonVariant::Destructive, "Delete workspace")
            )
        )
    })
}

Asset bundling

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! { <img src=(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

Enable the tailwind feature to integrate Tailwind into your project:

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

Learn Topcoat

Start here

Rendering

Routing

Working with requests

Asset system

Client reactivity

Miscellaneous

Third-party integrations

Roadmap

Planned features we'd like to bring to Topcoat. Have an idea? Open an issue.

topcoat (tokio-rs/topcoat)

Searching Database…

6.1K ·GitHub
Что это такое?Topcoat — это модульный фреймворк на Rust со всем необходимым из коробки для создания полноценных веб-приложений, в которых компоненты отрисовываются на сервере и могут напрямую обращаться к базе данных.
Чем это отличается от типичных веб-фреймворков на Rust?Topcoat отрисовывает всю разметку на сервере и позволяет компонентам быть асинхронными и напрямую обращаться к базе данных, поэтому отдельный слой API не нужен. Его выражения $(...) — это обычный Rust, который также работает в браузере, без wasm-бандла и шага сборки для клиента.
Как запустить проект на Topcoat?Вы следуете руководству Getting started, чтобы создать новый проект, установить CLI Topcoat и запустить dev-сервер.
Нужен ли Node.js или отдельный шаг сборки JS для реактивных частей?Нет. Выражения $(...) — это обычный Rust, который Topcoat вычисляет на сервере и сам переводит в JavaScript, поэтому wasm-бандл и шаг сборки для клиента не нужны. Tailwind также можно включить через встроенный флаг фичи.
Готов ли Topcoat к использованию в продакшене?Нет: проект сам описывает себя как находящийся на ранней стадии и экспериментальный, и стоит ожидать несовместимых изменений.
Что такое shards в Topcoat?Shards — это компоненты, помеченные #[shard], которые Topcoat заново отрисовывает на сервере каждый раз, когда меняется один из их аргументов $(...), и вставляет новый HTML прямо на страницу на место старого.
Что такое Topcoat UI?Topcoat UI — это библиотека компонентов на основе Tailwind, вдохновлённая shadcn/ui. Компоненты копируются в ваш проект с помощью команды CLI topcoat ui, чтобы вы могли свободно менять их дизайн и поведение.
Можно ли настроить маршруты без ручной конфигурации?Да, Topcoat может при желании полностью вывести дерево маршрутов напрямую из структуры модулей вашего приложения, без необходимости в шаге сборки.
Поддерживает ли Topcoat аутентификацию?Не полностью: уже есть аутентификация на основе сессий с входом и выходом, скользящим сроком действия и ротацией токенов, но полная поддержка аутентификации и валидации всё ещё в планах.
Creator
tokio-rs
Size
6.8 MB
Stars
6.1K
Age
6mo
Commits · 90 Days