354: Next.js and Now with Guillermo Rauch

Download MP3

Guillermo Rauch stops by to talk about Zeit, Now, and Next.



Guillermo Rauch

Web · Social

Before starting ▲ZEIT, Guillermo was the CTO and co-founder of LearnBoost and Cloudup, acquired by Automattic in 2013. He's the creator of several popular Node.js open source libraries like, mongoose and slackin. Prior to Node.js, he was a core developer of the MooTools frontend toolkit.

Time Jump Links

  • 00:41 Guest introduction
  • 01:21 What is Zeit?
  • 06:27 How does Now work?
  • 12:25 Lamda isn't required
  • 15:28 The nature of what we're doing is serverless
  • 17:50 What's the reliability of serverless?
  • 21:44 Sponsor: Jetpack
  • 23:22 How granual is control?
  • 31:40 Mono repo
  • 35:35 Sponsor: Flywheel
  • 37:50 React and next
  • 48:23 Performance concerns
  • 53:22 Pre-rendering
  • 56:21 How has React changed everything?


[Banjo music]

MANTRA: Just Build Websites!

Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another episode of the ShopTalk Show, a podcast all about frontend Web design and development. I'm Dave Rupert and with me is Chris Coyier.

Chris Coyier: [Laughter] Hey, Dave! We're kind of rounding out the end of our little mini-series talking about the JavaScript-based ecosystem of today. I think we have the perfect guest for the end of that series. It's Guillermo Rauch. Hey, Guillermo. How are you doing, man?

Guillermo Rauch: Great. How are you guys?

Chris: Good. Good. You do so much great stuff. First of all, everybody should follow Guillermo on Twitter. Hilarious. Good Twitter follow, I have to say.

Dave: I think half my computer is Guillermo Rauch products.


Dave: I'm not sure, though. I'm not sure.

Chris: It's interesting to think about you as a whole because there are all of these big, major projects that are all under the ZEIT umbrella, in a way. ZEIT itself, maybe just tell us what ZEIT is and the different components of it, as you think about it.

Guillermo: Yeah. It's a global company whose mission is to bring cloud computing to everyone in the world. Obviously, cloud computing is very broad but, the way that we're getting started is, we're making serverless computing more accessible. Meaning that you can deploy any website or application instantly, whether you get/push and you get a URL from us of your deployment, bring your website online in seconds, or you use our Now tool to write Now in a Terminal and you get your deployment ready.

We also are very famous for our Next.js framework, which is a React framework. We had the same idea that we should make deployments simple. Creating a React app was not simple enough. Everything we do is React. We love React, so we looked around and we were like, "Oh, this is too hard." The company tries to create the best developer tools that are ergonomic, that are open source, that are free to use and, yeah, bring them to as many people as we can.

Chris: Maybe some people's first experience with ZEIT is Now because it's so satisfying to have a URL for the thing that you built. You're working locally. That ship has already been established, fortunately, in the world of working on computers. People learning these days, that's how they learn. They make a directory in their local computer, they build stuff, and they NPM install stuff, whatever they're doing, especially if what they're learning is JavaScript-focused.

Guillermo: For sure.

Chris: Then what? You maybe even have a local server going and it's somewhat satisfying to work on stuff, but there is always that final step of getting to an actual website. It's kind of a fun part, in a way. Some people take to that. Maybe they turn into dev-ops people someday or something.

I remember what it was like in my early days. I'm like, "I bought a domain name! I managed to do it. Somehow, I figured this out myself." Then I got an email that gave me FTP credentials, and I figured out how all that works. I found some freeware FTP client, and I managed to get myself connected somehow.

Guillermo: Or you bought one.

Chris: Yeah, perhaps I paid for one and dragged and dropped some files in there. I guess I put them in the right place because now my website is showing up. I had to hand deal with DNS and stuff.

Sometimes that stuff is still fun. I do some of that stuff once in a while but, wow, is that ever a barrier. I could see how a curriculum at a school might just be like, "Oh, here's what we're going to do now. You have your little project going. Type, "Now." [Laughter]

Guillermo: Right.

Chris: It goes, "Whoosh."

Guillermo: Actually, since you mentioned DNS and there is also SSL certificates to make the connection encrypted and secure. What's great is we do all that for the developer, but then we also expose all the underlying layers. It's not that we're trying to give you some magic potion, lock you in, and then you never learn about all the pieces or you lose the ability to customize.

What's beautiful is, you run now. You get your deployment going. Then you can peel back the layers if you wanted to. Like you said, for example, if you want to associate your deployment with a domain name, we handle all that DNS configuration, all the TLS configuration for SSL certificates. It's all for free, things … encrypt.

Yeah, you get kind of the best of both worlds, which is why I'm so excited about this because it is unusual that you get a good experience as someone that is just getting started. Then you actually get a scalable experience if you're getting a ton of traffic or your project is really growing and really getting traction.

Chris: It's best of both worlds in all ways. It's easy and configurable, and it's for little sites and huge sites. You kind of cover the whole spectrum there.

Guillermo: That was our inspiration was companies like Apple. They have put out a lot of ecosystems that have been so great in that divide. If you think about the current iOS ecosystem where they even now teach you Swift on the iPad with Swift to play around, I think all the platforms are kind of converging into this idea that you have to serve the creator at all levels of their expertise.

Chris: Yeah.

Dave: Kind of nube and pro, consumer pro.

Guillermo: Yeah. I think, in many ways, we're all new to technologies all the time. The neat thing about it now is that we never married ourselves to one programming language, one technology, or one framework. We're obviously fans of React, but we have a ton of Vue user, for example. [Laughter]

Dave: Yeah. I was going to say, I think I always associate you with the React kind of deployment system, and that's probably because of Next, which we can talk about. Now, in itself, is kind of just a node server, but it looks like you serve PHP and all kinds of things, right?

Guillermo: Yeah. Yeah, because--

Chris: Yeah, let's get into that in a minute but, first, if I just create-react-app and I have a little react-react-app going, I would just assume that it's going to work on Now, and it probably does, but how does it, though? Does it need a dist folder? What's the magic that makes that? Is it going to run some script from my package.json? I assume it will pull all my dependencies for me, or do I have to push my nodes modules folder? How does it work?

Guillermo: You can run the build local if you wanted to. Like you said earlier, you can bring in your NPM dependencies and all this kind of stuff. Then you get a dist directory with create-react-app, for example, or petty much with every static site generator.

Then you could say, "Hey, now deploy this folder." But the way that we promote doing it is, we can actually run the build in the cloud. There are lots of benefits to doing that, especially when you start realizing that, oh, my node modules directory is out of date or it gets really, really big. For example, you can keep a cache in the cloud so that all your builds get faster and faster, which is really nice.

Typically, what you do is, in your package.json file, you set up a script that is called Now-build. You say there … build or or whatever it is. Then in the Now.json file …, "Hey, I want to build this with Node.js," so we bring in NPM or Yarn and run the build and then serve your directory.

That's what I was mentioning earlier. There are a lot of people out there that don't use Node. What's neat about Now is that it's just as friendly for the Node.js developer or JavaScript developer as it is to even native developers. Since we come from the JavaScript community, we wanted to make this experience as easy as writing a Package.json file, which you probably already have.

Chris: Yeah. Yeah, and so your little repo, it doesn't even have to be a repo, right? Your little local directory could be just an index.html file if it wanted to.

Guillermo: Yeah, for sure. For sure.

Chris: It could run the Vue CLI. This was surprising to me. Can't it just be like an index.php file? It'll run PHP.

Guillermo: Yeah. [Laughter] Yeah, so that's the beauty of it. We have this concept of what we call builders. For those of you in the audience that are familiar with Heroku, you can kind of think of Now as Heroku for a server, meaning there is no process that you have to monitor of serve. There is no dyno. You actual pay by hundred milliseconds of execution instead of paying for a monthly price of a server.

What's really neat is this concept of builders. You can say, "Hey, all my PHP files use Now/php." Now/php is another open source project, which is an NPM module, which will wrap your code, your PHP code, in this case, and make it work serverlessly. The beauty of it is, any kind of code that you have in your directory or in your repo can be packaged and run in the cloud and you didn't have to do any of the building, any of the packaging, any of the cloud configuration. Like I said, it works just as well for PHP as it is for create-react-app.

Dave: I think a lot of PHP apps are kind of built on a framework like--

Guillermo: Laravel, yep.

Chris: Yep.

Dave: --Laravel, that's kind of just like a restful server and that's kind of serverless's bread and butter.

Guillermo: Yeah, exactly. One of the things that we set out to do with Now is, like, okay, what are the things that are not going to change in ten years? In my opinion, that's protocols. TLS, SSL, HTTP: they do evolve, right? HTTP has become HTTP 1.0, 1.1, HTTP2, and now they're coming out with HTTP3.

Older apps are always backward compatible from a protocol standpoint. The same with TLS. We went through TLS 1.0. It had a lot of bugs. 1.1, now we're at 1.2, now we're going to 1.3 and it's being deployed right now. All those things just work for the end user.

However, technologies change a lot, right? The frameworks tend to be more of a fast-changing, faster-changing ecosystem, at least. I was doing MooTools first. I was doing jQuery next. Today, I'm doing React, and who knows what we're going to do in five years.

Our take was, okay, how can we help developers get started instantly and, yet, retain that flexibility to be completely future proof? We handle all the protocol stuff for you, like I said, like DNS, et cetera. Then we expose these little JavaScript builders that will wrap your code, build it if necessary, and this build will happen in the cloud.

Then when that build completes, the outputs of that build is what matters to us. The outputs could be static files. As you mentioned, Chris, when you build with create-react-app, it gives you a dist folder with a bunch of static files. That's one potential output of the builders.

The other one that is super interesting is this land of functions concept. Land of functions is kind of like static files. They kind of get distributed in our CDN, just like static files. But when you hit them, as a user when you request them, they can execute dynamic code.

Chris: They run. Right.

Guillermo: Exactly, so it's a beautiful model because what I always say that if you've ever used a CDN, we never stress that your CDN will stop working in the middle of the night, will not scale. You're like, "Oh, my God. I cannot serve enough load without PNG." That never happens.

With Lambda functions, you put your code side-by-side those static assets at the CDN edge. Then when the requests come in, when your users come, they get executed. It's kind of magical and we make it very open. We make it very transparent. We make it a multi-cloud provider. We make it multi-language, multi-framework.

Chris: Oh, so you're using the word "Lambda," which happens to be an AWS word, but it doesn't--

Guillermo: Correct. [Laughter]

Chris: It doesn't matter.

Guillermo: Yes.

Chris: It's just a cloud function, yeah.

Guillermo: Yeah, so AWS kind of pioneered this concept. But, nowadays, there is quite a steady inflow of competitors to the space. The idea is that cloud function today. One example is AWS Lambda, Google Cloud Functions, Azure Functions.

What's beautiful about Now is that you focus solely on standards compliant code. You kind of write the code the way that you've been writing it all your life. Then, at packaging time, we're sort of deploying them with all the cloud providers. This is what our customers really don't want to do. Our customers don't want to log into a cloud infrastructure provider console. They don't want to twist and turn the knobs. Most likely, you just want -- you know this very well because--

Chris: No, it's terrible. It's terrible. I've done it. None of them do it particularly well, which is why other companies are having success in it too, not that you'd want to sit around and talk about your competitors. Just think of a big one like, which really helps you with this.

Guillermo: For sure. Absolutely. Absolutely, and it's a very exciting space. I think when you think about, okay, if I had to build an application the best way I know today, you kind of always want this sort of new trait. You would want to reach every person in the world instantly.

Deployment used to be very much confined to, I picked one AWS region or I picked one Google Cloud region, and then I booted up my server there. But at the rate that businesses are evolving today, you kind of want to be wherever your customer is, and you want to be right there. Serverless kind of gives you this in a very, very natural way.

Our job is, we take your code and we place it right where you need it without doing any configuration. We've had customers that were, for example, very California-centric in the beginning of their business lifetime. Then they started spreading in the U.S. Then they became international, and they never had to reconfigure anything. Never reconfigured an internal VPC network or a load balancer, a placement group, or auto-scaling group. I could go on and on and on about all the jargon that our amazing dev-ops team knows but, luckily, our customers don't even need to learn about, really.

Dave: I went through the process of setting up an AWS with a load balancer in a staging environment and all this stuff recently, and it was nightmare fuel. It was really difficult and awful, but I like that you all handled that and you're kind of going for latest best practices too.

Guillermo: For sure. As I was saying, I think those have a place, but they have a place in very, very, very special and specific circumstances. What's neat about serverless, in my opinion, is that most of the stuff that we do is inherently serverless. This is kind of one of the keys to me.

Even though we can write things as servers, the nature of what we're doing is serverless. What do I mean by this? When you are writing, for example, PHP back in the day and you were mentioning uploading it into the FTP, of course, there was a server somewhere. In general, with something like Apache or NGINX. But when you were writing PHP, you were kind of focusing on, I'm writing the request logic. I'm writing only my business logic, and that's a really nice thing because you can sort of separate your code, the one that matters to your customers, from the server code, the one that matters to protocol developers or load balancer people.

Arguably, every time you're doing something on the Web, you can model that problem serverless. If you opted to do so, you kind of liberate yourself and get all these properties. You can move from cloud to cloud. You can go to the edge and meet your customer there. You can focus only on a smaller surface of the problem.

A common problem with JavaScript that bit me so many times throughout my career, especially with JavaScript running on the server, was, if anything goes wrong with your process, with your server, you bring down everyone with it. I'll give you an example. You have a hundred requests coming in, some for your API, some for express JS static file serving and whatnot. Something goes wrong somewhere, so the process crashes. It fails at this point. An unhandled promise rejection problem, for example, or a memory leak, which are supremely common in a language like JavaScript. When your server crashes, it literally brings several … common to that place.

A very interesting aspect of serverless functions, as I mentioned, you can think of them as static assets. They're all sort of independent units of execution so, if 100 customers come to your application and one has a problem, the problem is limited to the invocation of that function. I cannot describe how many headaches this model will save you.

Like I said, it's not even just talking about our solution. It's all about the model that has been this liberating discovery that many people in the industry are making.

Dave: What's the reliability of serverless? It's always the, "You're just using somebody else's server in the cloud." In your experience, what's been the uptime reliability of serverless?"

Guillermo: The reliability of it, I think, I would say is what it's best at because of this idea that I mentioned that you can almost imagine that the requests that come into your system are sort of the health checks to your system. If you've ever written a server correctly, you might know that you have to write what's called health … or health checks. It's kind of like if you have a server just sitting around there permanently. It's almost like, every once in a while, you have to go to the server, "Hey, are you okay? Are you still connected to the database?"

Dave: Yeah. [Laughter] We have a whole Slack channel dedicated to, "Hey, can you reboot the server?"

Guillermo: Exactly. You're like, "Server, are you okay?" You pray to it. You sort of massage it a little bit. You have to do this every five seconds. [Laughter] In practice, obviously, you tend to set up this automated health check and whatnot.

Then there's another problem that comes in there like, you can't just write a health check that says, "Are you okay?" It's almost like you have to ask the server everything about its life. "Server, are you okay? Are you connected to the database? Can you resolve DNS? Do you have enough memory? Are you not in an infinite loop deadlock there?" It's like you have to ask it for the entire state of the world.

Serverless doesn't need you at all. There is not even a way of doing this. It doesn't need you to write health checks at all because what happens is, you can imagine it's almost like lots of mini servers are booting up and dying all the time. What happens is, the request comes in and your function gets instantiated. Then it establishes the database connection and so on. That limits the room of what can go wrong.

You were asking about reliability, and this is where I get really excited because, throughout my career, I've had so many of those situations that you're talking about right now, like the infamous, "Have you tried unplugging it and plugging it back in?" That's what you sign up for when you use servers. You sign for, eventually, at some point, someone noticing that some state somewhere went wrong and you have to turn it off and turn it back on again.

Serverless functions are always turning off and turning back on again. They naturally--

Dave: They've just kind of accepted that natural reality.

Guillermo: Yeah.

Chris: Yeah.


Chris: Although, you can't really control it, to be fair. Sometimes it will recycle itself and sometimes it won't, in my experience.

Guillermo: Yeah, so there are a few rules that, once you started using the system, you understand that there are some optimizations that go in. Obviously, it doesn't solve every last problem in the universe. But, like I said, this is kind of how people started doing Web servers to begin with way back in the day.

Then, yeah, you mentioned, we took a lot of detours. We made deployment really hard. We had to get FTP credentials, et cetera. I would say, in technology, the problem is not always linear. I think sometimes you take ten steps forward and, in some situations, one step back. I do think that this is one of those cases where, by yourself opting into a simplified model of execution, what we call a scheduler. When you use a simple scheduler, which is a way of handling incoming work, you basically just have a simpler operational experience and you can focus on your business, and you can focus on your website.

Every single day, I think what I try to remind my team of is, our experience is all about the pixels on the screen, the replies in the command line, how fast our APIs are, and it's not really about what kind of infrastructure we decide to run on. I think it's all about saving energy and time.

[Banjo music]

Chris: This episode of ShopTalk Show was brought to you by Jetpack, you know the WordPress plugin that does all kinds of stuff for your self-hosted WordPress site. I use it on every single self-hosted WordPress site I have because I just love the feature set. One of the feature-set things that's pretty cool is, you just flip it on.

There are a bunch of these, like, light switch features in Jetpack where you're just like, "Do you want this?" Yes. Switch it on. Now you have it. It requires no configuration, no fancy stuff. You just get some improvement from it.

One of them is that they have an image CND called Photon. If you have no image solution other than just hosting your own images on your own website, you'll almost certainly benefit from this. You just flip it on and then your images are hosted on their CDN called Photon, which is already good because CND hosted images are just an improvement, of course, but it helps optimize them. Because your site already does responsive images anyway, you have that.

I've talked about this before. They just improved this feature. They call it Site Accelerator now that does your images as well, but it's starting to host more and more files on their CND for you. This new one is that anything that ships with WordPress Core, any file that they can count on that is hosted in that way that your site uses for some reason, when you flip this feature on, it is also CDN hosted now. That's pretty cool.

I'm going to run some tests pretty soon, I think, on a self-hosted WordPress site with none of this stuff turned on and then flip it on and see what kind of speed improvements are there because they're definitely there, especially if you test in different locations around the world farther away from your home-based server and all that. The new Site Accelerator feature in Jetpack 6.7, I've just been like, "Hey, cool. Hey, thanks for the help." [Laughter]

[Banjo music]

Dave: I have a question. I do want to talk about Next, but when you design an API or something or you kind of auto-chunk it up, it sounds like a bit, let's say I have a CRUD app and I have whatever posts in my CRUD app--that's create, read, update, delete--when I push a serverless function, is the create a post function its own separate application or is there a user application? How granular does it get, or do I not even need to understand that?

Guillermo: That's a good question. I think it's useful to understand that there is a huge advantage to being granular. Imagine that you have an application that has 100 API endpoints. How neat would it be? This is kind of the crux. If there was one takeaway of server versus serverless, this is, in my mind, the crux of the question. When you have 100 API endpoints and you change one, and the other way that I described it to front-end developers is if you have 100 pages and you fix one typo, what would you rather do? Would you rather rebuild the entire server and redeploy it in its entirety? Keep in mind that projects just grow, especially successful ones.

Chris: I don't know. It depends, I guess.

Guillermo: This could be ten endpoints today.

Chris: Yeah.

Guillermo: One hundred API endpoints tomorrow, 1,000 in the next month. Or would you rather change one function and redeploy that? That's what our system does. But it kind of works like React, so if you are familiar with React, you always tell it, "Hey, re-render the whole thing."

That's what you tell Now. You're like, "Hey, Now, here's my entire project. Do your thing." What Now is going to do is, for example, if you have an API directory and you have a bunch of files in there, like user.js, index.js, and sessions and files, or you have even more granular stuff like a functions directory, we will go and package each one of them. Then we are smart, kind of like the whole VDOM div, like React div approach of the DOM. If something changed under the hood, we only redeploy that. This just has tremendous efficiency advantages.

To give you an idea, when we packed servers into containers, the smallest server, the smallest container -- and you can check up on this later on after the show. The smallest Node.js container you could possibly create after gzip compress level 9 is 40 megabytes or so. There are some tricks. You can use different base operating systems or whatever. Some will originate 25 to 55 megabytes.

In comparison, a serverless function of a Node.js application ends up being just the scripts that make up that serverless function. Some of our customers have mini express apps, mini express.js apps that are serving a part of their application at a particular endpoint and they are like 200 kilobytes. It's rare that, in a field like ours, you start to see 100x improvements overnight in a particular dimension of the problem. In this case, deployment time tends to be much, much, much faster. Application size ends up being much, much faster. Like I said, room for error as a result of this smaller granularity ends up being much better.

Nowadays, we have technologies like TypeScript that prevent a lot of human error, but I've seen a lot of times where one typo in one API endpoint, if that typo makes it into the container, then you would boot up the container and, boom, it's all broken. There is this idea that if you take advantage of the granularity, as I mentioned, you get all these nice properties; smaller payloads go the cloud.

What I like about all of this, and this is a great show to be on, is that we're mirroring what happened with the Web platform. This is a good segue into Next.js as well. The Web platform taught us that we have distinct URLs to distinct resources. The URL is a universal resource locator. Each of those resources can execute a code dynamically or serve something from a cache, from a CDN, et cetera.

Furthermore, when we respond, we want to only respond with what the customer needs. We want to give them a bundle that's practically reasonable in size so that you're not downloading things that you're never going to need like megabytes and megabytes of JavaScript, megabytes and megabytes of just CSS. This is what we're starting to see in the cloud as well is, when you are editing the equivalent of one page or one API endpoint, we're forcing the redeployment of the entirety of the server infrastructure and it's kind of pointless because the Web has this neat system that is already breaking things down into distinct entry points. This is what this entire system takes advantage of.

Chris: Dave, your CRUD example is interesting, though. It probably might be smart then to write four functions separately.

Guillermo: Yeah. Sometimes what we recommend is sometimes businesses think of objects, like you want to deal with invoices. Perhaps, you can handle your get and delete method and post method in the same function.

I'll give you a great example. A very nice practice of Rest is typically that, when you operate in an object, you still want to return it the way that it is now. If you post, you want to do almost like the equivalent of a get in the same transaction. Sometimes the code is so common anyways between different methods of the CRUD application that sometimes you do want to have one type of object and then different HTTP methods inside.

Typically, the advantage of serverless is that you can be very, very granular. It even helps with team organization. Teams can say, "Oh, this is my part of the app. If I make it slower and not making slower the other part of the app that someone else is in charge of." Serverless gives you this nice insight into how the application is evolving.

Chris: Yeah. That stuff will be interesting to shake out. Also, if it's a CRUD app, it needs to connect to some kind of data source. If I have six functions that I need to teach all six of them how to connect to the same data source, it seems like a little wasteful, although I'm sure there are interesting ways to handle that kind of problem.

Guillermo: Yeah. Like I said, what's interesting is that we've had that problem with React. The React committee ended up saying, "Oh, if five components need the same thing, let's use this common abstraction.

Chris: Imports.

Guillermo: Yeah, usually it's important and it's some functional primitive. We do see that we're all headed into this direction. React just changed everything to be functional and hooks are, in some ways, reminiscent of monads in some ways.

On the server side, we're seeing the same thing. It's like this function gets invoked and you need to get some data, so you need to connect to data vis, and then you have some side effect, and then you have to return some stuff. In the case of React, you return JSX. In the case of Node, you return an object that gets JSON serialized.

There is this amazing symmetry that we're already witnessing that is super inspiring to me because I can see how, by giving people these abstractions, we are enabling them. We're enabling anyone to be a React developer, but we're also enabling them to be a backend developer, only one monorepo that they deploy always within the same fashion.

Chris: That monorepo is a word we haven't touched on yet, but the idea there is, I have my CRUD functions, but I also need a website to show the invoices or whatever.

Guillermo: Correct. Correct. Yep.

Chris: I could have one repository that deal with all my functions or one repository per function, or something like that. I might even assume that that's what I need to do if I need to deploy them separately. You're saying that's not the case. I can put all of my functions and my website in one repository.

Guillermo: No because, like I said -- correct, and this is what we also found out in the React…. The jQuery way was, "Hey, let's granularly select a DOM element and change it." That's what would happen if you were, and said, "Hey, I'm going to go to my function. I'm going to change this function directly."

What React taught us is, "Hey, why don't you tell me exactly what you want in its entirety?" that's what we do for deployment. You run Now, or you get/push, and we deploy the entire repo.

Now the question is, "Okay, how is that not super slow?" It's the same with React. How is it not super slow? Later, you can do some optimizations. You can have caches. You can do deduping.

What mattes is what abstraction you're giving to the developer. Yeah, the average developer needs a front-end and a back-end. You can't make one work without the other, so we encourage people to model their interfaces as monorepos. You put your front-end code in one folder, for example, and your back-end code in another folder.

Sometimes people have several front-ends. You might have your back office and you may have your front-end and you may have your marketing website. This even allows you to experiment with different technologies like, say, "Now I'm going to try Vue for the marketing pages," or, "I want to use Next for my dashboard, and I want to use Gatsby for my front-end, but I want to have a common React component system that both folders share." That's where the beauty of the monorepo kind of starts to show.

Dave: That's interesting that you advocate for that because monorepo and monoliths tend to have this really negative connotation.

Guillermo: Yeah. Well, and it's a very heavily debated topic. Our take is monoliths -- okay, this is fact. Okay, no discussion here. Monoliths are incredibly successful.

Dave: [Laughter]

Guillermo: GitHub is a monolith. is a rest monolith.

Dave: Gmail.

Guillermo: is a rest monolith. A lot of things that work extremely well that you can go and Robin Hood and buy their stocks and they're hundred gazillion billion dollar companies, you go to their GitHub, or you go to their thing, and the backend is this gigantic thing.

Exhibit A, it works. But our argument is, all of the things that I said about servers where you fix one typo and you rebuild the entire thing and you move a gigantic container over, that's not what you want. But what I think made those companies really successful is that all their teams and all their API endpoints and all their front had this common vision of the world. When you onboard a new person into your team and you're like, "Okay, here is the project."

"Oh, it's just one folder. Oh, and you deployed it with literally three letters." Now, that's what you want.

A monolith is always a monorepo, but a monorepo doesn't have to be a monolith to be successful. A monorepo that has a React front-end and serverless functions and whatnot is the right way to build something today and it'll give you this feeling that you're operating on what DHH famously called the majestic monolith because it works so well for him. It's not only GitHub or Hubify; it's also Basecamp and numerous companies that have seen success with this.

[Banjo music]

Chris: This episode of ShopTalk Show was brought to you in part by Flywheel. It's, which is WordPress hosting. Perhaps you've heard of Local by Flywheel, which has kind of taken the local development environment for WordPress community by storm.

I feel like I used MAMP for ten years. It still exists and if you use it, that's fine. I'm not crapping on MAMP or anything, but Local by Flywheel, to me, blows any other choice out of the water.

For one, I kind of like little UIs. I like a UI for my Git. I like a UI for all kinds of stuff, not that I'm afraid of command line stuff. Sometimes it just like it, though.

Local by Flywheel is an app that sits in your doc on your Mac or it works for Windows too, which is relevant to us because are redesigning the ShopTalk Show website and I recently moved hosts for it too. That's the connection between these things. Of course, I run WordPress locally on my machine with Local by Flywheel. I spin up ShopTalkShow.local on my local machine to work on the WordPress site. Dave can work on it, too, because Local by Flywheel just spins right up on his Windows environment too, so now we're a team and we can work together.

Moving the site was so great because, right in Local, there's a button, "Connect to Flywheel." Boop. Connected. "Send it up to Flywheel." Boop. It's like two buttons and it shoots up our whole site to Flywheel hosting. You get a little subdomain. You can make sure it's all right. You map the DNS over to the Flywheel hosting and, boom, it's moved.

I feel like I was like, "Oh, I want to get this site over on Flywheel. I'll section off the morning to get this done. Hopefully, I can get pretty far. Maybe I'll get it done."

It's like 30 minutes later, it's done. I love that when you find this hosting product is so good, so easy to use, helps you with local development and live development. Plus, I'm in there, like, "Do you want to turn the CDN on, click CDN on? Click here. You want SSL on, click here."

It's this beautiful UI internally, and I started to demand that from my host too. I'm like, this is a paid software product. It should have a nice, clear, intuitive UI and, of course, it does.

Anyway, love Flywheel. Love Local by Flywheel. Love it all. It's great for us. We use it here on ShopTalk Show to power our WordPress site.

[Banjo music]

Chris: Let's morph into the Next stuff, if we could. Fans of React, as we may be here, React is kind of notorious for not giving you all that much out of the box, right? At this point, it doesn't even give you React DOM. You've got to grab that separately.

It certainly doesn't give you routing. It doesn't give you global state management. There's all kinds of stuff that it kind of doesn't give you, perhaps on purpose. One thing it definitely doesn't give you is routing, like I said, and any kind of server-side rendering kind of thing. That was a gap in the market. People want that, and Next was there for it, right? Am I right on there?

Guillermo: Yeah. Funny enough, all those examples that I mentioned are apps that use a lot of static websites but, primarily, are server rendered websites because, when you grow to a certain point, you need to query a database and a data source and respond dynamically. If you look at a project like create-react-app or a lot of projects where you run a build process, they typically are a monolith, so going back to the analogy. I'm not sure about Vue, but perhaps it is this way out of the box. When you use any of these projects, they yield one app.js file and one .app CSS file. That is the first thing we noticed. We said, "Oh, that seems like it's not going to scale."

You keep adding functionality. One day you say, "Hey, I'm going to add this super cool rich text editor." Then the app bundle is just going to get bigger and bigger and bigger and bigger. That app bundle and that monolithic, single page application is the "server" of the front-end world.

Next.js makes React serverless in the sense that what we have you do is you create a pages directory. Inside of the pages directory, you create all your entry points into your application, akin to serverless functions, so you create index.js, settings.js, about.js, all your pages.

Chris: Yeah.

Guillermo: All those pages are just functions that return React components.

Chris: It feels like server-side rendering that way in that each one of those pages is a folder called "About" with an index.html file.

Guillermo: Yeah. Correct, and in this case it's index.js and index.js returns a React tree. You can do server stuff, server rendering as well. You just create your directory. Another amazing thing that we hear a lot is that, when you have the monolithic, single page application design, it's hard for people to learn their way around the application, whereas with Next.js and Now, you open the application. You open the folder and you're like, "Oh, there's a pages directory." You're like, "Oh, these are all my public URLs."

We do a lot of automatic stuff for you as a result. We can do code splitting of bundles, so each of your pages becomes a bundle of code, like a JS bundle or a CSS bundle that is specific to that page, and it just scales very well. Here's a paradox. If you wanted to have a single page application, you would just create pages/index.js. You would put all your life there. But what we encourage you to do, and I think what happens very naturally, if you start creating one page per route that you have. Then we expose--

Chris: Does it hydrate into a SPA then or not really? What happens when you click from one page to the other?

Guillermo: Oh, that's a great question. We give you a component called Link that allows you to link between pages. The beautiful thing is that we load those pages kind of like how Turbolinks works.

Chris: Really? It's a Turbolinks approach? Oh, that's cool.

Guillermo: [Laughter] It's like a Turbolink, but it's actually a little bit more sophisticated.

Dave: I knew Turbolinks was a good idea, damn it! [Laughter]

Chris: I know! It's a great idea!

Guillermo: Guys, it's a frickin great idea!


Guillermo: All this stuff works really well! Again, we are doing a few touches that we think are a step forward. In this case, what we do is we prefetch, which I don't know if Turbolinks does, but Turbolinks cannot do this because, if they prefetch, they would be adding all this load to your database. What we do is we prefetch just the instructions for rendering. We prefetch just the skeleton of the React code, basically, but not the data. The data, actually, you can prefetch optionally because, if you want to have more load in your database but benefit your users, go for it.

When you have this link component that we give you, which in itself is optional as well, by the way. Next.js does not really get in your way. What's going to happen is we're going to prefetch the thing that we're linking to. Then when you click or when you interact with that hyperlink, we probably already have the page preloaded, so it feels exactly like a single page application, which is ultimately what the customers have always wanted. Who wants a slow loading website? Who wants page transitions to be slow, right?

Chris: No, but does it do history push date thing?

Guillermo: Yes.

Chris: It does?

Guillermo: That's managed by Next.js. What's neat about that is that we can do a lot of optimizations by having that power on the client side and we still have a very minimal runtime. It doesn't mean that Next is adding a lot of code or you, and it's very, very natural.

One of the things that we decided to do is, let's mimic the behavior of a Web browser exactly. When you click a link, we just replace the entire React tree of one page with the Next entire React tree. This a few things that, for example, customers can do once they have this power. They can retain state between page and page, so they can have caches. They can have local state. They can have pieces of JavaScript that have already been loaded that are very expensive.

Imagine CodePen, the text editor and syntax highlighting code and all that is super expensive. When we transition from page to page, we can keep as much stuff in memory as you want, which allows you to do all sorts of really neat things like transitions, page transitions, animations.

Chris: Oh, believe me; we're trying to get there. It's close. It's close. Don't worry.

Guillermo: Awesome.

Chris: That's great. The magic part to me is, like, okay, you have all these different entry points. There's an index.js and there's a product.js. Then you load index.js and enough time goes that it hydrates itself or whatever it does. I don't even know if you use that term.

Guillermo: We do.

Chris: Then you click onto a product page and enough JavaScript gets executed that it's going to behave in this SPA type of way.

Guillermo: Yeah.

Chris: But it needs new stuff because maybe there are some tabs on the product page, right? The first bundle didn't have the tabs in it, so it didn't download that or didn't need it.

Guillermo: Exactly. What's really neat is that when you went to index, which could be your marketing pages, right? Sometimes it's not even related to what you're going to do next. You only downloaded the bundle that is related to that section of your application.

Another great example is when you're in the dashboard, your admin panel, or however it is. Things tend to get pretty heavy. You start loading a lot of components, et cetera. You don't want these things to constantly be battling for the user's download bandwidth.

The main benefit is that when you enter--that example you gave--the product page, you're not downloading the terms of service. [Laughter] It's funny, but if you go to any SPA that has a page dedicated to terms of service and you're loading a critical section of your website, an e-commerce product that you want to sell, as your JS downloads, first of all, most likely, you're going to render a blank page because that's how most SPAs work. Then you're going to start loading some JavaScript. That JavaScript is going to contain even the terms of service. Then it's going to request data, and then it's going to render your product.

With Next.js, we go to the page. We already get all the prerendered information that we wanted, including all the product, its price, its stock, et cetera. Then when we download the JS bundle, we only get the JS that's needed for that page.

Chris: Sure. It's code splitting, but it's managed for you.

Guillermo: Yeah, and the code splitting is happening automatically because you're taking advantage of saying, "Hey, these are all my pages. There's not one global bundle." The developer doesn't have to go in there and say, "Hey, I'm going to code split here, I'm going to code split there, et cetera."

Dave: Per route code splitting is kind of difficult to set up yourself.

Chris: Yeah.

Dave: You can shove it into Webpack and it'll give you ten bundles if you want, but it's not necessarily per route.

Guillermo: Yep, absolutely. That's where you start seeing the similarity between serverless functions and server rendered React applications, like Next.js, because just like a serverless function is doing code splitting of your API, Next is doing code splitting of your pages, your public pages, your front-end pages. It's a beautiful system. It's very coherent.

Dave: Then is it like Next plus Now then gets me server side rendered serverless functions for my front-end code. It kind of all starts happening in concert. Is that right?

Guillermo: Yeah, correct. You model your monorepo with your Next application and your API endpoints. The nice thing is, again, Next just happens to be one really great candidate but, actually, we have great support for Nuxt as well, which is a Vue version of Next. There are a lot of interesting solutions to this problem, but I think what's interesting is, if you use this model, you'll start worrying a lot less about all the different aspects of putting together your application.

Dave: Not to throw React under the bus, but it has somewhat of a notorious performance concern. [Laughter] Google Chrome developers are very, very serious about its performance.

Guillermo: Yeah. Yeah.

Dave: Is that kind of the problem you set out to solve? Were you just like, "Let's fix performance"?

Guillermo: Yes. Absolutely. For example, if you're doing anything dynamic, you're never going to beat the experience of giving the customer, in the first hop, the information that they wanted. Next is sort of rendering, so it's giving you -- or prerendering as well. You can export a prerendered version of your app. You'll just get all your data in one go, and that's just HTML and CSS. There's basically no performance problem.

The performance problems of React tend to be when you're doing a lot of React. This process that you mention, Dave, that's called rehydration. When it rehydrates, this what CRUM developers tend to go nuts about is the time to interactive, TTI.

A React obligation our even an NJS page require that we prerender the server-rendered and then we load the code. Then that code attaches to all the event listeners and whatnot. Then it can do some interaction.

Next actually kind of solves this problem as well that React has because, remember that I mentioned that we have this link component, but all this link component is doing is using a regular anchor or HTML element. It's like a normal hyperlink. Even if the JS hasn't loaded, you can still click around and you're going to go to other pages, which themselves are prerendered or surrendered. When you go to them, it's all probably going to work a lot better than if you were to do it yourself. But what Chrome developers really pick on is, imagine that you're rendering a product page and you have a buy button. That buy button renders a modal. It has to load Stripe and then asks for your credit card details.

Chris: Yep.

Guillermo: That's all client-side JavaScript stuff. For that JavaScript to work, then you have to be mindful of how big is my bundle? In this case, because it's only per page, it's probably not bad thanks to Next. Thank you, Next. Or you have to be mindful of, okay, I opened the timeline and be like, "Okay, how long is React taking to rehydrate?" and so on and so forth.

One nice thing that I've observed with a lot of customers because this is used by, so if you just watched the "Fyre Festival" documentary, you've probably used Next.js. The key thing that all these customers have noticed is you kind of always want to have URLs because that's when the Web works best.

One thing I encourage is, if you're going to have a buy modal, so you press on the buy button and you render a modal, you can also attach a URL to that, so your URL can become--and if it happens in the client, it's going to be via a push state--it's going to become /products, /fyrefestival, /buy. Here's the really cool thing. Next.js kind of puts you into this paid success. You succeed or you succeed because, if you use the URL system, then you copy/paste that URL. You send it to a friend and that interaction is always going to work, even if it's a modal, because Next knows when it first loads, "Oh, the URL looks like this. Let's match it to this. Even if it's a modal or some complex interaction like that, it kind of all works very naturally, just like the original Web did.

Yeah, there are some performance problems that React has, but I would say that most of them, Next.js, because of its model, kind of prevents you from going into. That's where Chrome developers just generically say that all apps need some sort of budget or boundary to be very successful. I tend to agree with that because I've seen so many now where you launch your new application, it's super fast the first day, and then you kept adding stuff. You didn't quite measure the lighthouse every single day of your life. Then, six months later, all your bundles are bigger and it's not as fast anymore.

The other question that goes in there, which is why Google invented Amp, is like, okay, what are the right constraints to introduce so that you don't accidentally fall off the cliff? Even though we went into this success path, what can we do to make you not fail in terms of, "Oh, I accidentally brought in a huge dependency and now my JS bundle is ten megabytes"?

Chris: I saw a demo just the other day. I was at a local meetup here. It was Paul Armstrong, this developer, came and showed Next and just live coded, "Here's how we might build this little website in Next." It was really, really cool.

This is what the page did. It loaded up a little React app, but the React app's job was to go get a meetup from and say the name of the meetup and what it is. There was a little bit of data fetching it had to do.

It built it in Next and there was a URL for it and all that stuff. It was cool because then he ran the build and the build itself could go make that data request and then build the page out of it. The output of it was the actual HTML file that had the Next meetup data right in it. You're like, "This is actually SSR," and, beyond that, it's statically rendered too.

When I think of SSR, there's a version of SSR, which is like, "Ask the server for a page." The server might then go make the request for the data and, ultimately, return a page. That kind of SSR is cool, too, because you still get JavaScript. JavaScript doesn't have to do the rendering of the thing. You get that document and it can render it right away.

This is kind of both, right? It's server-side rendered and it'll hydrate itself.

Guillermo: Yeah, absolutely. We call that prerendering. To us, they're both the same technology. Think of it as lazily fetching data, right? You can fetch data when the customer hits your application or you can fetch the data ahead of time. It's also a little bit like ahead of time compilation or just in time compilation. It's ahead of time data fetching at build time or just in time data fetching upon request.

There are use cases for both. Some customers have very static data sets, so think of it as a meetup, like you said. You're building a very simple website for a meetup that you're going to host. You want to get some data dynamically, like your speakers or bios, and you're fine but, whenever data changes, you want to rebuild and recompute the whole thing. Your API backend can take the load of fetching all that data at build time.

There are a lot of customers that have gigantic data sets. Imagine that every time you build, you've requested. We have a customer that has hotels, so tens of thousands of hotels every time you build. It's impossible. It is possible. Everything is possible at, but it's not practical.

Next puts the developer in control, like if you want to, at build time, fetch all your data, do that. But we also give you the flexibility to say, "Oh, if my data set is larger, I can fetch it on demand.

Dave: That's smart. I think I am coming up to a hard stop here. Guillermo, you've been famously quoted here, at least in Twitter stream. "React is such a good idea that we will spend the rest of the decade continuing to explore its implications and applications." I'd love the two-minute version of what do you think some of those implications are how Reacted has changed the game?

Guillermo: It's funny because I tweeted that in 2016. I don't credit myself with being a super, super early adopter of React. I would say I was the second wave, and the first wave is a lot of people that were doing SPAs with things like Ember or technologies that, at the time, didn't have quite the React model.

I was still a pretty early adopter. I wrote this article called Pure UI where I anticipated, in a way, that we were going to focus more on functions. I remember that Sabastian, today the lead maintainer or one of the lead maintainers of React, and I lived very nearby in San Francisco. One time, we ran into each other at a café. I was telling him, "I'm writing this article. I don't really want to use a class interface. Why do we have classes?" [Laughter]

Of course, it took a long time to take the classes out. It was very difficult. I didn't even know how to do that, but I had this sort of intuition, and that's why the article is called Pure UI. It's kind of a pun on that; you should focus purely on your UI. Just focus on the UI. But also, that you could use pure functions.

When you go and read that article, again you'll see that I really restrained myself from using classes when providing the examples at the expense of a lot of trouble at design because I think, at the time, React didn't even have stateless functions. But I really wanted to see that idea through that you could have a path of data output UI. That was the idea that I fell in love with.

Why do I think that the implications are massive? First of all, it's a switch from … programming, an imperative style of programming to declarative or functional. I think we have a few cycles into this idea, still. I think you've seen hooks, right? You've seen this idea of well-delineated effects. Segregating the effect and the declaration of the effect from the pure part of your application, I think that needs further elaboration. I think that is a very great direction, and I think we need to go all in on that and continue to explore that.

I think another set of implications is what's going to happen to React and React Native. Even the fact that you have to explain to people that there is React, but there is also React Native, and then you have to explain the difference between what native is and what not native is, which is also in itself incredibly blurry, let's not forget that a lot of the applications that we use on a daily basis, we could not have told ten years ago if we launched them today. You launch an electronic app, and electronic apps have a lot of problems, but they do their job very well with certain downsides. Most people would never be able to say, "Oh, yeah, this is a co-co-native-whatever." No, it just works.

I always tend to look at things as I'm the end user. I'm an 80-year-old man. I lost all the React waves. I didn't go to Hacker News ever. All I care about is the end user experience. As an end user, I want cohesive experiences, a cohesive design system between the mobile app, desktop app, and a Web app. I want the information to be there. I want all the features to be there.

The most common customer frustration is, "Oh, I love your responsive website." Sorry, "I want your mobile-optimized website, but it doesn't have this feature. I had to switch to desktop mode. Then I had to shrink in and I can't even tap." I think we need to do further development and research into this. Expo and the React Native team are very focused on solving this problem. I'm very excited about that as well.

I think the other thing that's going to always keep us on our toes is that this model works really well, but there is always a point where fear emits practice, right? The model might make you a little bit slower, and you need an escape hatch, or further concurrency models need to be put inside React, like is happening now.

I think what's also going to happen is the technologies that we deployed React to are also changing, so we're moving into serverless now. React has to boot in completely different circumstances. It's still a V8 and it's still a Node, but there is a lot of optimization to be there because now we have this better model for splitting concurrency into this discrete request. I think the server runtime is going to change significantly.

You might think of React in the future as the runtime. You're starting to see that React has its own language semantics, even. Hooks have rules of hooks. React, for better or for worse, invented JSX. For me, it's for the better. That's not inside JavaScript.

I think the server runtime, it's almost like you're really just thinking of the server runtime as React. The Node part is interesting that it's there, but you're not going to be using Express as much. Like I said, you just think of this beautiful world of just writing your pages. You don't think about, "Oh, I'm going to boot up. I'm going to write an Express app," and whatnot.

With Next, we're trying to define what this ideal React app is, really, in its true sense, a full React app. Yeah and, like I said, I see every day there is this Inc. project that brings a React modal to the terminal. I kind of anticipated that, as well, a few years ago. But now it's been done so well by someone in the community. Unfortunately, I'm blanking on his name, but he did such a great job.

The React modal is so good at handling asynchronous data fetching and so on that, with this Inc. project, you can now express very sophisticated command line interfaces with very little code and a lot of simplicity. The Jest output is one of their examples with progress bars and a layout system in the terminal, so we're going to see React in a lot of places, I think. Yeah, it's going to be a lot of fun.

Dave: I have to wrap up. I have to leave, but you all can keep talking, I guess. [Laughter]

Thank you so much, Guillermo, for coming on the show. I know your schedule is very jampacked, so we really appreciate it. For those who aren't following you and giving you money, how can they do that?

Guillermo: Yeah, so to follow up, go to I think that's a really great starting point to learn about every project, follow all of us that work there. Our pinned tweet usually contains the most up-to-date information about us. Yeah, @zeithq on Twitter.

Dave: Awesome. Thank you very much. Thank you, dear listener, for downloading this in your podcatcher of choice. Be sure to star, heart, favorite it up. That's how people find out about the show. Follow us on Twitter, @ShopTalkShow, for tons of tweets a month.

If you hate your job, head over to and get a brand new one because people want to hire people like you. Chris, do you have anything else you'd like to say?

Chris: Oh,