Rendered at 17:44:41 GMT+0000 (Coordinated Universal Time) with Cloudflare Workers.
carllerche 2 days ago [-]
I didn't expect to see this here yet. We opened up the repo because we ran out of private CI usage. A blog post is coming next week :). Happy to answer questions here though.
One thing to keep in mind, the main reason for Topcoat to exist is that many organizations are already using Rust for infrastructure-level or performance sensitive reasons and often just want to build a web app using the programming language they already use.
Both Loco and Topcoat aims to be "batteries included" but that means very different things to each project. Topcoat aims to make it easy to build reactive apps without writing any browser JS (or Rust). It uses a similar strategy to Hotwire, HTMX, Datastar, ... It also will default to using the Toasty ORM (though topcoat is modular so you a swap it out). Topcoat is very young and there is a lot more to build.
jonahx 2 days ago [-]
I'll say that first code snippet is a fantastic TLDR.
jjice 2 days ago [-]
Oh man I'd love a nice full stack framework in Rust! Django, Laravel, and Rails are very neat. I used to be a micro framework kind of guy, but having everything integrated is more and more appealing over the last few years.
This would take a long time to get feature complete with the core of those big full stack frameworks, but I'm rooting for it! Getting to use the Rust type system with a full stack web framework sounds incredible.
carllerche 2 days ago [-]
Yes, that is the goal. Those frameworks have a bit (more than a decade) head start though :) there is a lot to build.
> Those frameworks have a bit (more than a decade) head start
A decade? More like 21 years
carllerche 2 days ago [-]
Don't remind me... I'm old. (I was involved w/ Ruby on Rails in the early days)
frio 2 days ago [-]
Exciting, but I’d give a lot for an equivalent to Django. There are very few problems I need to solve that are fixed by htmx style “full stack” apps, but many that are solved by the generated admin, authentication framework, caching, eventing etc.
Unfortunately, you end up bound to Python’s poor performance and poor typing stories, which Rust solves in spades.
m4tx 6 hours ago [-]
Shameless plug: I've been developing https://cot.rs/ for a while, which is strongly inspired by Django, and auto migrations, admin panel, auth, etc. are among the features supported by Cot.
westurner 2 days ago [-]
Here's a v0.0.2 jinja2rs built on minijinja with optional python compatibility; CompatMode::Django(…) Django template language (filters, app-directory loader, auto-escape) :
Which Rust components are like the Django ORM and django.contrib.admin and DRF/FastAPI; with convention over configuration and tests and great docs?
westurner 18 hours ago [-]
When I searched for that last sentence in full, I found this:
dj-bolt/django-bolt: Rust-powered API framework for Django achieving 60k+ RPS. Uses Actix Web for HTTP, PyO3 for Python bridging, msgspec for serialization. Decorator-based routing with built-in auth and middleware.https://github.com/dj-bolt/django-bolt :
> Faster than FastAPI, but with Django ORM, Django Admin, and Django packages. [...] Django-Bolt is a high-performance API framework for Django, providing Rust-powered API endpoints capable of 188k+ RPS.
newaccountman2 2 days ago [-]
You could check out Loco.rs
I don't use it personally because I don't like the look of SeaORM
mamcx 2 days ago [-]
This sound fantastic and Django is the main thing I miss from python.
htmx+ tailwindcss is the one combo that is right and I use it so seeing is the direction give me hope.
Some notes, I hope can be considered!:
- The main thing is the auto admin, then `auth`, is great that the `auth` is mean to have a one-to-one connection for your own extensions
- The main pain is that everything is tangled to the ORM and the auto-admin
What I have done informally is that with traits I have something like `ListQuery` and compose `Paginate(ListQuery)`.
Then pure descriptors of what the ui DO, but not what it looks like and not even html at all.
THEN, I inject the stucts/enums (all Ui is things like `Label{...}` with not logic at all in templating, all the server side is in charge of pre-render) into some templating and there is where the ui is alive, but replacing is 100% doable and expected.
What I miss is a way to introspect to auto-generate things more auto.
hoistbypetard 2 days ago [-]
This seems to be missing both an ORM and an argument for building without one; I'd have a hard time calling something a "full full-stack framework" without either an ORM or a very well-articulated statement for why that's a non-goal and what convention replaces it, allows for auto-generated admin pages, etc.
I don't think an ORM is necessary, but I do think you need to say what people are meant to do instead and how your batteries are included without it, if you're going that direction.
Hmm... I'm a big fan of a lot of the things that the tokio project has built and a happy user of axum.
I'm not sure that projects like Topcoat and something like their ORM is a great direction for the project, and worry that they will possibly gain outsized adoption in the community based on name recognition rather than merit.
carllerche 2 days ago [-]
I think it is highly likely topcoat / toasty will get split out. It is just work, especially since tokio-rs has more CI usage available than the default GitHub org.
BobbyTables2 2 days ago [-]
Does “full-stack” really mean “webserver + webpage” nowadays?
It is early, a lot is coming, but you can already build good stuff now.
hingler36 2 days ago [-]
Super exciting stuff, especially coming from one of the best projects in Rust (imo). Can't wait to see where this goes!
fuddle 2 days ago [-]
This looks great, it looks like something I'd use long term instead of Typescript. I do see a couple of things missing before I could port my web app over.
Integration with -
Design systems such as Shadcn or Radix UI.
An example on how to integrate with an OpenAPI endpoint.
carllerche 2 days ago [-]
All on the roadmap :) topcoat-ui is already usable with Shadcn components (recent Pr: https://github.com/tokio-rs/topcoat/pull/118) we are still working on pulling in more components.
Re: OpenAPi you want to consume or provide an OpenAPI endpoint? I’m assuming you want to provide one. This is probably on the medium term roadmap after other stuff like UI, tighter ORM integration, email, etc…
fuddle 14 hours ago [-]
This would be consuming an openapi endpoint from my rust service generated using utoipa. Currently I generate an openapi.yaml file and use openapi-typescript to generate the api bindings.
az09mugen 1 days ago [-]
The simple fact that there is the use of "full fullstack" means that word "fullstack" lost its meaning over time.
So what does fullstack mean now ?
seanclayton 2 days ago [-]
Back in my day 'batteries-included' at least included schemas/models and a database abstraction. Claude can whip one up quick!
carllerche 2 days ago [-]
It's built: github.com/tokio-rs/toasty/, just not tightly integrated yet. That is on the roadmap.
valorzard 2 days ago [-]
This might sound dumb, but is Tokio slowly (if it hasn't already) become the Spring/Spring Boot for Rust?
carllerche 2 days ago [-]
Depends on what you mean by that. Tokio the runtime is lean, and stable. Tokio the org is a collective of devs working on creating and maintaining a full ecosystem for building client and server apps with rust.
valorzard 2 days ago [-]
yeah i mean more so, is the goal for topcoat and toasty and friends to become like Spring Boot from Java but for Rust.
(also it was nice meeting you at the zscaler talk you gave a couple of weeks ago)
frytaped 2 days ago [-]
How does this compare to Leptos ?
carllerche 2 days ago [-]
Topcoat is entirely server rendered. Reactivity is added using attributes and other signals to a JS “runtime” shipped with topcoat. It is a similar idea to htmx/datastar/hotwire where as Leptos uses wasm to run rust in the browser as well as the server, more like nextjs or solidjs
jdw64 2 days ago [-]
I'm looking at it with anticipation, but I want to hold back because I don't want to offend you... I think this works as a wrong pattern in Rust.
When I see syntax like $(...), it looks like a transpiler that embeds Rust AST inside JS. I think it would make Rust's already terrible developer experience even worse. I think the actual value of the string length on the server side will differ, specifically `len()`.
And I'm not sure if bundling binaries and assets this way is the right approach. This feels less like Rust and more like a DSL that intersects Rust and JS. it feels like something different.
I like Tokio and think it's really well made, but this framework seems a bit wrong to me.
carllerche 2 days ago [-]
I don't take offense from differences in design opinion. The goal of topcoat is to be opinionated and not make everyone happy. And JS libs are a heavy inspiration. They do a lot right and have years of experience in the browser-app space. If you don't like it, Axum aims to be the lower-level HTTP router that anyone can build their own abstractions on top of.
That said, if you are up to it, I would ask that you try using it and provide your thoughts after using it as an issue. Feedback is appreciated.
jdw64 2 days ago [-]
Thank you. I hope I didn't offend you. First, I think the len() part is problematic. Could you check that for me? I think it's calling Rust's str::len() and using JS's String.length, which I think should be aligned with UTF-8.
I'll try it out next time and give feedback later. And you're right, it's just a difference of opinion.
Also, for the API side, Unicode strings are usually 4 kinds right? I think using Rust-style snake_case, we might need separate functions like len(), utf16_len(), and so on. But I'm not sure how to handle the abstraction between libraries and browsers.
Sorry for being critical. I'm not that good of a programmer, so it might be a mistaken observation. Please check it.
canadiantim 2 days ago [-]
Looks incredible, also loving toasty. Great work all around
27183 2 days ago [-]
Is the name a POR-15 product reference? Incredible if so :D
\m/_(>.<)_\m/
newaccountman2 2 days ago [-]
I don't feel like this is solving the painpoints I feel in the Rust web framework ecosystem. And how is it full-stack if they don't have anything for the DB layer in here?
carllerche 2 days ago [-]
This will (very soon) integrate tighter with the Toasty ORM http://github.com/tokio-rs/toasty/. E.g. tight form -> record flow. We are shipping now though to get usage.
What pain points do you have in the Rust web framework ecosystem? Happy to hear.
newaccountman2 2 days ago [-]
Oh cool, I will poke around Toasty. I am in the process of having LLM switch a project from some raw sqlx jank to Diesel, and mildly annoyed about some the boilerplate Diesel involves. Will have to see if Toasty solves it and whether it lets one query for arbitrary structs and add fields to structs from query results (e.g., in the README example for Toasty, explicitly joining on TODOs and mapping them to a simple field on the User objects as opposed to using ORM `has_many`)
> What pain points do you have in the Rust web framework ecosystem? Happy to hear.
I think I have more "gripes" than strong pain-points admittedly. Off the top of my head, complaints about boilerplate to simply access path params and JSON bodies.
Currently using Rocket, but it looks dead and unsupported. It's not perfect, but I like aspects of it, such as the global error handling and relative ease of accessing params.
Probably going to seem nitpicky, but compare these 2:
Why can't name just be String? Why can't `hello` endpoint just indicate clearly what it returns?
carllerche 2 days ago [-]
> Will have to see if Toasty solves it and whether it lets one query for arbitrary structs and add fields to structs from query results (e.g., in the README example for Toasty, explicitly joining on TODOs and mapping them to a simple field on the User objects as opposed to using ORM `has_many`)
I'm not 100% following. Feel free to ping me in discord (https://discord.gg/tokio) or open an issue on Toasty and we can dig into it. Toasty is also pretty new, but maturing fast.
My "arbitrary structs" thing is exactly what Aeltoth was discussing in the Discord a couple days ago.
For the other part, I am basically saying I don't like, if one has a FK from Posts to Users, the ORM semantics of having user.posts automatically eagerly populated OR Deferred. I personally prefer to write SQL DSL in whatever language I am using whenever there is a join and explicitly add gather and add the posts. But I should probably get over that. Most of the time that is more cumbersome and having them eagerly there reliable is usually what I want anyways.
the__alchemist 2 days ago [-]
Likewise. I'm commenting based on my position:
- Rust Fanboy; use it in several domains (embedded, PC applications, bio/chem)
- Web dev is the main thing I still use Python for, as there's nothing on Django's level.
Of interest: I am not a fan of Async in rust. I get that for web stuff it is a suitable model, but I still don't like it for no original reasons. As you stated, I don't feel like this is solving the missing aspects, e.g. auto migrations, admin, email, auth, etc.
m4tx 6 hours ago [-]
Shameless plug: the lack of a fully batteries-included framework (with DB, auto migrations, admin, etc.) is one my biggest gripes in Rust - and that's why I've been developing https://cot.rs/ for a while.
One thing to keep in mind, the main reason for Topcoat to exist is that many organizations are already using Rust for infrastructure-level or performance sensitive reasons and often just want to build a web app using the programming language they already use.
This would take a long time to get feature complete with the core of those big full stack frameworks, but I'm rooting for it! Getting to use the Rust type system with a full stack web framework sounds incredible.
There already is an ORM (https://github.com/tokio-rs/toasty/). You can see a sketch of the roadmap here: https://github.com/tokio-rs/topcoat/issues/104
A decade? More like 21 years
Unfortunately, you end up bound to Python’s poor performance and poor typing stories, which Rust solves in spades.
jinja2rs::filters : https://github.com/westurner/dsport/blob/main/src/jinja2rs/s...
jinja2rs::filters::django : https://github.com/westurner/dsport/blob/main/src/jinja2rs/s...
Which Rust components are like the Django ORM and django.contrib.admin and DRF/FastAPI; with convention over configuration and tests and great docs?
dj-bolt/django-bolt: Rust-powered API framework for Django achieving 60k+ RPS. Uses Actix Web for HTTP, PyO3 for Python bridging, msgspec for serialization. Decorator-based routing with built-in auth and middleware. https://github.com/dj-bolt/django-bolt :
> Faster than FastAPI, but with Django ORM, Django Admin, and Django packages. [...] Django-Bolt is a high-performance API framework for Django, providing Rust-powered API endpoints capable of 188k+ RPS.
I don't use it personally because I don't like the look of SeaORM
htmx+ tailwindcss is the one combo that is right and I use it so seeing is the direction give me hope.
Some notes, I hope can be considered!:
- The main thing is the auto admin, then `auth`, is great that the `auth` is mean to have a one-to-one connection for your own extensions
- The main pain is that everything is tangled to the ORM and the auto-admin
What I have done informally is that with traits I have something like `ListQuery` and compose `Paginate(ListQuery)`.
Then pure descriptors of what the ui DO, but not what it looks like and not even html at all.
THEN, I inject the stucts/enums (all Ui is things like `Label{...}` with not logic at all in templating, all the server side is in charge of pre-render) into some templating and there is where the ui is alive, but replacing is 100% doable and expected.
What I miss is a way to introspect to auto-generate things more auto.
I don't think an ORM is necessary, but I do think you need to say what people are meant to do instead and how your batteries are included without it, if you're going that direction.
I'm not sure that projects like Topcoat and something like their ORM is a great direction for the project, and worry that they will possibly gain outsized adoption in the community based on name recognition rather than merit.
It is early, a lot is coming, but you can already build good stuff now.
Re: OpenAPi you want to consume or provide an OpenAPI endpoint? I’m assuming you want to provide one. This is probably on the medium term roadmap after other stuff like UI, tighter ORM integration, email, etc…
When I see syntax like $(...), it looks like a transpiler that embeds Rust AST inside JS. I think it would make Rust's already terrible developer experience even worse. I think the actual value of the string length on the server side will differ, specifically `len()`.
And I'm not sure if bundling binaries and assets this way is the right approach. This feels less like Rust and more like a DSL that intersects Rust and JS. it feels like something different.
I like Tokio and think it's really well made, but this framework seems a bit wrong to me.
That said, if you are up to it, I would ask that you try using it and provide your thoughts after using it as an issue. Feedback is appreciated.
I'll try it out next time and give feedback later. And you're right, it's just a difference of opinion.
Also, for the API side, Unicode strings are usually 4 kinds right? I think using Rust-style snake_case, we might need separate functions like len(), utf16_len(), and so on. But I'm not sure how to handle the abstraction between libraries and browsers.
Sorry for being critical. I'm not that good of a programmer, so it might be a mistaken observation. Please check it.
What pain points do you have in the Rust web framework ecosystem? Happy to hear.
> What pain points do you have in the Rust web framework ecosystem? Happy to hear.
I think I have more "gripes" than strong pain-points admittedly. Off the top of my head, complaints about boilerplate to simply access path params and JSON bodies.
Currently using Rocket, but it looks dead and unsupported. It's not perfect, but I like aspects of it, such as the global error handling and relative ease of accessing params.
Probably going to seem nitpicky, but compare these 2:
Rocket ``` #[get("/chat/threads/<thread_id>")] async fn get_thread(thread_id: Uuid) -> Result<Json<ThreadResponse>, AppError> ```
Actix ``` #[get("/{name}")] async fn hello(name: web::Path<String>) -> impl Responder ```
Why can't name just be String? Why can't `hello` endpoint just indicate clearly what it returns?
I'm not 100% following. Feel free to ping me in discord (https://discord.gg/tokio) or open an issue on Toasty and we can dig into it. Toasty is also pretty new, but maturing fast.
The other points are valid. There are challenges with extracting params and a type system. This is how topcoat does it: https://docs.rs/topcoat/latest/topcoat/router/attr.path_para...
For the other part, I am basically saying I don't like, if one has a FK from Posts to Users, the ORM semantics of having user.posts automatically eagerly populated OR Deferred. I personally prefer to write SQL DSL in whatever language I am using whenever there is a join and explicitly add gather and add the posts. But I should probably get over that. Most of the time that is more cumbersome and having them eagerly there reliable is usually what I want anyways.
Better to ship early and hear what people want though :)
Rust in general