Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop an approach for frontend/UI #130

Closed
jondot opened this issue Dec 12, 2023 · 32 comments
Closed

Develop an approach for frontend/UI #130

jondot opened this issue Dec 12, 2023 · 32 comments
Labels
enhancement New feature or request

Comments

@jondot
Copy link
Contributor

jondot commented Dec 12, 2023

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:

  1. If Loco provides UI, will it be Rust or js based? Is it possible that we won't provide a UI at all?
  2. How can you make use of the auth feature more easily (provide forms and UI), like Rails' devise
  3. What kind of starting (starter template) will we offer to make people more productive in this regard?
  4. If possible gather feedback from other people of what they would expect (keep the audience wide, e.g. no bias for Rust-based frontend)
@jondot jondot added the enhancement New feature or request label Dec 12, 2023
@jondot jondot added this to the 0.1.7 milestone Dec 12, 2023
@gbj
Copy link

gbj commented Dec 12, 2023

(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...

@jondot
Copy link
Contributor Author

jondot commented Dec 12, 2023

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.

@jryio
Copy link

jryio commented Dec 12, 2023

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.

@suleymanozkeskin
Copy link

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.

@AvidDabbler
Copy link

AvidDabbler commented Dec 12, 2023

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.

@jondot
Copy link
Contributor Author

jondot commented Dec 13, 2023

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.

@1cg
Copy link

1cg commented Dec 13, 2023

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.

@1cg
Copy link

1cg commented Dec 13, 2023

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/

@jondot
Copy link
Contributor Author

jondot commented Dec 13, 2023

Are there any big "in the wild" uses of htmx?

@1cg
Copy link

1cg commented Dec 13, 2023

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.

@jondot
Copy link
Contributor Author

jondot commented Dec 14, 2023

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.

@1cg
Copy link

1cg commented Dec 14, 2023

some other alternatives if you want a hypermedia-based front end lib out of the box:

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

@jondot jondot modified the milestones: 0.1.7, 0.1.8 Dec 17, 2023
@kaplanelad kaplanelad pinned this issue Dec 18, 2023
@kaplanelad
Copy link
Contributor

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.

@kaplanelad kaplanelad removed this from the 0.1.8 milestone Dec 18, 2023
@narup
Copy link

narup commented Dec 30, 2023

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

@HatsuMora
Copy link

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)

@brohithkr
Copy link

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.

@jondot jondot unpinned this issue Jan 14, 2024
@sidoki
Copy link

sidoki commented Jan 17, 2024

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:

@stefan-vatov
Copy link

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".

@kaplanelad
Copy link
Contributor

hey @stefan-vatov,
we are going to release server side rendering next week

@thebl1985
Copy link

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.

@rubiktubik
Copy link

+1 for templating support to be able to use htmx

@jondot
Copy link
Contributor Author

jondot commented Feb 4, 2024

If you want to see how server side rendering will look like it is in master here: f6fae06

@rubiktubik
Copy link

Very exciting! With your framework, rust has reached a new level of versatility. Keep up the good work

@kaplanelad
Copy link
Contributor

The version was released 0.3.1

@jondot
Copy link
Contributor Author

jondot commented Feb 8, 2024

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.

@em-jones
Copy link

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
    • 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
  • 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 🤷

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 (makes maud 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!

@laojianzi
Copy link

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

@seivan
Copy link

seivan commented Aug 16, 2024

The best approach is one where the front-end is written in something that's somewhat native to the front-end but still allows for static typing.
Something like TypeScript and since it's for the web, it's going to have better interop with the ecosystem of libraries for the web. One of the biggest mistakes Phoenix (Elixir) did was to go their own way and its eco system is minuscule and spread thing compared to TypeScript.

@HiImJulien
Copy link

I hope this doesn't come across as a shameless plug, however I might have a solution for the remark by @jondot :

  • 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.

I've created a small library called in-vite today. Which allows you to integrate Vite bundle's into your Rust backend (both during development and production). It even implements the necessary traits to use it with Tera templates:

<!DOCTYPE html>
<html>
  <head>
    {{ vite(resources=["./src/app.ts"]) }}
  </head>
</html>

The function vite() then generates the appropriate <script>- and <link>-tags required to load your bundle and chunks.

A small bare-bones example with for Axum & Tera using Tailwind, AlpineJS and Typescript via Vite can be found here.

Note, that this is my first public Rust library and thus might be a bit rough around the edges. Your feedback is welcome.

@chrisabruce
Copy link

Personally, I would like to stick as close to Ruby on Rails as possible. I really like the direction of Ruby on Rails version 8. Things like Hotwire, frames, etc mean you don't need to have heavy front end framework. I like this. I feel the direction of frontend architectures are going very complex with SSR and Hydration, etc. If you watch the Ruby on Rails 8 keynote, think you can see a much better approach, especially when we consider "one man" projects.

DHH Ruby on Rails 8 Keynote - YoutTube

@Keats
Copy link

Keats commented Nov 5, 2024

Hey there. I feel like this would be a pretty good place to find people using Tera and potentially htmx together ;)

I'd like to make it easier do complex templates in the next version of Tera as well as making it easier to integrate with htmx/livewire-like things with more targeted re-renders (block/component level). In practice this means adding the concept of components to Tera (similar to React/Vue/Solid etc) to replace macros (which are almost the same thing). The goal being to make a template engine where making complex UI feels as easy as React/JSX.

If that sounds interesting, I would love some feedback on Keats/tera2#51 (and any other Tera feature request tbh, this is the right repo to ask)

@rubiktubik
Copy link

@Keats
I think this would be awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests