loco
loco copied to clipboard
Develop an approach for frontend/UI
Currently Loco offers html output as a starting point for UI. We have decided to not decide about frontend, so that we can focus the thinking on it separately, and now have come the time to start thinking about frontend :)
Principles:
- There are too many frontend frameworks. If we pick one we want the most productive one.
- We want to prioritize Rust-based framework, but not to make it a crusade to use Rust at all costs at the expense of productivity
- There can be some tricks to be had, such as "hotwiring" Rails' Turbo infrastructure to gain frontend "for free", which depends on the ability of Turbo to work outside of Rails and without Rails
- If we pick a JS framework and ecosystem -- we must pick something that would be very minimal overhead of tooling and installations. Examples for minimalisms: (1) use bun (2) use tailwind, which will prevent a lot of js libs from being installed (3) defer choosing a state framework for react (4) be very mindful of libraries, dont install anything thats not bare essentials (5) build a very minimal frontend starter/scaffold
Insights
- Dioxus looks like a leading Rust-based frontend and the biggest advantage is to stay in Rust and not have any toolchain or js libs involved. Not completely convinced productivity is higher than a React based project. There is a certain advantage of sharing Rust structs for data objects, or some Rust validation logic. The biggest disadvantage is if we choose it, we risk including a very small subset of Rust developers that are actually willing to do frontend in Rust
- React is React
- Yew, leptos look like a runner ups to Dioxus, and aren't providing more benefits (to my knowledge)
- Tailwind will be great here. And is a must. We cannot afford Chakra, or other likeminded libs, because they're too big and carry too many js libs
Output of this task Answer the questions:
- If Loco provides UI, will it be Rust or js based? Is it possible that we won't provide a UI at all?
- How can you make use of the auth feature more easily (provide forms and UI), like Rails' devise
- What kind of starting (starter template) will we offer to make people more productive in this regard?
- If possible gather feedback from other people of what they would expect (keep the audience wide, e.g. no bias for Rust-based frontend)
(Came here from your Reddit post.)
"Productivity" is probably the most subjective possible metric here. The range of answers you've already either proposed gotten on Reddit is so wide as to cover the full spectrum of things that could possibly run in a web browser, from slint (doesn't even use HTML/DOM but renders into a canvas) to Hotwire (doesn't do any frontend but diffs new HTML from the server). Maybe this reflects the fact that people are the most productive in the tool with which they're most familiar.
That said, a few technical points:
- If you're going for broadest possible appeal, "choose a frontend framework" means React, but...
- Running a Rust server is already excluding JS server-side rendering, so choosing a JS framework you would likely end up with two separate approaches, one for HTML templating in Rust (i.e., something that allows you to return HTML from views easily) and one for client-side interactivity.
- This is essentially reinventing the "two-app" problems of the 2000s-2010s and is the reason every framework has moved into its own server-side rendering
- React in particular is pushing React Server Components as the default future for React, although the community doesn't universally share the React team's vision here
- Most modern JS frameworks include pretty significant build/bundling steps that you'd need to run alongside your Rust build process.
- Exceptions include something like Lit (no JS build step required), as well as Vue in its "just add me to HTML mode" (very popular in Laravel world); alternatives like Alpine or HTMX that are designed to "just work" with HTML fall into the same category
- Choosing a Rust frontend library or framework allows you to share types and logic between the server and client much more easily, at the expense of increased build times (compiling for both server and WASM) and smaller audience, as you note
- You may want to consider a library that includes the possibility of creating small "islands" of interactivity within a larger "ocean" of inert HTML. (Leptos is the only Rust option that supports this to the best of my knowledge, as well as a few other features like streaming HTML rendering that may or may not be useful to you.)
Given all that, personally, I'd very strongly recommend you choose a Rust HTML templating approach that you like, and make it obvious to people how to return HTML in a blessed way. (I don't see this at the moment in examples or docs but will admit I haven't read them thoroughly.) You could build "and here's how to have a React frontend that only supports half of React's features and adds a bunch of additional complexity and build tooling" but if someone wants a full-featured framework using React they're just going to go for NextJS anyway...
Thanks @gbj this is what I'm taking from your thinking:
- +1 for Rust as frontend, supporting it means: "show the world how to share types between Loco and frontend, and the build story should be simple using the same tooling", owning that approach
- Give people an option to integrate React if they would like to, but do not own that approach. For example add static file serving, and offer some snippets to configure webpack, vite, to use Loco as a server. Also show people how to deploy their Loco server as well as bundled assets.
Here are a few thoughts in addition to @gbj's great comment
-
Loco is and will try to be opinionated, which is the appeal. However choosing a frontend framework / style / approach is effectively taking a dependency out on that technology. Whether it be JavaScript, Rust (Dioxus, Leptops, Yew, etc.), or templating.
-
A follow up question is: how often will that dependency 'churn'? How many major versions will Loco have to keep up with? How reliable and performant are the build systems surrounding those tools? E.g. Most JS build tools outside bun.sh and maybe esbuild are going to be slow. Plus the JavaScript ecosystem can quickly lead to heavy weight applications.
-
Assuming anyone can use Loco to build JSON APIs and then build their own separate Single Page Application at any time, it would make the most sense to me to have Loco be opinionated about HTML templating and have guides, examples, support for building and serving SPA bundles which are framework agnostic. Effectively an escape hatch. Ruby on Rails, Phoenix, Django, and every other opinionated web framework support this.
-
Back to basics, if Loco is going to be the single developer company framework for Rust, simple, effective, and performant are likely top of the list. I think HTML templating or something optionally interactive like HTMX are good choices.
It's worth mentioning that I am an admirer of Leptos and think it's excellent, great work @gbj. If I were using Loco myself for a personal / side project I would choose Leptos to continue working in Rust, reduce my language switching, and share code and types. In SaaS or general business environment, templating is safe and predictable.
That's my two cents, I'd love to see the other pieces of feedback from the community focused on tradeoffs and expectations for opinionated web frameworks.
Allowing users to pick either React or a Rust based frontend framework at the same time seems like the most inclusive option. I know that this would increase the complexity which goes against the idea of minimalism, however react ecosystem is mature, well supported in many ways. In my opinion, this approach would probably catch attention of more developers. As @jondot said,
"including a very small subset of Rust developers that are actually willing to do frontend in Rust"
could be a mistake moving forward. At the moment, attracting more developers seems like the better decision.
I started thinking that React was the obvious choice for this, but after reading a lot of the comments about the complexity it would add I think I would like to see htmx as the de facto template and a rust frontend for type sharing if needed. It would be nice to be able to go either way on this depending on page complexity.
If the user really wants to use react I'm sure that you would use loco as an api with your front/full stack of choice.
I'm distilling some more of the feedback:
- htmx - seems many people refer to it. I've since look at it, and it reminds me of what used to be pjax in Rails, and now the Turbo family of libs. This means betting on html templating, which we can spice up a bit (we already have some initial support).
- leptos - I put more of my time to look at dioxus but seems there is a lot of love for leptos. I should look at it again
- js/react ecosystem - I get stronger vibes to stay away and not "own" this decision as something that's prescribed by Loco. what I'm taking from this is we should have an example for how to set up Loco for a React/SPA based project and leave it at that.
if you decide to support htmx and have templates, consider supporting template fragments w/ whatever your templating solution is:
https://htmx.org/essays/template-fragments/
this makes it much less annoying to decompose a view into dynamically updated bits by avoiding template file blowout.
also suggest supporting both a hypermedia API & a JSON API on different end points easily:
https://htmx.org/essays/splitting-your-apis/
https://htmx.org/essays/hypermedia-apis-vs-data-apis/
Are there any big "in the wild" uses of htmx?
hgtv/food network is starting to use it: https://www.foodnetwork.com/holidays-and-parties/photos/top-holiday-cookies
some others:
https://www.nikevision.com/
https://light.berkeley.edu/nobels/
mistral is using it: https://jobs.lever.co/mistral/586bc657-f593-4a1e-90c6-06ca3838d5a5
there's a webring here:
https://htmx.org/webring
but it's not backed by any of the big tech companies. I know one FAANG that is using it for internal tools, but can't say which.
Thanks!
Some more community updates from Loco:
- Meanwhile we've built a way to serve static asset bundle
- You can now build docker images which detect your bundles and package those into the docker image (using
cargo loco generate deployment
) - I'm getting a stronger vibes for htmx, having that it is most similar to Rails' Turbo and will only require templates support. It still needs to be tested for ergonomics vs Leptos (full Rust frontend)
Edit:
- One more conclusion is that whatever will be chosen will have to appear on
cargo loco generate scaffold
, as in a full scaffold for interacting with entities. For example, if htmx is chosen then we'll also have a basic CRUD UI using it. This resolves the meaning of "supporting frontend" in Loco.
some other alternatives if you want a hypermedia-based front end lib out of the box:
- Turbo (obviously) - https://turbo.hotwired.dev/ (supported by a larger, richer company)
- Unpoly - https://unpoly.com/ (better at progressive enhancement, if that's a goal)
we also have a book (free online) if you want some background philosophy on the hypermedia approach (esp. the first two chapters):
https://hypermedia.systems
and we have a #rust-htmx channel on our discord if you want to talk to rust users who have worked w/ htmx. Obviously severe selection bias, but maybe useful for practical experiences:
https://htmx.org/discord
We created an example of how to serve/develop a front-end app with Loco. Blog Repository
It will be greate to get your feedback.
I would vote for starting with htmx. I could be wrong but most of the folks who will adopt Loco will be mostly backend developers trying to build a full-stack app or SaaS so making frontend development easier will be really helpful. Rails is pushing for that as well with hotwire and even plain old CSS
Hi, Just started to learn Rust but come with some Ruby on Rails knowledge... My two cents, for quick prototyping / solo framework my go to preference are frameworks that have HTML templating, it is good enough for my hobby or personal projects. Even if it means to reload the full page on each request. Not writing a client application is worth the overhead of full reload.
This is only a problem when building customer facing application because the current UX expectations from the users, and normally a rich UI + API will be the way to go. And this is already supported (API side)
Maybe Look into Slint UI. It's a language (kinda) for creating ui for Slint apps. The UI written in Slint supports adding logic in rust or any other language and it gets compiled natively to system. It's syntax approach is almost like flutter, hence it would also improve productivity. Though people have to learn a new tool, it's pretty easy to learn.
For Leptos, I think it's better to contribute to their end since they have templating mechanism for each web framework (currently actix and axum).
So, Loco can just focus providing the backend and let Leptos handle the frontend matters.
That should be much flexible.
References:
- https://github.com/leptos-rs/start-axum
- https://github.com/leptos-rs/start
Hi, Just started to learn Rust but come with some Ruby on Rails knowledge... My two cents, for quick prototyping / solo framework my go to preference are frameworks that have HTML templating, it is good enough for my hobby or personal projects. Even if it means to reload the full page on each request. Not writing a client application is worth the overhead of full reload.
This is only a problem when building customer facing application because the current UX expectations from the users, and normally a rich UI + API will be the way to go. And this is already supported (API side)
I agree here, found loco by searching "rails for rust". I was looking specifically for something that would allow me to iterate fast without fussing too much about the UI stack. Almost expected the project to use something like https://github.com/Keats/tera for the templating out of the box.
The whole alure for me is the speed and productivity gains that can be had. Think Rails for Ruby or Phoenix for Elixir.
Server side rendered templates feels like the only missing big piece from "Rust on Rails".
hey @stefan-vatov, we are going to release server side rendering next week
I don't want to just leave a +1 but loco supporting templating/htmx is literally the only reason I will go back to doing frontend development after 10 years of avoiding it like the plague because of the javascript hell it turned into.
Really looking forward to this.
+1 for templating support to be able to use htmx
If you want to see how server side rendering will look like it is in master here: https://github.com/loco-rs/loco/commit/f6fae06fe52dd60eec825e7ec625f6f62ef819f5
Very exciting! With your framework, rust has reached a new level of versatility. Keep up the good work
The version was released 0.3.1
Views are now out! https://loco.rs/docs/the-app/views/
It should cover all bases. Anyone who wants to experiment with HTMX is now welcome. This should enable using HTMX more easily.
This iteration looks fantastic. Great work, everybody.
I want to share some thoughts as a polyglot engineer that's having a difficult time finding satisfaction in any ecosystem.
Places that I see view logic being done elegantly:
- convention-based - the only code I need to render something from a path is a file in a location following a naming convention
- obvious drawbacks that come from conventions is that those are strongly enforced opinions that may require additional work arounds
- island architecture (as @gbj mentioned)
- on the server, this is lovely, as this means that when I'm using
htmx
or something of the like, I can directly depend on the services that are going to be useful to me - no controller glue required(I'll save that overhead for my json apis) - the ability to gain the value of streaming individual components is relatively "low effort" considering the value that is received from it
- worth noting-
htmx
and it's siblings offer a similar user experience with "onLoad"-based triggers
- worth noting-
- additional benefit comes from the lack of "prop drilling" that I have to do- if I'm using islands, then state tends to be easier to access closer to the template that's rendering it
- on the server, this is lovely, as this means that when I'm using
- type-safe routing allows me to treat my routes like first-class citizens in my type system... if they're going to be state, it would be nice if I could type it
- form validation enhancements - similar to type-safe routing- I love it when a framework saves me the trouble of interacting with
FormData
directly - "client"(or, apparent) interactivity - I feel as though every well-architected front-end eventually looks similar to the elm architecture... may as well start there :shrug:
astro's pages
remix routes
blazor's route templates
tanstack router - typesafe routing
Things that I see lacking in some/all places:
- over-abstraction (blazor) - it's fairly trivial to maintain the type of the element that's been abstracted over in the JS ecosystem UI engines. Blazor has patterns that support it, but it's highly coupled to blazor conventions that I'd like to not have to learn if I'm only there for having type-safe htmx templates.
- IDE support - unless there's a good reason (other + big ecosystem) benefits, I'm not going to touch a template engine unless it has an
lsp
(makesmaud
actually feel like a better solution than others in the rust ecosystem) - testability - I think this one is just generally difficult to accomplish
It looks like Loco
is very much headed in the right direction. Don't stop!
htmx is a good choice, and if it can be like templ, there can be
- It's like writing rust/go
- A freer, more modular combination of