React Server Components and Shopify Hydrogen [Ilya Grigorik]

The ex-Google performance/browser expert explains Shopify's new React Distro.

Listen to the Changelog (40mins in)

React Distros: tweet, blog

Try it out:


when we looked at the available set of tools in the React ecosystem, we felt like the existing crop of frameworks, and particularly ones for commerce, don’t solve the right problems, or maybe don’t stack the right decisions to enable this dynamic commerce experience that we’ve been talking about.

There’s a host of really good tools for statically generated pages, but if you really wanna build a fast, server-side-rendered, React-powered experience, you have to hire some really smart people to make that work. And that gets very expensive very quickly. So most teams fail. They end up with subpar experiences, and we thought we could help. So this is why we entered into this space and said – it’s not like we’ve invented server-side streaming.
I think I was with you guys on this show ten years ago, talking about streaming in HTTP servers.
So this is not new technology, but it’s a new stack. It’s a different stack, it’s a different set of choices. So now the question is “Well, I do want to use React on the server and client. How do I do that, while still delivering a really fast server-side streaming solution that is not blocking on data requests, such that I can enable the clients to quickly render at least like a visual shell of the page, provide some loading indicators, and speak to that user experience aspect of speed, not just the technical metric of speed?” Like, did you get the fast time to first byte?
I can imagine us being two years down the road, having you back on, Ilya… So we’re at the opening gates of a new thing for you. You’ve put six months into this, you’ve worked closely with the React core team, so you’ve had very knowledgeable people involved with this project on how React works. But I can just imagine, to Jerod’s question, like “Why did you choose React over Vue, Svelte, and does it lock out other frameworks?”, I can imagine this as the beginning. And like any beginnings, you start from somewhere.
I think that’s exactly right. We took a pragmatic choice. So if you look at Oxygen - as I said, it’s a thing that accepts an HTTP request and spits out an HTTP response. It doesn’t matter what JavaScript code runs inside. So any server-side JavaScript is fair game. On top of that we have GraphQL, which is framework-agnostic, of course… And now it’s a question of “How do you make the right architecture decisions on the server? How you compose the response such that you don’t end up blocking the response for too long?”

[36:12] So let’s say you need to fetch product data, query some product description data, maybe figure out card discounts… Can you do those things in parallel, as opposed to sequentially and blocking, and stream that such that the user has a good user experience?” So that’s a set of choices that you have to make, and that’s a problem that we’re solving with Hydrogen.
You mentioned Next.js… Did you consider a similar approach, versus all server-side rendering, but kind of a hybrid, where they have some prerendering, they also have some server-side rendering? Or is it just caching is your answer to all prerendered pages? Like, you’ve got a marketing page, or your About page, and instead of prerendering it, you just cache it?
Yeah, we actually work very closely with the Next team. They’re also innovating and pushing the boundary on React Server Components. React Server Components is this new hot thing that the React core team dropped as a Christmas gift to the community last year… And everyone got super-excited, because it’s this RFC, and it answers the perennial question of “How do we actually separate client and server concerns? Can we create a convention around data loading patterns?” Because right now, every React framework has to figure out “How do you do data loading?” You know, getServerSideProps vs. something else… You have to learn a new dialect every time you pick this up. React Server Components tries to answer that.

And further, it adds a set of new – or opens doors to a set of new possibilities. Things like – it wasn’t possible to do component-level updates before. So if you render the page, and the user is interacting with the page, and you want to reload just a sub-tree, you can hack that via various ways, but there’s no well-defined convention for how the framework itself can do that. React Server Component answers that. Also, by creating this boundary between client and server allows us to build better and more optimized bundles.

One of the pitfalls - pardon the tangent here - of isomorphic client-server JavaScript is, ultimately, we’re building these React applications to run in the browser. So there’s a set of assumptions about browser capabilities and browser APIs being available. You bring that onto the server, and you go “Well, it’s not quite like the browser”, right? These APIs are not available, and now I need to figure out - if I only run this code, do I export these exports to clients as well? It becomes really muddy, really quickly. And maybe if you’re super-judicious, you can navigate through that forest, but it’s a very challenging problem.

RSC (React Server Components) defines those boundaries, and at least on paper it promises to solve many of those things. And it’s still under active development. Shopify has been one of the early adopters. We saw it, we played around with it, we tried to rebuild our own applications with that pattern, and we felt like it felt nicer than what we were using before… Because similar to any other framework, we were inventing our own data loading strategy. And then we swapped it out for RSC, and we’re like – look, it’s new, so there’s still friction for most React developers, because, well, it’s a new shape of API… But you kind of get these second-order effects; it just feels more intuitive. It’s easier to grok. So even though it takes a little bit of runtime for someone new, they see the filename, and it says .server, and it kind of just clicks. It’s like, “Oh, I can infer what that means.”

So we have the benefit at Shopify of starting anew. We’re not a framework with an existing install base of thousands of apps. We don’t have to move them over into this new world, which is one of the challenges with the React Server Components, Suspense, and all the rest. If you have an existing application, a lot of these things are not easy to adopt, because they change how you have to think about data loading, different state transitions, and all the rest. For better or worse, we’re starting from scratch, so we’re willing to take some opinionated and future-looking bets, because we have the luxury of not breaking anything… Yet.
[40:04] [laughs] Yet. You have the luxury for now.
Exactly. So this week – this is maybe a good transition… So what have we launched this week? This week we launched the Hydrogen developer preview, which is – we’re not claiming it’s production-quality code. In fact, we wouldn’t encourage you to write production code; you could, and nothing stops you, of course… But we wouldn’t encourage that, because we wanna use the period of the next couple of months to really iterate on the APIs based on feedback from real developers, and probably break things. Right now is the time to dramatically change in backwards-incompatible ways, before we declare it to be a 1.0 that folks can build production storefronts that run on Shopify… And then we have to maintain for a while.

So this is a really good time, if you’re just curious about what is React Server Components, what is Suspense, how do I do server-side streaming - go kick the tires on this thing. Play around. I think we’ve made it really simple. For anyone listening to this, if you just type in in your browser, it will open up a StackBlitz-powered dev environment that runs completely in your browser, and you can just start hacking right away. It’s a really awesome experience.
2021 Swyx