Remix is a new full-stack JavaScript framework which focuses on web standards, modern web app UX,
and which promises to help you build better websites. In this post we'll explore how Remix is ideally suited to
headless commerce.
First of all, if you don't know the term "headless commerce", it just means e-commerce applications where the storefront communicates with the commerce backend via an API. Vendure is one such "headless" server - it deals with all the product, order & customer data and logic, and the storefront interacts with it via its GraphQL API.
I've been aware of Remix for a while, but it was only after reading
their blog post comparing Remix to Next.js that I really sat up and paid
attention. I soon discovered that it could be an ideal framework on which to build a headless commerce storefront:
- it supports server-rendering by default
- it ships minimal Javascript to the browser, keeping initial loads fast
- it has native support for prefetching to speed up page loads
- it encourages graceful error handling
- it runs on edge servers (more on this later)
In fact, I was so impressed with what I saw that I decided to make Vendure
an official sponsor of the inaugural Remix Conf!
React made simple
As a React newbie, I wasn't sure what I was letting myself in for - I've dabbled with Next.js, but I'm not afraid to
admit that some of the more advanced uses of hooks still confuse me. I was really happy to discover that the whole
design of Remix meant I very rarely needed to reach for anything more complex than useState
!
For the initial proof of concept I had the help of a React-savvy friend to get
things started, and after sharing my progress on Twitter I got
some invaluable tips from Kent from the Remix team (shout
out to Kent for his incredible work supporting and boosting the Remix community!)
After that I found I was able to move quickly, even with my limited React experience! The more notoriously complex
aspects of building a React app - wrangling build tools, dealing with state management libraries - seem to be completely
side-stepped by Remix's opinionated approach to the app-building experience.
Effortless server rendering
E-commerce is the archetypal example of the need for server-side rendering (SSR) of web applications. Why? Because
ensuring that search engine crawlers can read our pages is essential to driving traffic to our shop. Back in the early
days of JavaScript web apps, we had some interesting solutions to this problem - anyone else remember using headless
Chrome to crawl our sites and generate static HTML files? On the other hand, build-time static site generators like Gatsby can become difficult to scale to stores with hundreds or thousands of products.
Thankfully, most modern JS frameworks have some kind of built-in support for SSR. Remix is a great example of this. The
server and client code exists in the same file and passing data from the server to the client is a matter of returning
an object from the loader
function.
Not only does this approach make your pages SEO-ready by default, it also allows you to limit the browser bundle to only that code strictly needed on the client. This can massively reduce the amount of JavaScript sent to the browser,
significantly reducing load times and speeding up the storefront experience.
Bye-bye client libraries
Since Remix is a full-stack framework, it is able to load data directly from a database rather than requiring an HTTP
API like most front end frameworks. I was curious to see how it would work with Vendure's GraphQL API as a data source.
I was very pleasantly surprised to find that it works really well! I would usually reach for a full-featured GraphQL
client with a normalized cache like Apollo Client or Urql, but by fully embracing the Remix way, plain old fetch
worked perfectly. The usual issues of client state getting out of sync (which I typically solved with a normalized
client cache) are solved by Remix's method of revalidating any data that might have changed.
Not only does this significantly simplify data handling, it also completely removes the need to ship any kind of
GraphQL client library to the browser!
Living on the Edge
Since a Remix app is both a server and a client application, we can't just host it like a simple static website. It
actually executes JavaScript when a new request comes in. So how do we host it?
One option is to run it as a traditional Express app. But due to the smart platform-agnostic design of Remix, it can run
in any Node.js server like Vercel,
Netlify or AWS Architect. Furthermore, it can run on non-Node.js platforms like Cloudflare Workers or Deno Deploy.
Cloudflare Workers is a particularly exciting technology - it allows you to run code
at "the edge" - which means a network of servers distributed all around the world. So if a customer in Sydney visits
your store, they will be served by a Cloudflare server right there in Sydney. Likewise in Vienna, Lagos, Seattle or any
of the 250+ locations worldwide. This can dramatically reduce the latency of requests, making your storefront lightning fast (as you'll see in the demo below!).
Show me!
Yes, the video above is in real-time!
The Vendure server is a default installation running on a $5 Digital Ocean droplet backed by SQLite. No special caching or performance tricks - just a completely vanilla install.
The Remix storefront is running on Cloudflare Pages. It feels like a static website, but it's fully dynamic.
The combination of Remix's performance-first design running at the edge really has to be seen to be believed. Try it for yourself! 👇
🛒 remix-storefront.vendure.io
👨💻 github.com/vendure-ecommerce/storefront-remix-starter
Special thanks to Edo Rivai for doing the initial work on the Remix storefront repo - your React expertise got me started in the right direction! Also thanks is due to Conor Burns & Timur Dogan of 0xcb.dev who first got it running on Cloudflare Pages 🙏.
Top comments (1)
Thanks for sharing your journey trying out Remix and thank you for sharing the repo to get my hands on it and test it out 😉