Tom MacWright

tom@macwright.com

Remix notes

Val Town switched to Remix as a web framework a little over a year ago. Here are some reflections:

  • The Remix versioning scheme is a joy. They gradually roll out features under feature flags, so you have lots of time to upgrade.
  • Compared to what seems like chaos over in Next.js-land, Remix hasn’t had many big breaking changes or controversies. It’ll eventually adopt RSC, but I am glad that it is not the ‘first mover’ in that regard.
  • We’ve hit a few bugs, in types and utf-8 support, and docs, but Remix is rarely the culprit when there’s an outage or some quirk in the application.
  • We haven’t switched to Vite but are pretty excited to. Initially the fact that Remix is obviously a “collection of parts,” like react-router and esbuild, rather than a “monolithic framework,” was a source of uncertainty, but I now see it as a strength. It is cool that Vite will allow Remix to have a narrower role.
  • The actions/loaders/Forms paradigm is pretty great, but I am still not happy about FormData and not excited about how actions are typed in TypeScript and how much serialization gunk there is. God, that Twitter thread was irritating. I sometimes think conform might help here. We use tRPC a bunch because its DX is superior to Remix’s: the types “just work”, there’s no FormData inference & de-inference required, it’s easy to just call a method.
  • The Remix community is pretty good, there are some good guides and documentation sites to be had, especially epic stack. I’m not especially worried about the project losing steam - any concerns I had right after Shopify bought Remix are gone. I also don’t think that any of the React-alternative frameworks are that tempting yet, though I’m keeping an eye on SolidStart and SvelteKit. Please, please do not @ me about how much you like Vue, I do not care at all and you do not need my approval to keep liking Vue.
  • Most products have a Remix integration - instrumentation with OpenTelemetry just works, Sentry’s tracing integration just works. Clerk has an integration but using Clerk is one of my top regrets for this application: we’ve encountered so many bugs, and so little momentum on support and fixes.
  • We barely use nested layouts, one of Remix’s main features. There just aren’t that many opportunities to. We also don’t really use loaders for the list of vals, either: I think that full stack components are the answer here, but we haven’t implemented that yet.

In summary: Remix mostly gets out of the way and lets us do our work. It’s not a silver bullet, and I wish that it was more obvious how to do complex actions and it had a better solution to the FormData-boilerplate-typed-actions quandry. But overall I’m really happy with the decision.