Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I've been looking at Remix a bit recently and it looks really cool, but the part I'm not too fond of is having to use Node on the backend. I moved to writing all of my backends in Go after I was burned by the whole ESM/CJS/TS disaster. But there doesn't seem to be any true way to get reliable/feature full SSR with a backend that is not javascript based.

I do see that has has a BFF mode, but I can't really find any instances of many people using it, or at least writing about it. Does anyone have experience with BFF mode?

I think I may just stick with React + Tanstack router + Tanstack query + zustand for now and try the BFF model eventually?



React is a JS library, so it needs a JS runtime to execute outside the browser.

It's hypothetically possible to use a JS runtime as a subprocess from another language to use React for plain HTML SSR, but it probably wouldn't work for React's streaming HTML generation (or at least would likely be very difficult to get working).


SPA mode (what I assume you mean by BFF mode) is brand new, so almost nobody has used it. However, a close example would be the Oxide web console, which we build as an SPA because we want to serve it as static assets from a Rust backend. It's very close to your suggested stack: React + React Router + Tanstack query + zustand, though importantly we also use React Router's loaders to give the app a better-than-SPA feel on navigations. I do plan on moving it to Remix SPA mode when I get a chance, but like I said the result should be very similar so it's not that high a priority for me. If I were starting from scratch I'd probably use Remix SPA.

Repo: https://github.com/oxidecomputer/console/

Live demo here with in-browser MSW mock API: https://oxide-console-preview.vercel.app


This is what I'm referring to when I say BFF - https://remix.run/docs/en/main/guides/bff

Essentially, its the backend for frontend model, where I guess you really just have a node backend specifically for hosting your frontend app, so you get all of the advantages Remix/SSR/etc provide. The node server usually would handle auth between the frontend and the node backend with a cookie, and then the node backend would call your other backend services, either by forwarding the auth the frontend client sends, or transforming it into maybe a JWT token, or just mTLS? aka a glorified proxy server I guess.


Ah. In that case, that is not a mode (which is why I misunderstood), that is the default way Remix works and it's more or less what every user of Remix is doing. Some people might implement API endpoints in Remix itself, but for the most part people are calling out to APIs in loaders.

Here's a Remix site that works that way: https://rfd.shared.oxide.computer/

We have an API written in Rust that serves the RFD contents and powers search. For logged-in internal users, we are also talking to GitHub APIs in loaders to pull in PR comments.


Ah interesting. How do you generally handle auth between FE <--> Remix BE, and Remix BE <---> Other services?

I could just keep my auth backend in go, on maybe like auth.mydomain.com, and issue cookies for .mydomain.com, which the remix BE can handle. This way the remix BE is really just a thin "api gateway" in a way.


We use cookie auth only for the Remix server. The API uses OAuth, or something close to it. So when a user logs in, we get a token from the API (scoped to the particular user, not a special backend super-token) and store it in the session (encrypted in the cookie value, Remix server has the key — this is built into Remix: https://remix.run/docs/en/main/utils/sessions). That token is then used by the Remix server whenever it talks to the API.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: