The Rust ecosystem needs more high-level frameworks like this. However, I've been shipping Django since 0.96, and I don't think Cot really addresses the main issues Django currently has. Performance isn't in the top 5.
Django's biggest issue is their aging templating system. The `block`, `extend` and `include` style of composition is so limited when compared to the expressiveness of JSX. There are many libraries that try to solve Django's lack of composition/components, but it's all a band-aid. Today, making a relatively complex page with reusable components is fragile and verbose.
The second-biggest issue is lack of front end integration. Even just a blessed way of generating an OpenAPI file from models would go a long way. Django Ninja is a great peek at what that could look like. However, new JS frameworks go so much further.
The other big issue Django has _is_ solved by Cot (or Rust), which is cool (but not highlighted): complicated deployments. Shipping a bunch of Python files is painful. Also, Python's threading model means you really have to have Gunicorn (and usually Nginx) in front. Cot could have all that compiled into one binary.
About performance: I agree, and I'm not even trying to make performance a priority in Cot. I mean, of course, it's nice to have an actual compiled language, but I think a bigger perk in using Rust is having *a lot* of stuff checked in compile time, rather than in runtime. This is something I'm trying to make the main perk of, and it is reflected in multiple parts in Cot (templates checked at compile time, ORM that is fully aware of database schema at compile time, among many others).
About JSX: I think that's the one I'll need to explore further. In my defense, the templating system Cot currently uses (Rinja) is much more expressive and pleasant to use than Django's, but admittedly, the core concepts are very similar. This one might be difficult to address because of an ecosystem of templating engines that is pretty lacking in Rust, but I'll see what I can do to help this.
About front-end integration: that's something that will be (at least partially) addressed no later than v0.2. Django REST Framework is a pain (mostly because it's never been integrated in Django), Django Ninja is something I haven't personally used very much - good to have it mentioned so it can be a source of inspiration. Generating OpenAPI docs is something that's even mentioned in the article "Request Handler API is far from being ergonomic and there’s no automatic OpenAPI docs generation" so yeah, I'm aware of this.
Deployment is indeed something that's super nice – and a part of this is that newer Rust versions generally don't break compatibility with existing code, unlike Python. I agree this should be highlighted, thanks for suggestion!
The post mentions an ORM, but the docs don’t provide any examples of how it works. How does the Cot ORM compare to Diesel?
There are certainly places where I find Diesel falls short of, say, ActiveRecord (like traversing relationships via “includes”/“eager_load”/etc.). I’m not convinced that these shortcomings warrant a separate ORM as opposed to making contributions to Diesel, but I’m open to being wrong. Are there any particular shortcomings that motivated starting from scratch?
One thing I really like about Rust dev is the way ORM and API server concerns are separated. Will Cot’s server support using Diesel? Can it be used without the ORM package being involved at all?
There are several reasons I don't like the existing ORMs in Rust, many of them being overly verbose, some generating unnecessary files, and having somewhat weird DSLs being the main reasons. The main reason, I think, was that none of them supports automatically generated migrations, and I absolutely loved that feature in Django. The differences between existing ORMs sound like a neat idea for another blog post, to be honest, so I'll probably do that soon!
Diesel absolutely can be used, there is no reason it can't - database support is feature flag-gated, so disabling it as as easy as adding one line in your Cargo.toml file. This, however, will obviously also disable some other features that depend on the database, such as authentication through database.
Whether building a custom ORM will be a good idea - only time will tell.
I think Django's marketing for perfectionists with deadlines is a bit better than "for lazy developers" :) but excited to see people build "Django, but compiled"
I'm currently using Rocket, Maud, Rusqlite, and Serde for the first time on a project. I'd like to offer my perspectives as someone new to this space.
Rocket routes work pretty well. I like being able to derive FromForm and have it reliably work, including nullable Option fields.
Maud is just wonderful. It's going to be hard to go back to plain HTML after getting the same logic in such cleaner syntax.
I haven't quite figured out authentication yet. Rocket has some functionality, but I might punt this up to Nginx (I'm using Nginx to proxy to Rocket). I'd like for cookies to be a little easier.
Rusqlite has not been fun. I couldn't get Rocket to compile with Rusqlite integration, so I've been manually opening the database for each request. (This is a very, very small site that I'm working on, and web dev is not my main role.) Anyways, all my queries are so verbose and have tons of seemingly-unnecessary Ok() statements and ? syntax. It's nice to map_err to Rocket's HTTP error types, although I'd like a less verbose version. Right now it feels like writing Java with long boilerplates that I'm copying for each route.
If Django works for you, I'm absolutely not saying you should switch to Cot immediately! Some people like to have as many type-safety and compile-time checks as possible, so that's the crowd we're trying to satisfy.
That's actually a very good point. I was thinking a lot about whether to make async a requirement. Given that sync code is often easier to reason about and debug and Cot tries to be developer-friendly, I'm leaning towards "sync by default, async when you need to", but I'll need to explore this more. Thanks for this thought!
This is exactly what I'm looking for. Rust is my favorite languages in many domains; I use Python and Django for web backends due to the immature rust ecosystem there. I am not a fan of Async for various reasons, so: Batteries-included web backend + rust + not-Async would be amazing!
I just had an issue yesterday in my company where a backend keeps crashing, because a function blocking the main thread, which means that the healthcheck endpoint was not responding... Async is definitely a needs
Anything that has Oauth2 integration with Github, Google, Facebook, etc. out of the box is going to win this by a country mile. That's by far the most annoying thing about setting up any website that has user accounts in my experience.
I understand people use these logins, but I'm not trusting a third-party login to gate access to anything I might miss. It's already annoying enough that there are virtually no access guarantees for a service, but to add a second point of failure is a risk I'm not going to take if I have any fear of losing access. For something like TikTok where I can download the recipe videos the risk is appropriately low, but that's the only place I can think of off the top of my head where I actually use a login provider.
Plus, it offers very little convenience for users vs just using a password manager. I realize figuring out the right bcrypt/datastore setup is kind of annoying, not to mention opening you up to liability, but it's always been worth it to me in the past.
What's funny is its obviously in early stages, but its homepage doesn't show an immediate code sample. I find it funny because you are trying to appeal to lazy devs but making them work to get to any code samples.
The golden rule for making a website / readme for any programming language, web framework (or even GUI frameworks) is to have at least one or more code samples, so people can see what coding in your framework looks like.
I'll excuse it since it's a newish project it seems. :)
On that note, I'll be keeping a close eye on this one. This is the kind of web framework I look for, batteries included.
> The ORM is very lacking at the moment and the automatic migration generator only works with a small subset of possible operations,
I would have hoped that by 2025, new projects would have moved away from ORMs entirely. They really are a useless abstraction layer that always brings tons of trouble and usually makes queries harder to write.
Composability is the often cited benefit. As an example, I can do the following in Active Record (Ruby):
class Account < ApplicationRecord
scope :active, -> { where.not(active_at: nil) }
belongs_to :user
end
class User < ApplicationRecord
scope :born_before, ->(born_on) { where(birthdate: born_on) }
end
active_users_with_birthdays_today = Account.active.joins(:user).merge(User.born_before(Date.today))
Contrived, of course, but it's not hard to see how you can use these sorts of things to build up record sorting, filtering, etc. Doing this by hand wouldn't be very fun.
Writing raw SQL is perhaps indeed easier for simple queries, but put some foreign keys inside or slightly more complex relationships between tables and you'll probably quickly fall into the trap of having to remember your entire database schema to write anything. Yes, the example from the documentation is slightly more complicated, but it checks at compile time the exact column names and types, so you get feedback much quicker than actually running the SQL query.
In addition to that, over the years of writing web services, I always found raw queries much less maintainable. The ORM immediately tells you that you messed up your refactoring, whether it is just renaming a column, or removing a table completely.
Pretty much every ORM (including the one in Cot) also allows you to write your own custom queries if the abstractions are not enough, so there's always this fallback option.
I've yet to see an ORM which doesn't just eventually make everything harder. Especially when it comes to automatic migrations, which seldom seem to take into account production necessities like multi-node deployment, downtime considerations and not destroying your production data silently because it doesn't fit.
It's 2025, and some ORMs are quite good (eg. Django, ActiveRecord). You can have an ORM with escape hatch of SQL. I do not understand the people who are so against ORMs.
I use ORM query interfaces 80% of the time, and for performance critical queries I can use direct SQL. But the query sanitization, smart preloading and performance checks, schema management and migration tools they often provide, and type checks / hints are really nice features of ORMs.
Furthermore, ORMs are ESPECIALLY useful in teams where you have more junior devs who need these guardrails.
I think the issue here is trying to reinvent a new ORM.
As long as it's still possible to also use SQL queries with it it's fine, right? I know some people who prefer using ORMs and some who like writing SQL.
ORMs, in my experience, fail the hardest when DB admins and web devs butt heads in when and where to create models. It can be an extra hurdle for data flexibility, but it clarifies data architecture at the beginning. In our Django environment, the DB admins won and we added `MIGRATE = False`.
ORMs are great. They afford abundant opportunities to look like a hero by swooping into a project and cutting a page load of forty seconds to under one second.
Frameworks that do “everything” are not a good idea. I’m from the Java ecosystem. Spring is the “batteries included” framework there. If you have migrated any real world application to a new major version once, you’ve learned forever that “all in one” frameworks are bad. Please don’t do it!
Instead, use scaffolding tools, that give you a head start on creating a new project, using smaller, specialized libs.
Also, don’t use an ORM. Just write that SQL. Your future self will be thankful.
> Also, don’t use an ORM. Just write that SQL. Your future self will be thankful.
I have never understood this. I've been using the ORM for twenty years now, it's saved me countless hours, and I've very rarely needed to break out of it. When I did, I just wrote an SQL query, and that was it. What's the big deal?
Every one of the three points you made in your comment has been disapproved by Django.
It's a framework that does (or at least tries) to do everything (or as much as possible), and it's good. Really, really good.
I'm in the process of upgrading an app of mine after months of abandonment, and the process is so smooth it's boring.
Also, Django's ORM is the closest thing to a perfect tool. Sure, it has some dark corners here and there, but Django's ORM has considerably improved my quality of life as a programmer. Heck, I even moved from SQLite to PostgreSQL in an old project, and all I needed to do is to change a couple of config code.
Oh, and Django is both stable and enjoys a constant pace of updates adding useful features practically at every major version.
Github copilot is so good at writing CRUD db queries that it feels as easy as an ORM, but without the baggage, complexity, and the n+1 performance issues.
What is the competitive landscape looking like these days for Rust web frameworks? I couldn't help but feel a bit insecure last time I was exploring the various options because none of them seemed to have the maturity or longevity of frameworks from other languages (for obvious reasons).
Is there one framework that stands out from the rest from an "investment risk" perspective? In other words, if my company is going to choose a framework to build a website, which one has the lowest odds of burning me by becoming abandoned or unsupported?
I would say pick Axum or Actix, these are the go to right now with lower risk to be abandoned, But they aren't batteries included. Here is a list of blessed[0] libraries that might help you to choose the most popular ones in their respective category, but at the end depends on you to pick the one that has the biggest community.
Axum is most likely to be supported long term since it has quite a bit of support and is a Tokio project but it's not nearly as batteries included as something like Rails or Django. I doubt any of the current batteries included Rust
web frameworks will last.
Lots of “Rails but for X” projects exist in various states, for various languages, but have failed to gain traction and stand abandoned.
…like, a lot.
I thiiiink, fundamentally, it’s a harder-than-it-looks problem space and if you come out with something that’s rough and broken, it never gains enough critical mass for it to become self sustaining.
What’s the “pitch”? It’s can’t be “Django but for rust but it’s kind of not ready yet”, bluntly.
So it needs to have some outstanding feature or accumulation of features that let it stand out from the other 30 rust web frameworks. Is there something here?
You really need to call out the “why another rust web framework” in more than just terms of ambition, imo.
Yeah, that's something I'm painfully aware of. Part of the reason I'm starting to push hard even though it's not ready yet is to gain as much feedback as early as possible to avoid expensive mistakes in the long run. Is that a mistake – I don't know, we'll see.
The main selling point for now is the admin panel and the custom ORM that handles automatic migration generation. There are a lot of finer differences as well, and I'll add a comparison table soon since that's something I'm (expectedly) getting asked about quite frequently.
Your BodyFactory example isn't even functionally the same as the quoted code snippet. Nowhere is the Body::fixed(rendered) equivalent seen, for example.
That's one of the issues explicitly mentioned in the article ("Request Handler API is far from being ergonomic"). This will get better in the nearest future as it's a major pain point, I'm just thinking of the best API for doing request/responses.
blopker|1 year ago
Django's biggest issue is their aging templating system. The `block`, `extend` and `include` style of composition is so limited when compared to the expressiveness of JSX. There are many libraries that try to solve Django's lack of composition/components, but it's all a band-aid. Today, making a relatively complex page with reusable components is fragile and verbose.
The second-biggest issue is lack of front end integration. Even just a blessed way of generating an OpenAPI file from models would go a long way. Django Ninja is a great peek at what that could look like. However, new JS frameworks go so much further.
The other big issue Django has _is_ solved by Cot (or Rust), which is cool (but not highlighted): complicated deployments. Shipping a bunch of Python files is painful. Also, Python's threading model means you really have to have Gunicorn (and usually Nginx) in front. Cot could have all that compiled into one binary.
m4tx|1 year ago
About performance: I agree, and I'm not even trying to make performance a priority in Cot. I mean, of course, it's nice to have an actual compiled language, but I think a bigger perk in using Rust is having *a lot* of stuff checked in compile time, rather than in runtime. This is something I'm trying to make the main perk of, and it is reflected in multiple parts in Cot (templates checked at compile time, ORM that is fully aware of database schema at compile time, among many others).
About JSX: I think that's the one I'll need to explore further. In my defense, the templating system Cot currently uses (Rinja) is much more expressive and pleasant to use than Django's, but admittedly, the core concepts are very similar. This one might be difficult to address because of an ecosystem of templating engines that is pretty lacking in Rust, but I'll see what I can do to help this.
About front-end integration: that's something that will be (at least partially) addressed no later than v0.2. Django REST Framework is a pain (mostly because it's never been integrated in Django), Django Ninja is something I haven't personally used very much - good to have it mentioned so it can be a source of inspiration. Generating OpenAPI docs is something that's even mentioned in the article "Request Handler API is far from being ergonomic and there’s no automatic OpenAPI docs generation" so yeah, I'm aware of this.
Deployment is indeed something that's super nice – and a part of this is that newer Rust versions generally don't break compatibility with existing code, unlike Python. I agree this should be highlighted, thanks for suggestion!
pseudocomposer|1 year ago
m4tx|1 year ago
There are several reasons I don't like the existing ORMs in Rust, many of them being overly verbose, some generating unnecessary files, and having somewhat weird DSLs being the main reasons. The main reason, I think, was that none of them supports automatically generated migrations, and I absolutely loved that feature in Django. The differences between existing ORMs sound like a neat idea for another blog post, to be honest, so I'll probably do that soon!
Diesel absolutely can be used, there is no reason it can't - database support is feature flag-gated, so disabling it as as easy as adding one line in your Cargo.toml file. This, however, will obviously also disable some other features that depend on the database, such as authentication through database.
Whether building a custom ORM will be a good idea - only time will tell.
winrid|1 year ago
bestouff|1 year ago
aleksjess|1 year ago
7bit|1 year ago
wjholden|1 year ago
Rocket routes work pretty well. I like being able to derive FromForm and have it reliably work, including nullable Option fields.
Maud is just wonderful. It's going to be hard to go back to plain HTML after getting the same logic in such cleaner syntax.
I haven't quite figured out authentication yet. Rocket has some functionality, but I might punt this up to Nginx (I'm using Nginx to proxy to Rocket). I'd like for cookies to be a little easier.
Rusqlite has not been fun. I couldn't get Rocket to compile with Rusqlite integration, so I've been manually opening the database for each request. (This is a very, very small site that I'm working on, and web dev is not my main role.) Anyways, all my queries are so verbose and have tons of seemingly-unnecessary Ok() statements and ? syntax. It's nice to map_err to Rocket's HTTP error types, although I'd like a less verbose version. Right now it feels like writing Java with long boilerplates that I'm copying for each route.
bdaebgi|1 year ago
What about Django?
m4tx|1 year ago
freeone3000|1 year ago
tonyhart7|1 year ago
aside from joke, "I want every good thing about C++ but easiness of high level language" seems the norm
ldng|1 year ago
m4tx|1 year ago
the__alchemist|1 year ago
ygouzerh|1 year ago
brink|1 year ago
pveierland|1 year ago
https://github.com/tuono-labs/tuono
IshKebab|1 year ago
m4tx|1 year ago
TransAtlToonz|1 year ago
Plus, it offers very little convenience for users vs just using a password manager. I realize figuring out the right bcrypt/datastore setup is kind of annoying, not to mention opening you up to liability, but it's always been worth it to me in the past.
tomaszsobota|1 year ago
Also, +1 for
> struct GownoApp;
johnisgood|1 year ago
m4tx|1 year ago
Onavo|1 year ago
milne-dev|1 year ago
m4tx|1 year ago
tonyhart7|1 year ago
I wonder how this par with something like https://loco.rs/
vaylian|1 year ago
> And yes, there’s Loco (which, by the way, has started after the idea for Cot was born), which is a great framework, but [...]
giancarlostoro|1 year ago
The golden rule for making a website / readme for any programming language, web framework (or even GUI frameworks) is to have at least one or more code samples, so people can see what coding in your framework looks like.
I'll excuse it since it's a newish project it seems. :)
On that note, I'll be keeping a close eye on this one. This is the kind of web framework I look for, batteries included.
Cot's homepage:
https://cot.rs/
m4tx|1 year ago
unknown|1 year ago
[deleted]
Eikon|1 year ago
I would have hoped that by 2025, new projects would have moved away from ORMs entirely. They really are a useless abstraction layer that always brings tons of trouble and usually makes queries harder to write.
Looking at the first example in the docs
https://cot.rs/guide/latest/db-models/#retrieving-models
I really don't get the point, and that'll certainly get worse with any somewhat non-trivial query.Why go through all the trouble of reinventing a new DSL when the SQL equivalent would be so much cleaner?
jherdman|1 year ago
m4tx|1 year ago
In addition to that, over the years of writing web services, I always found raw queries much less maintainable. The ORM immediately tells you that you messed up your refactoring, whether it is just renaming a column, or removing a table completely.
Pretty much every ORM (including the one in Cot) also allows you to write your own custom queries if the abstractions are not enough, so there's always this fallback option.
mathw|1 year ago
sergioisidoro|1 year ago
I use ORM query interfaces 80% of the time, and for performance critical queries I can use direct SQL. But the query sanitization, smart preloading and performance checks, schema management and migration tools they often provide, and type checks / hints are really nice features of ORMs.
Furthermore, ORMs are ESPECIALLY useful in teams where you have more junior devs who need these guardrails.
I think the issue here is trying to reinvent a new ORM.
schmorptron|1 year ago
winrid|1 year ago
Also, people like ORMs. Type safety is nice too without having to map manually. Sqlx is also great
csh602|1 year ago
ahmedfromtunis|1 year ago
Using Django's ORM, that would simply be: link=Link.objects.get(slug="cot")
It'd still be very readable and manageable even for complex queries.
alabastervlog|1 year ago
whoomp12342|1 year ago
unknown|1 year ago
[deleted]
bkummel|1 year ago
Instead, use scaffolding tools, that give you a head start on creating a new project, using smaller, specialized libs.
Also, don’t use an ORM. Just write that SQL. Your future self will be thankful.
stavros|1 year ago
I have never understood this. I've been using the ORM for twenty years now, it's saved me countless hours, and I've very rarely needed to break out of it. When I did, I just wrote an SQL query, and that was it. What's the big deal?
ahmedfromtunis|1 year ago
It's a framework that does (or at least tries) to do everything (or as much as possible), and it's good. Really, really good.
I'm in the process of upgrading an app of mine after months of abandonment, and the process is so smooth it's boring.
Also, Django's ORM is the closest thing to a perfect tool. Sure, it has some dark corners here and there, but Django's ORM has considerably improved my quality of life as a programmer. Heck, I even moved from SQLite to PostgreSQL in an old project, and all I needed to do is to change a couple of config code.
Oh, and Django is both stable and enjoys a constant pace of updates adding useful features practically at every major version.
adampwells|1 year ago
Github copilot is so good at writing CRUD db queries that it feels as easy as an ORM, but without the baggage, complexity, and the n+1 performance issues.
tcfhgj|1 year ago
unknown|1 year ago
[deleted]
rocky_raccoon|1 year ago
Is there one framework that stands out from the rest from an "investment risk" perspective? In other words, if my company is going to choose a framework to build a website, which one has the lowest odds of burning me by becoming abandoned or unsupported?
norman784|1 year ago
My go to is Axum + sqlx most of the time.
[0] https://blessed.rs
skldj28d2|1 year ago
unknown|1 year ago
[deleted]
darrenf|1 year ago
m4tx|1 year ago
unknown|1 year ago
[deleted]
noodletheworld|1 year ago
…like, a lot.
I thiiiink, fundamentally, it’s a harder-than-it-looks problem space and if you come out with something that’s rough and broken, it never gains enough critical mass for it to become self sustaining.
What’s the “pitch”? It’s can’t be “Django but for rust but it’s kind of not ready yet”, bluntly.
So it needs to have some outstanding feature or accumulation of features that let it stand out from the other 30 rust web frameworks. Is there something here?
You really need to call out the “why another rust web framework” in more than just terms of ambition, imo.
m4tx|1 year ago
The main selling point for now is the admin panel and the custom ORM that handles automatic migration generation. There are a lot of finer differences as well, and I'll add a comparison table soon since that's something I'm (expectedly) getting asked about quite frequently.
unknown|1 year ago
[deleted]
datadeft|1 year ago
[deleted]
unknown|1 year ago
[deleted]
singularity2001|1 year ago
no thank you. if you like it good for you, for me this looks worse than
Body body = BodyFactory.newInstance(BodyConfiguration.OK)
which is still SHORTHER and less cancer
orangeboats|1 year ago
m4tx|1 year ago