Remix Vite Is Now Stable
remix.run
remix.run
That behaviour wasn't documented when I got started with NextJS 13...imagine the fun I had trying to work out why I can't get updated data from the server. It was nuts.
KISS.
Should've been a different product.
[1]: https://nextjs.org/docs/app/api-reference/functions/unstable...
This is pretty important for things like sessions with httpOnly cookies. And it forces you make an API call to yourself to resolve.
If only this had been brought to their attention recently with a bunch of good-faith discussion.
This is why you don’t use VC backed dependencies that are not easy to move away from.
now you can simply use the full power of Vite, which means you aren't locked into Remix having to make choices for you.
This is the 3rd time they migrated the underlying tech though, first it was rollup, then esbuild, and now Vite, which is effectively rollup again. I hope they stick with Vite for the foreseeable future though
I’m ashamed to say this took way too long to get working nicely. It was worth it because our linting otherwise went crazy over misuse of Link and anchor, and people on the team weren’t respecting it. This made it so we could say “only use Link” and make it easy for that to be accomplished.
Trust me, it’s way easier to get stuff done with Next :)
Once you get past the day or three spent making it so links do what you wish they did… And you discover it handles cache headers differently than it’s supposed to… And middleware doesn’t work in several contexts with no explanation… And on and on.
AFAIK it’s built by the same folks as React-Router, and I have a distrust of that project because of the tendency to make large breaking changes in order to make things “better” according to some criteria. I’ve been through a few RR upgrades that required a lot of extra work because we were using some previously supported pattern that then disappeared. I like the look of Remix but I don’t want to get trapped in that kind of situation again.
But, Remix’s breaking changes start as future flags on the current major release and slowly become breaking changes over time.
That means you can incrementally adopt the breaking change so the upgrade isn’t all at once.
I suspect the original author might’ve very much learned how to do API design on the fly when those first major versions of RR were shipped. Ie: the hard way, because every change they made caused a lot of complaining (for good reason maybe, but still! People complaining about your open source project is not fun)
So maybe if anyone has a nuanced and wise view of API design and versioning, it’s the RR people :-)
The really hard part has been migrating other stuff like CJS to ESM, or upgrading other dependencies like cypress, but that is not related to remix.
While vite is perfect for most users, there are just some usecases that are not doable with meaningful performance. Without boring you with details why, let me assure you that having a performant webpack replacement for those 10% who need it, helps vite staying lean, as they are not bothered with feature creep.
If you want a small detail why: Vite is built on esbuild. Esbuild is carried by a single developer (https://github.com/evanw/esbuild/graphs/contributors) thus every nut and bolt that vite does for you on top is built in javascript, so you are in slow-land again.
webpack and turbopacks promise (and complexity) is that it treats these extras (plugins and loaders) as first class citizens and thus tries to make them as fast as possible by applying tons of caching. E.g. if you'd throw a webpack workflow at vite, you might end up with a slower build then webpack. And this is where turbopack tries to improve.
> Esbuild is carried by a single developer
The right answer is to support that developer and contribute to the project.The VC answer is to build something entirely novel and then fail to deliver.
They sponser https://github.com/kdy1 (see the vercel in his profile), who spearheads swc, which is very similar in goals and scope to esbuild. swc may ring a bell, as it's the parser/compiler that is used by deno and bun.
Source: check the language breakdown on zig's repo: 0% rust (what swc is written in).
Turbopack is made with that in mind.
That's not Vite's priority, it wants to have a novel approach without backwards-compatibility in mind.
that said, i wonder if anyone has advice on a couple of things
1. typesafe routing and fetching, e.g. using useFetcher then fetcher.submit({title: 'hi'}, {action: '/blog'}). i would love both the {title: 'hi'} and the 'blog' to be typesafe (as safe as you can get in typescript)
2. i still haven't got onboard with using uncontrolled inputs, so i end up using react hook form again. i feel like eventually i need to "watch" one of the inputs, and the main thing again is the typesafety. with react hook form, i can declare my form with zod and be sure it's exactly what i'm then submitting to the server, and revalidate it there. any good ideas here? i would love to get the progressive enhancement from not using js
2. I use remix-hook-forms. It's got helpers that validate on server side and lets you send the errors back to the client and that will display the error on the frontend. This way you can have server side additional validations and send those errors to the client
[0] https://teslamotors.github.io/informed/api-reference/useFiel...
It’s so funny.
I'm on Remix / Drizzle ORM / Render.com / Render Postgres / Cloudflare R2 / DaisyUI + shadcn/ui these days.
Drizzle can be a bit tricky if you're coming from ActiveRecord but once you have your own helpers with a base class that implements common method such as find_by({ key: value}) / create({ data }) / update(id, { data }) / delete(id), things get better.
Render is really good - you don't need any specific configs, just set env vars on their dashboard and git push to deploy. Simpler and better than Heroku workflow.
You can take a look at https://github.com/remix-run/blues-stack to learn how you'd manually implement cookie-based auth on this framework.
Remix is the closest thing to Rails in the JS ecosystem IMO
Check it out, it’s really nice.
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?
Repo: https://github.com/oxidecomputer/console/
Live demo here with in-browser MSW mock API: https://oxide-console-preview.vercel.app
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.
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.
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.
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).
I have never been so productive as I have been with Remix and it's really good that the finally have embraced Vite so I can use all the different plugins etc that exist for it.
It's also more straightforward to get started and has sane defaults for the different "stacks" that exist. It's also way easier to self-host. So there are many positives for remix.
I would say if you know that you are going to use Vercel, use Next.js but otherwise I would always argue for Remix. I was a bit hesitant towards React before but Remix had me totally converted due to how easy it feels developing a full stack react app. Nothing even comes close in the javascript land imo. I have done years of work with SPA with web components/Vue/Angular and an api but using Remix I feel like I am several times more productive.
You don't need a state machine with remix as long as you use a backend (I haven't tried the new Remix SPA mode yet), even if you have a backend in another language it is a great way to do backend for frontend meaning that you can gather the data you need and provide it to the client in a nice way. No more spinners everywhere, let your fast server do the api calls and serve the rendered page to the client. You won't have the issues that usually comes with a SPA if you use Remix with a backend. You can stream stuff if you know you have requests that will take a bit longer to complete: https://remix.run/docs/en/main/guides/streaming
You can read more about why remix is nicer here: https://www.epicweb.dev/why-i-wont-use-nextjs
Exactly. It makes absolute no sense to deal with all of Next's artificially imposed limitations if you're running it on your own servers.
And how about that dev rel... no response since August of last year.
This is why you don’t use VC backed dependencies that are not easy to move away from.
> Next.js is on version 13. React Router (built by the same team as Remix) has been around for much longer
this is not a selling point for me. React Router has been such a pain to deal with and upgrade, Next was much nicer to use in apps in comparison.
Hmm. I'm using Remix and Vercel for a side-project right now and it's pretty awesome. Lightning fast build times (around 30 seconds).
At work, I use Vercel with Next.js and our build times are in the one-three minute range.
Altough, I have never used Vercel so that was just an assumption from my part. From my understanding though, they make it really easy to host Next.js apps with Vercel.
I guess the good part of using Remix if you use Vercel is that when they pull the rug from beneath you, you can always switch to another hosting provider.
I'm open to being wrong here, but this is symptomatic of the developers who implement the components, not the frameworks no? I'm unaware of any major framework that hijacks buttons, you very specifically have to not use the `<button>` element to not get a button.
If what you really mean is an action can still take place even though some JS wasn't loaded (e.g. web standard form submission) then I understand, but otherwise I'm not sure how frameworks are at fault for this issue
> This is a Fetch Request instance. You can read the MDN docs to see all of its properties.
Compare this to Next's app router equivalent of fetching the request headers [1]:
> The headers function allows you to read the HTTP incoming request headers from a Server Component.
[0] - https://remix.run/docs/en/main/route/loader#request
[1] - https://nextjs.org/docs/app/api-reference/functions/headers
And if you want a route's request object in Next, use a route.js file.
I maybe don't understand the parallels being drawn at the moment, so this view is subject to change when I dig in a little deeper.
It's not simpler as in less features.
Genuinely curious as I’m burnt out of the react ecosystem entirely. Svelte seems good but haven’t done much out of demo projects.
I started using when Svelte+Sapper was a thing, simple filesystem routing was the great selling point, then came SvelteKit which introduced plus based routing like +page.ts,*.client/server.ts, inside folders which IMO is a bit more tedious.
and now there are runes, I spent sometime understanding the reactivity syntax using $ and could intuit around it pretty well, but now I've got to re-learn that as well xd.
Note though, I still love Svelte and don't have an issue re-learning since I knew using it before pre-1.0 would certainly involve breaking changes, but the API really did move around a lot and caused some issue.
It's also pretty clean to write and understand Svelte code, feels almost like writing pure HTML/TS.
I personally have built multiple enterprise grade applications (something akin to Substance Painter) using Svelte, and though the reactive dependency chains got long (due to my own faults) they were easily abstractable and resulted in code that's still able to be maintained by junior devs and has survived multiple refactors due to the changing APIs with minimal friction.
Summary: Learn Remix, Accidentally Learn the Web
> It is an explicit goal of ours to design APIs that are high-level enough to help you just get the job done, but close enough to the web to backfill your fundamental knowledge of Kung Fu the web.
That's something I really like about remix.
If I want to learn web fundamentals I SHOULD learn web fundamentals, not through an API that makes it seem like magic, because it's not transferable to other frameworks/platforms. This creates problems for new developers as well, who in this day and age learn frameworks instead of the underlying tech, and then bring that mindset to other domains.
I've had so many React devs being unable to work with say a Svelte or a vanilla HTML/TS applications because their web development skills are actually React skills.
For ex this line here
"When you learn how to handle requests and send responses in Remix, you're actually learning the Web Fetch API that's in the browser already."
I'd rather just use fetch so I know explicitly what I am doing.
I must say I'm not entirely blown away by it. It's unique feature (frontend/backend coupling) kind of feels like it's just a re-engagement with the traditional web app. Or even just akin to a mono repo for a modern frontend/backend.
Beyond that, it's main let down (which is in no way unique to it) is not having a straight forward application entry point that allows you to wire things up as you see fit (composition root). Instead we get a request handler that we hook into another server technology that in turn makes their controller equivalents work like magic.
My struggle with it, as of this afternoon, was to figure out how to bundle raw SQL files in the build until it became apparent that you have to unbox all the Vite functionality and do it that way (which seems to have some depth) or literally have a parallel step outside the build for copying the files into the build dir. Not the greatest experience for what is a pretty basic step (embedding resource files in the build output).
Very much feels like a project that is just a small twist on what already exists in the ecosystem and will fall into the growing black hole of JS web frameworks. Sorry to be glum :/
Edit: and maybe to add more context (and a bit less glib). My approach to interacting with an rdbms is to put each query in a separate SQL file (so no dynamic SQL and no query builders - ORM or otherwise) and execute them with a simple db client. In this case pg-promise. I've landed on this approach after many years of using various approaches and seeing how those approaches take affect on a team/product over time. Though of course ORM vs raw SQL is an argument as old as time (or as old as ORMs at least).
SSG is somewhat tricky with solidjs, in fact I used Astro with solidjs integration to achieve it.
Personally, I haven't experienced that kind of "this is simpler" feeling since jQuery.
This is thrown around by each and every framework so much that this lost any meaning. What does it mean? Which of the 11 custom React elements (including Link, Form, Await) and 26 custom React hooks are "simplification and leans heavily into Web APIs"?
---
As a side note, here's how it tells you to add a stylesheet to the app. So simple, much Web API: https://remix.run/docs/en/main/start/tutorial
import type { LinksFunction } from "@remix-run/node";
import appStylesHref from "./app.css";
export const links: LinksFunction = () => [
{ rel: "stylesheet", href: appStylesHref },
];- loader, action, component colocation
- code splitting without thinking about it
- automatic data revalidation on mutation
- useFetcher for optimistic updates
In terms of the fancier things (the react components) -- none of that is necessary. Personally, I don't use <Await> or <Defer> at all. Although it's nice to know that I need to pull some performance levers, I have those options.
One React component that I do use a lot is <Link>. The thing I love about it is that I can add a <Link prefetch="intent"> to it, and I'll get an near-instant page load when I click it.
The web APIs that I work with in Remix are Request, Response, Headers, Cookie and FormData.
Simplification compared to what?
A better alternative to what?
> In terms of the fancier things (the react components) -- none of that is necessary.
It doesn't matter if they are necessary or not, they are there in the framework.
> The web APIs that I work with in Remix are Request, Response, Headers, Cookie and FormData.
That's.... it? You call that "leans heavily into Web APIs"? Have you ever thought of what backend services do all day everyday? These are not "web apis". These are wrappers over HTTP.
It is still better than any React based framework.