When you are developing React apps, you have heard about Create React App, Next.js, Gatsby and others. Those frameworks make it super easy to develop React applications rapidly by providing a foundation for single page applications, static and/or server side rendered pages. They abstract cumbersome tasks like bundling your application, running your development server and, in some cases, routing. They make it easy to set up and begin developing your business application.
Now a new kid entered the stage: Remix Run. It is a React framework with the fundamentals of the web in mind: server-side rendering, easy data fetching and mutations, and giving as much control to the developer as possible.
In this blog post I want to highlight some of the features I find particularly interesting. If you want to read more about those features, I encourage you to read Remix’s documentation. Lots of things are still work in progress as Remix is still in Beta.
The first thing that stands out: Remix is not free. It costs $250 for an indie and $1000 for a company license per year. Most other frameworks are free and open source, with Remix you get access to the code when you buy a license. I think paying for a solid framework is worth it – it helps funding the developers behind Remix – and, more importantly, gives you access to support. In most open source projects filing an issue in the issue tracker (like GitHub Issues) gets recognized by the maintainers. Depending on their schedule, they might help fixing the issue or leave it be. My hope with Remix is that by paying for the license, I get faster help with and fixes for my problems – and at a higher quality. Currently, you get access to a Discord server from the developers where you get help from them and the community around it.
Client and server entry points and imports
The second thing that jumps out is that you get access to the React entry points. You have a
entry.client.tsx and a
entry.server.tsx file, which contain the
ReactDOM.hydrate(<RemixBrowser />, document) and
ReactDOMServer.renderToString() functions. You can even wrap them and inject render times to your page. This is super cool and (to my knowledge) no other framework provides this.
Additionally, every file you suffix with
.server.* is only available on client or server. This ends the days of checking if
window is defined. Depending on the location, the import is
undefined and the code not executed. Awesome!
Remix uses esbuild as their bundler. It is written in Go and has insane compile times. I built a simple dashboard for applications running on my Raspberry Pi 4. Building the React application using Next.js (which uses webpack) took 55 seconds to build on said Raspberry Pi 4. The same dashboard takes less than 500ms to build with Remix. Yes, you read that right. Less than 500ms. To be fair, I’m using Tailwind CSS, so we have to add 10 seconds build time to the 500ms to have a more fair comparison between both as the Tailwind CSS minification takes place in the Next.js build and is separate for my Remix build. But nevertheless, the speedup makes trying Remix out worthwhile.
Data fetching and mutations & session management
Remix is build on the concept of
loader for each page. They are run server side where you can talk to your database or API. A
loader fetches data from any source and passes it to your client. An
action is called whenever you have a
<form> submit – gone are the days of client side mutations. This is especially useful when you want to save the data a user entered in a form or clicked a button. This is now handled by the
action on the server side, where you can talk directly to your database for example. They also provide handy helpers to model loading states and even “submit” calls to the action if you don’t have a
<form> for data mutations.
Passing data between client and server is also made super easy using sessions. A session is a cookie that holds your users data which you can use to pass data from your
action to your
loader, e.g. error states.