Guillermo Rauch the future of NextJS, JAMStack, Vercel, edge networks, & eventually consistent state

In this interview, Guillermo Rauch, CEO and co‑founder of Vercel and co‑creator of Next.js, walks through the origins, philosophy, and evolution of Next.js and the broader Jamstack ecosystem. He explains how Next.js was born from internal tooling needs, its opinionated approach to routing, CSS, and data fetching, and how it differentiates from Create React App and Gatsby. Rauch discusses React’s rapid evolution—hooks, Suspense, React Refresh—and how these features enable a more declarative, reactive model. He delves into the static‑vs‑dynamic rendering debate, introducing concepts like eventual consistency, static hoisting, incremental static regeneration, and background revalidation, emphasizing performance and availability trade‑offs. The conversation covers Vercel’s edge network, pre‑loading, low‑JS strategies, automatic code‑splitting, and the SWR library’s stale‑while‑revalidate data fetching model. Rauch also shares thoughts on design systems, the relationship between design tools and code, the limits of bundling, and the importance of CSS as a performant primitive. He critiques heavy infrastructure‑as‑code approaches, advocating for “infrastructure as no‑code” and trusting edge platforms. Looking ahead, he predicts the web will increasingly replace native apps, with Next.js powering progressive web apps and hybrid native/web experiences. Finally, he offers career advice, encouraging developers to publish work, use the Next.js learning resources, and adopt habits like #100DaysOfCode to build a portfolio and contribute to open source.
Chapters
Welcome to another episode of Work in Programming. This week I am with Guillermo Rauch. Guillermo, thank you so much for joining me. Would you mind giving a quick introduction?
Sure. I'm the CEO and co-founder of Vercel, and I'm the co-creator of Next.js, which is our open source framework for building and deploying Jamstack websites and applications.
Yeah, and Next.js is obviously— I would say it seems like it's the number one framework for building React applications now. At my work, we do a little bit of Gatsby work now for Jamstack as well, but Next.js is definitely— it seems like it's kind of taken over because of the whole serverless capabilities and being able to do dynamic data as well. So—
Yeah, the React space is obviously as a whole growing really, really fast. We've been lucky to really have been one of the first frameworks that was strongly opinionated on this idea of frameworks should give you all these basics like routing built in, CSS built in, data fetching built in. Another interesting thing that we did that I think has helped a lot is multiple pages built in. Funny enough, the very own Create React App, which kind of came out at about the same time that we were about to get Next.js out, with the substantial difference that we had already been dogfooding Next.js for a year. By the time we put it out. So even Create React App had this idea of like, oh, it's a single page and that's it, right? And like, we had this need of like, funny enough, I always tell the stories like, well, we had this need of two pages. And the example is we had our terms of service and literally this is how our startup started. We had three pages, homepage, enter your email to be notified of what we're going to be working on. And then we had the privacy policy and the terms of service. We're taking user data, we have to have it. Even though it's just an email, right? And I was like, wow, all this information, all these static pages are now going into the bundle that Webpack is outputting. And when Create React App came out, imagine that you're working on a thing, right? You see the very authors of this React component that is so, you know, that's so important to you and to your creation and you see them put out a quote-unquote competitor to your idea, well, you'd probably be at the very least, you know, a little shocked, worried, say, "Oh, is that it? I wasted all this, you know, I wasted this entire year working on this." But for us it was the opposite. It was like, "Oh, wow." "They're putting it out and we actually disagree strongly on this, this and that. And we thought we already lived through this. We already tried to have that bootstrapping mechanism that it was featuring at the time. Oh, we already tried and discarded that and not because it's bad, but like, oh, we kept working on our product and so on and iterating with the framework and we found that, oh, you can do more and you can do more and you can do more." So what we did is at that point, I told one of my co-founders, Yuki, it's like, "Hey, let's just take this stuff that we've been using internally and productize it." And that's how Next.js was born. And it was featuring all these ideas that really resonated with people that were working on products that needed these things to be built in. They didn't want to go shopping for options. They didn't want to shop for a router. They wanted to shop for a CSS solution and so on and so forth. Yeah. And yeah, I think that's kind of been our advantage is we got obsessed with this idea of React should power the entirety of the product and website that we're creating. And we kind of had a little bit of a head start and then we had some strong opinions and it's worked out really well so far.
Yeah, yeah. It's amazing that, it's kind of funny that, it's really funny that you launched right around the same time as Create React App.
Yeah.
I remember, 'cause to me, one of the most amazing things about React when it came out was that it wasn't one of these frameworks that, forced you to totally do everything their way, and you could kind of pick and choose your favorite technologies for each thing. But then it's exactly like you're saying, it's, it's the, the first like week to two weeks of any project is like picking your framework and setting it up and reassembling the same pieces over and over again.
And also, it fit— React at the time fit the narrative of the time, right? Like Facebook was also going through their own incremental adoption of the technology. I was sharing this with my team the other day. It's interesting to think that no technology gets a free pass. It always has to be evaluated, marketed, presented pros and cons. And at the time, React was going through that process. Of course, it already had sufficient buy-in that they were motivated to open source it because they have high standards and they wanted to promote a tool that they liked. But it was still going through that process of like, how far can this React thing go? And I remember for me, a decisive moment was, oh wow, Instagram.com, which launched on web, is entirely powered by this thing. So the trajectory was, React, of course, was a V in MVC at the time and it was powering very specific components and some were still, you know, for Facebook in the legacy stack and some, the new ones were creating as React. It was going through that trajectory but where we leapfrogged was, well, yes, that makes sense for that kind of incremental adoption for Facebook and I'm sure also for incremental adoption within, you know, you had a WordPress website and you wanted to add some cool reactive component, like drop React in. But then we're looking ahead, it's like, yeah, but sure, why don't you start with the assumption of React from the get-go? And that's why we kind of started working on Next. And our vision was components are such an amazing primitive and abstraction that it doesn't matter what you're building, you probably want to build it with React, right? I remember one of my popular tweets at the time was like, "It seems to me that we haven't heard about the end of React nor even the beginning of React yet because there's so many more places where this component abstraction will make a lot of sense." And that kind of predated React VR existing, Ink, which is a project for using React on the command line. There's so many places that you can put it because fundamentally it was a leapfrog in the programming model. And that's what I think makes it so strong because the component is just how people think. I've also said React is the Lego for adults. And it is good to think of the world that way. We've seen the co-evolution of React with design systems. They've kind of gone hand in hand. With the ability to do the work once and then componentize it and then distribute it. When Hooks first came out, I got really excited because I could, I kind of, for me, that was the moment where I foresaw that, well, now we can componentize data and functionality in a way that we couldn't before, right? Like Mixins had failed. Copying and pasting onto a component class prototype doesn't quite do it. So how do you get a hook for data fetching or a hook that encapsulates a behavior like subscribing to certain events? And that to me was another really, really massive win for React. Oh, another Lego bricks for behavior. And the other day even, I found this interesting company that provides a gateway for blockchain and they were distributing their API as React hooks. So that kind of confirmation was like, wow, think about 10 years ago, you were presenting your new idea to the world and your hello world could have been curl and here's the API. And that was certainly true for companies like Stripe. Now you're presenting some cool data binding or data solution or API layer and whatever, and the abstraction has been risen. So now you can talk about, oh, here's my hook that does this thing. If Firebase came out today, they would be selling you on, here's the hook, right? For subscribing to data changes.
Right, and then I guess at that point, you could kind of connect to any API and It looks almost exactly the same. I mean, you just get your data back and you might have some broadcast events or another handler.
Totally. And what I like about hooks too is that they almost look like imperative data fetching code, like A equals get B and then use it immediately. But that hook is reentrant. So actually it's not even a one-off function call. It's a function call that then gets re-executed in the future if the data changed. So now we're approaching the time where React has actually completed a vision and implementation that live up to their name. Now React truly is more reactive in a way, which is fascinating.
Yeah, it's really interesting how it's kind of evolved over time because I remember when it came out with mixins, everything was kind of just implied. So you'd add a mixin and you just get some sort of behavior and you kind of guess as to where it came from.
Totally. What is this gonna do? It merges this mixin, and what are the consequences of that?
And then it's almost taken the complete opposite approach. Now it's gone, it went from that to lifecycles on a class, and then now it's like, screw lifecycles, we've got a, we're gonna subscribe to some data, and we're just gonna render out whenever it changes.
Yeah, yeah. And there's a story of React really evolving so fast based on very interesting product requirements that Facebook had and a lot of other people from the community had that it almost feels like React is moving faster than the language can keep up, right? If you think about hooks, well, hooks are doing exactly what's necessary for that abstraction and yet the language in some ways fights against it and there's like now, you know, rules of hooks. So React in its own has always been so product-centric and so like, let's create cool things-centric that, you know, first of all, JSX was not part of the language. It got added in. Now hooks, well, they're just function calls.
Yeah.
But you know, they bend the language in this way, another way. Suspense is the same, like it throws promises. Who does that, right? And all these things come from like, well, it turns out that people don't like to see pages flickering in 20 different ways and see 100 spinners. And in fact, by the way, the spinners also take up resources and so do the skeletons. Like why not coalesce all this async I/O? And then they were like, okay, how do we do this? Oh, like you second on the front row, raise your hand. Throw a promise, okay, let's do that. You know what I mean? It's more like, it's a very interesting product-focused idea and ideation. And I've always been a really big fan of that. Honestly, I think that's what keeps React so interesting and relevant to people. And as well as Next.js. Today, we're wrapping up a release and I'm gonna share it because I think by this time the podcast will be out. Which we're incorporating React Refresh. And to my knowledge, this is the first framework that outside of Facebook, because Facebook has it internally, it's React's ability to do hot module replacement in basically real time as you edit your code. But also it retains the state so you can use it to refresh code while working on complex flows, multi-stage forms, all kinds of client-side state, navigation, animation. And one of the things, this is an invention that is now possible after React aligned all these ducks of hooks and how do we manage the state. And how do we manage components? Now this becomes possible, making the developer experience so good that your edits feel like they're reflecting in real time. So in some ways, this is what keeps React so relevant is that it's been a few years now and still we're working on just cutting-edge capabilities both for developers and users.
Yeah, it's interesting. It's almost like every time I talk to somebody new, I learn something new about React. Absolutely, same for me. Yeah, it's amazing. There's just so many new developments all coming at the same time.
Yeah, work— Oh, sorry.
One of the questions that someone from my work actually wanted me to bring up was kind of around Next.js, the move towards having static pages, and kind of, they're curious about like, well, like, what's the intent? What's the long-term goal for Next.js? Is it kind of moving into all of those spaces, or is it going to kind of stick with dynamic data? I guess the static data gives it a— static pages kind of gives it a great competition against Gatsby in a way, I guess.
Yeah. Our take on it is there are two types of pages that you build. One type of page that fits the model of eventual consistency, meaning that when you make a read, it's okay to be slightly behind if you're going to get performance and availability benefits. I don't want to get too much into distributed systems. Nerd-dom, but basically this is the result that Amazon and many other pioneers in large-scale distributed systems came to the conclusion of. And this model of you can be slightly behind fits a number of domains extremely well, like marketing pages, e-commerce, blogs and so on and so forth. In a way, to me, static is an optimization. If a page can be made static, it should be made static because now we can make copies of that page throughout the world more efficiently. I recently wrote a blog post in which I call this static hoisting. It means if Next.js knows what parts of your project, what pages are static, we can put them by your visitor ahead of time. So I don't think anyone in the world would want to miss out on an optimization like this, which is just fantastic. And what, what Next.js is giving you is now the ability to decide on a per-page basis how much of that data you want to inline in the page and convert into markup, right? So our very own website, Vercel.com, it's all static pages with different levels of client-side dynamism baked in. So for example, Vercel.com/blog uses the static data fetching hooks, which are getStaticProps and getStaticPaths, to get data at build time. Now, Next.js is already going in the territory of incremental static site generation.
Yeah.
So we already exposed the hooks for you to add more pages later on and also revalidate pages that already exist, which is quite fascinating because if your data changes Again, the edge already has the previous version so everything is fine until it receives— until the new one has been created correctly, right? And that provides also— that's why I make always the distinction between performance and availability. Well, certainly if you can make a page static and push it to the edge, it's going to be closer to the user and the edge is not going to have to travel to origin to retrieve the page. No one would agree considering the speed of light that that's not a performance benefit. But in terms of availability, it's also a benefit because of that eventual consistency trade-off that I just mentioned, right? Let's say that at this very given time, I update the stock of a product and say, "Well, it's now out of stock." I have to now produce a page, generate it, and distribute it to every edge. If meanwhile traffic is coming to the page, I want to serve the page. I don't want to go to the brain origin database just to exactly at that given time block all rendering, render a white page until we get the very, very latest version of the data. And what Jamstack allows, which is quite fascinating, is that if you do have to make what I call strongly consistent reads, and obviously I don't just call it that, but in distributed systems, if you need to read the very, very, very latest version of data and know edge caching could ever be afforded, what you do is now you transfer that to client-side JS data fetching calls with, for example, React hooks. So that gives it quite a pretty compelling model, right? So the vast majority of your pages exist at the edge, they get downloaded instantly, and then you can also attach to them magical JS code that can do more, register events and so on. And that kind of completes this vision of what I call React at the edge. Most of the markup can already be pre-generated and then React can kick in on the client side to do the last mile improvements on the page. And how do you—
Sorry, just a quick— So when you're rendering, let's say you want some static data but you want to refresh it. How do you prevent, say, the blog from rendering and then flickering and then loading completely new data?
Oh, we always render a consistent version of the page, right? So if we don't have the JS and the HTML of that page yet, we render the previous version, right? So when I speak of revalidating a page, I mean both things. One thing that we're working on right now that is pretty exciting is We're going to let CMS providers or any developer that has any data fetching system to basically identify which pages are linked because they're both representing the same, let's call it, datum. So let's say that you have your blog index and a certain blog page that both have, are rendering both the same blog post, right? We're going to let you, and this will probably be abstracted away with with data fetching utilities in the future, but we're gonna basically let you push both pages at once or none so that you can avoid basically parts of your website being revalidated by other parts not being revalidated.
Interesting. And then I guess you— so if you don't get both of them, then you would render out the old version of both?
Correct. And this is very— and again, the trade-off there can also be left up to the developer. This is very similar to how CDNs work that expose what's called surrogate keys where different parts of the cache can be invalidated by issuing an invalidation against that key. But what we found is, you know, frontend developers don't want to think about in terms of like, "Oh, there's a CDN and there's caching headers and there's this and that." It's much simpler to think about, "Well, I'm doing data fetching for this page and as a result, it's almost like I'm subscribed." to any data piece of this page is changing and then being able to revalidate those pages later on. So right now Next.js already has support and we put out an RFC that we have some great comments from the community for what we call background revalidation, which means when you visit a page, it's always served from cache and then in the background, we check if that page has changed.
So—
Interesting. What this does for a lot of people and we have lots of production customers using it, is it allows them to basically adopt Jamstack for very, very large-scale websites today. They don't have to wait for CMSs to expose webhooks and all this code to be written and so on. We use that also for Vercel.com. It's been really great. So basically you arrive to a static page and then in the background it's like, oh, let's try to generate it again. We only do it at most once, which means it's very, very cheap on the backend. And then if that page generation yields different HTML, we update the edge. So people that would wait sometimes 40 minutes for a build to yield all the static pages at once are now seeing that it takes 100 milliseconds to update a static page.
And I guess these incremental builds, they're not so much controlled. So for instance, if I'm using a Gatsby site, I know that they're working on incremental builds now, but if I were to try and render out the site with just standard Gatsby, I'm rendering out all of the static pages and then I'm pushing those to the CDN and then those have to revalidate. I'm guessing with Next, when you're doing this, is it dynamically happening at the server side? Correct. Or is it happening at rebuild?
Correct. Okay. So, it happens at build time for the number of pages that you want to generate. And this is where it also is important to draw a distinction here, right? If you have tens of millions of pages or products, you might not really want to build every single one of them, every deploy preview or every— maybe you want to do it for production, right? Maybe not. So Next.js already, and this is in production, already gives you the ability to say via the getStaticPaths function how many of them you want to do eagerly. So really what Next.js is doing is doing this dance between eager and lazy and having the developer have a voice or choice in which one to use and how, right? We think that it very much depends on the size of the website. It depends on like, you know, what affordances your data backends have, right? Because eager only works if your data backend supports hooks or streaming and so on. But that's not the reality for everybody. At the same time, we are going to a world where we know that all these data pipelines will be connected and then we can sort of perfectly know when each page has to be rebuilt. But in the meantime, it's nice to have a fallback, right? Also notoriously, in a lot of cases, events get lost. So it's nice that Next.js gives you this kind of sanity check and says, well, Every 5 seconds, if the page is being visited, we can try recomputing it in the background and see if it's changed. So if you compare that to SSR, you're thinking this is like 100 times cheaper and yet I have all the benefits of, I don't have to reinvent the wheel. I can think about data fetching the way that I always think about it and yeah, this is kind of giving the developer was using Next.js in the past and thought of it as, oh, it can only do SSR. Well, no, actually now you can do static and you can do incremental static. So it's a very nice kind of set of functionality that they have.
Yeah, it's very cool because I guess I've always thought of Next.js as the dynamic version, so the server-side rendering version of anything else, but I guess being able to do both at the same time is kind of Yeah, another great example that I always give people is like, why would you want your company's homepage to not be static?
Why would you put a server in between? Even if you're using the fanciest CDN you could buy on the market, why would you make that CDN make a trip to origin to fetch, you know, welcome to my company? And this is kind of what I was saying about like, I use the expression push to the edge a lot. If we know it's static, we can make so many awesome optimizations that, again, reflect later on through the lifecycle of your software being live and in production in just better performance and better availability. I think it's kind of this, as I mentioned, nature of the universe of there's different types of data, there's different types of pages. So what really played to our advantage was again, that multi-page system, right? So Next.js can now say, oh, this page has no data requirements whatsoever. So when you run next build, we just spit out HTML for that page. Then you can say, well, this other page needs data to be inlined at build time. So when you run next build, We get the data and then we spit out HTML. And now when you use a hosting provider like Vercel, Vercel doesn't have to consider that Next.js is like inside a black box. It can take these outputs and place them ahead of time where they belong and where it's most beneficial for, for your visitors.
And would you say that Vercel is heavily optimized towards Next.js? Or— because I noticed that it does— I mean, it hosts like Gatsby, and I actually have a Gatsby site that I'm working on that's currently hosted on Vercel and it seems to work very well.
I find Next.js to be, and I'm biased obviously, but I find Next.js to be a pioneering framework in a lot of ways. It's giving people features that are quite innovative. But my thing has always been like, I want to make sure that other frameworks can benefit from those. So we're actually working with the Nuxt team right now and Obviously, I haven't contributed that much, but every once in a while, I tell them, "Oh, we're doing this, we're doing that. Oh, you have a Functions API coming, that's really cool," etc., etc. And I love that because these ideas are more of— you can think of them as low-level ideas, right? We're talking about producing HTML, right? And putting it next to the visitor. Does it really matter? What framework is doing that. I think that over long periods of time, it doesn't. We want to be ready for that future. We want Next.js to continue to sort of be pioneering and give customers all these really innovative options and optimizations. But, you know, I could see a future where once things become more stable with regards to like, you know, what is the features that defines a modern framework? Next.js is a feature set that right now is being implemented by Nuxt. They don't quite have it yet. Once things are more— you're gonna see that all frameworks sort of catch up at one point. And they're all gonna offer you pretty much the same things. Even React, if you look at the React repo today, they're adding first-class data fetching functions to React itself. So things will become more normalized over time. And we want Vercel to sort of be this pioneering edge network that is ready for this new breed of, frankly, I call it Jamstack frameworks. Because the distinction to be made between an old school framework whose output was a process that lives inside a container, well, to me what defines a Jamstack framework is that now the output is HTML JS and functions. And those can be very, very much optimized for edge delivery. And that's kind of the big kind of wave that we're going to see. We're going to see new frameworks come in like Redwood, Blitz, and all these newcomers that are exploiting these new categories of optimizations that weren't possible before.
Yeah, it's interesting. I can see. So do you think that there are sites that would not benefit from being built in Next.js?
I always turn the question around to people because I'm like, why, like I said earlier, why wouldn't your company's homepage be a static page that is globally replicated rather than your static page living inside a container, living inside a process, being constrained from that process in time? And then remembering to set the cache control correctly. And so yeah, even S3 acts as that server that CloudFront connects to. So even though S3 is highly available, there are very interesting optimizations that can be made in terms of your bucket existing in multiple places of the world. And they're certainly possible. If you spend enough time with AWS primitives, you'll of course get to the same outcome. The question is, do you really want to? I spend all the time working with those primitives. But yeah, to answer your question quite directly, I think we've always thought of Next.js as this super versatile framework for building pages. That's why our trademark is you start by having a pages directory and throwing in React components inside and each page maps to a URL. I joke sometimes that we're not building a path in terms of platform as a service, I always joke we're building pages as a service. Just a new type of path. So if it fits the definition of a webpage, you know, we'll be there. As I mentioned earlier, I think components and React just fit my personal mental model of the world and how to combine things and make things reusable and so on. It's kind of like, just the building blocks of modern software. So that's why we work on Next.js. We enjoy using it every day and we highly recommend it.
Cool, yeah. Yeah, I guess in a way, you're just kind of bundling together best practices. I mean, I could work on a Create React App application and build a single page app, but I could also just take that single page application and put it into Next.js and still benefit.
Totally. Yeah, that's how the kind of architecture that we follow for our very own website. So like slash is our homepage, slash dashboard is fundamentally a single page application, right? And what that's allowed us to do is that we have the— now it's coming back in vogue, we have a monolith, quote unquote, right? And I always say quote unquote because The build process breaks down that monolith into these independently optimizable outputs, right? So it's the opposite of a monolith. It's a super mega distributed, globe, worldwide edge network mega not monolith. But, okay, you start working for Vercel tomorrow, you go to one repo and you run Next Dev. You run Yarn Dev. So to you— that you have the entirety of Vercel at your fingertips, right? You can work on the design system, you can work on the blog, you can work on a marketing page, you can work on the contact form, you can work on the sales form, you can work on case studies, you can work on the dashboard, you can work on the logging system, you can work on the billing system. It's a very, very nice way of working. And my take there is when you have a customer of your own business or even of your own blog, They go to company.com and they don't care that, you know, you, the architect, decided that, well, this system is create-react-app and this other system is this and this other system is that. No, they end up having this like— what I find at least, they have this like disjointed experiences, almost like you're putting out 3 products. But if you go and ask your customer, they think of your company as one thing. Oh, that's ProductA.com. Oh, now I'm logged in. Oh, now I'm not logged in anymore. Oh, and like the buttons have changed. Oh, I guess they're working on a new redesign. And that's why Next.js was designed from the get-go with this kind of— it looks like a monolith. And I see it really just like, it really makes teams more productive. That's always been my observation. It gives people a global view of what they're working on, even though everyone develops their own specializations over time. Just having that awareness of what people are working on. And that very much mimics the way that Facebook worked before they open-sourced React. So it's always been good to have the model of the originating company of the framework to follow.
Yeah, I guess it benefits especially since they definitely did end up acquiring a lot of talent just based on the fact that people can kind of work across teams and they can kind of access—
I'm a big fan of that. I'm a really big fan. There's this tweet by Sophie from— she was the ex-manager of the React team where she's like, if you have the skill sets to work on a website, You probably have the skills to work on everything else, you know, as long as you have curiosity and the desire to get involved and learn. And I've seen that come true so many times where like, we're seeing it a lot with— and I wrote about this in an essay that kind of became viral called Pure UI— we're seeing that too with like product design, design and development becoming skills that are more and more closer together than ever been where, you know, a lot of designers today just wanna be involved even with understanding how the implementation happens and, oh, I'm designing this component in Figma and it's gonna match this component in React. And having that understanding, it's just, you know, again, it's this global understanding of how the thing works and how it's gonna end up in the end user's screen.
Yeah, I mean, it seems really interesting. Like, if you've heard of like Framer X, for instance, there's this big— there's this idea, at least, of, you know, a designer should be able to create a repository— or sorry, like a design, and then they have their individual components kind of set up. And then in theory, you could just kind of export that from Figma or whatever your design tool is.
And absolutely.
Do you have a— do you have— do you believe that like eventually we'll get to the point where, let's say, your design system lives inside of some sort of design tool, but if you update those assets or if you update the content or however you manage that, that gets immediately reflected on the front end and rebuilt? Or do you think—
I think so. And it's going to take a while. I think teams that buy into those systems from the get-go will have that ability much sooner because there's already systems that do this, right? So there are people that are hearing this and like, oh, I already got that because we already have the early innings of those systems. I think a lot of it, one thing I'm particularly excited about is like, and this is kind of controversial, but I'm pretty excited about CSS. Okay. I think, you know, like, and just like regular CSS, I think it's a fantastic technology. A lot of people don't like it because it doesn't have power, it doesn't have a type system and so on. But that's the point to me. It's like, it's why I like static outputs. The static outputs are optimizable. CSS is very optimizable. The fact that CSS is not like Turing complete is great. And similarly, another thing that I find is that CSS is really good at giving the developer the ability to tune things that the platform already provides in some way. Right? So like, when you rebuild a select widget from scratch with React, you're subscribing to a world of pain and you're subscribing your user to a world of pain. And the pain has to deal with lots of code, mismatched keyboard shortcuts across platforms, Accessibility problems of all kinds and so on and so forth. So the better option turns out to be don't do it. So just use the platform primitive and guess what? You can use this super optimal styling system CSS to customize that. So now if you kind of make that the invariant that all you're gonna be doing is customizing things with CSS, I think you end up with a system that could realistically be quite easy to implement because you're already using the very own browser's primitives to do all the rendering and styling and people are just manipulating basic CSS, which is actually a really easy to pick up, very fast and fluent language. Now, the other thing that I'll say that is also a bit controversial at least from some people that I've spoken to, is that I think that nothing will ever replace unstructured creativity and ideation. And I actually prefer design tools that have no rules or understanding of layout whatsoever, because I've opened files on Sketch or Figma that feel like I'm interacting with a programming language. If I'm interacting with a programming language, I'm just gonna go to what I just described. I'm just gonna go to like edit HTML and CSS, right? I know how to do it. I can open a web browser and do it. And I'm not even gonna open a design tool that is not implemented as a part of a web browser because the web browser will always have, you know, no impedance mismatch between output and design. But I like the idea of just really fast ideation and moving the elements like I'm, you know, on a whiteboard. And that's what I see, you know, some part of that will have to be retained. And I think that if you're too much in the camp that there's perfect synchrony between code and design, well then design will slow down. Yeah. And the two things have to exist for successful product design. You have to have the liberty of no code and then you have to have the strict requirements and constraints of code. It's kind of like just different modes of thinking, right? Like you sometimes want to be super creative and like, you know, let the entire universe merge into a rainbow of sound and color. And sometimes you just want to be like, "Oh, okay, let's sit down. Let's look at the bundle size. Let's look at, you know, how many DOM nodes we have nested," and so on and so forth. So it's, to me at least, it's different kinds of thinking.
Yeah, yeah, I can see what you mean there, especially with like a lot of design tools. You know, say Figma, for instance, there's a lot of flexibility there. And I guess if you tried to just directly export that to the strictness of a web page, you wouldn't really benefit that much. Absolutely.
Absolutely. Yeah. It's not going to work. Or even if you do make it work, then what you've done is then you've turned Figma into the coding tool. And then if you turn Figma into the coding tool, then you lost the unconstrained creativity. So maybe it's just, you know, like this is a danger, right? It's like you have to decide, well, what mode am I in right now? And if it's the same tool, you can get into trouble, right? Like modes are quite difficult to grok sometimes, like as exhibited by people not being able to exit Vim.
That's very true. Yeah, I think that it's kind of like the same issue that people kind of have when they start hearing about design systems. I have a few friends that are designers for, say, a bank or a telecom company, and they had this idea that, okay, obviously they're going to bring in design systems because everyone wants to be able to normalize across all of their platforms and all their sites and keep everything consistent. But the immediate assumption is like, that's going to limit creativity because all of a sudden designers are forced to fit in with a system and kind of stick with it. But I've also heard the opposite from design managers who are running these teams. And they're saying, we have a design system, we can do pretty much anything we want, and we're almost certain that it's going to work out. So it's kind of like—
It's super tricky, right? You have to find the balance between how fast you can move with the existing primitives, but also moving fast with primitives that don't exist. So that ends up being a matter of retaining that freedom to constantly revisit assumptions, right? And not make these processes too rigid. And that's why I was mentioning that if you make the design tool too rigid, then you can get into trouble because the design tool has famously been the place where you weren't constrained by any of those rules that have been imposed by PR review and guidelines and design systems. And a great example of this is that things that cannot be done with the current system, right? Like things that like, oh, you want that flyout animation, blah blah. Like if you just always— your starting point is the constraints of the code of the existing system, then nothing is possible. Now, if you kind of divide those two minds of like, well, this is what I want, you know, let's work and find a way to do it, right? Like, uh, it's kind of— it reminds me a little bit about like some of the things that Apple has accomplished with some of their innovations in UI where those are not things that you can use any tool to describe. You know, like the new cursor thing on the iPad. I could imagine even a conversation happening where like, "Oh, what if we just make it like smoosh and squish like this?" You don't even have the words to explain it. And that's the thing, I do think that sometimes you want to have that kind of liberty to kind of push the boundaries. On the other hand, I always recommend design systems to people because when you're giving the developer too much or you're giving yourself even too much freedom to always reimplement, then you end up with inconsistent design or really bad accessibility issues. And this is a little bit of my concern too where companies always starting from nothing to implement their design system because they kind of learn painfully about these unknowns, right? That others have implemented into their design systems after years and years of years of iteration. For me, a big one there is keyboard navigation and so on where people just forget it and then you use a native component that comes with HTML And it has all these awesome built-in primitives that the operating system manages. So it kind of goes also into the problem that has become a big thing for everybody in the web community, which is the amount of code that we ship to users, right? So when you implement very heavyweight design systems, you're now shipping a lot of code to your user. Right? I was reading this fascinating tweet and a study today of how you can't even take caches for granted because in a lot of cases the network is faster than the cache. People think, well, I'll ship a 3-megabyte design system, it'll be cached. We'll do monthly releases anyways, we'll just send the immutable cache headers. Well, acquiring that design system JS file and CSS file from disk can actually be pretty slow. Maybe because of the capabilities of disk I/O bandwidth on the device. Maybe because there's a lot of pressure on the disk because you're, you know, booting up another application concurrently. Maybe you have an HDD instead of an SDD. So, you know, what I've learned so far is that the only way to be safe is to not ship too much JavaScript. That's what the best products end up doing. And certainly it doesn't fit every category of application. We're just talking about Figma. Figma, surprisingly to a lot of people in the audience, only ships a 2-megabyte WASM file. And I think it was like a— last time I looked at it, 1 megabyte or maybe less JS file. It doesn't sound like a lot, right? I think the Sketch binary is like 60 megabytes or something. It's an incredible feat for it to be that slow. And sure, if that doesn't load in 100 milliseconds, well, that's expected, right? And if the withdrawal of that asset from disk takes a little bit longer, that's also okay. We're launching a design app. When you do the same for CNN.com, that's where things start getting complicated, right? Because like, hey, like, I'm just trying to browse the news. I don't need to load Figma, right, inside. But that's kind of like the duality of the web today, right? It's so powerful. Unconstrained creativity, unconstrained everything. The other day, I saw another great tweet of one of the dev rels at Google for WebAssembly. That said the memory limits of WebAssembly heap size, I believe, has been lifted to 4 gigabytes. And that was like a new announcement. And it's like, oh, and he was kind of like being self-deprecating a little bit. It's funny. Oh, a new way of making Chrome use up all my memory, right? Just like load a 1-kilobyte WebAssembly binary that allocates 4 gigabytes of heap. There you go. You've used up all the available memory. But this is the thing, with Next.js, we are very conscious of this and we're making lots of interesting evolutions in this space of how to ship very little JS. We already have a Node.js, not Node.js, but a Node.js mode that you can enable on a per-page basis. But I'm particularly excited, I was actually speaking with Tim Judkins about this today, I'm really excited about bridging the gap of low JS. This is kind of a term that I prefer, low JS, you know. Don't throw the baby out with the bathwater, don't throw out JS entirely. There are ways that it can be used very strategically for the kinds of pages that are not Figma. Right? So if you're adding a little bit of scripting to one of those marketing pages or blogs or whatever, you don't have to ship lots and lots of JS. And then we can start being more mindful about making recommendations to people as well. Like, hey, this is not the type of page that should have more than N kilobytes of JavaScript. And that kind of guidance ends up helping a lot because what we've found and Google has found many times is you accidentally ship lodash.js in its entirety. You accidentally ship moment.js in its entirety. You accidentally ship a copy of Figma in your page in its entirety as an accident. That's kind of the— the problem with the web today that we're trying to help solve.
Yeah, it's definitely an issue with when you start bundling together a lot of different libraries and then especially if you don't have, at least early on, it's not trivial to set up code splitting yourself.
Totally. And that was also going back to the genesis of Next, that was the big idea behind the pages directory. Pages directory defines all your entry points. They become code-splitting entry points. And now if I'm going to the privacy policy, I'm only going to, that bundle only contains the privacy policy. It doesn't accidentally ship in your commons chunk or on your homepage. So we're heading in a very interesting trajectory because a lot of people have always resisted the idea. Let's talk a little bit outside of the React world. A lot of you have always resisted the idea of even using a bundler, right? If I just use HTML, if I add a link tag to a CSS file and maybe do some stuff with jQuery, that actually will be a pretty fast page to the dismay of a lot of people that want to make JS the— us included, the main character of the story. The reality is that if those were the constraints of your system, there's almost no way of making things slow, right? Because you got static HTML, static CSS, and then the JS that you write is pretty well compressed and whatever. But what's happened, if you look at it from a market dynamics perspective, is the demand has gone in the direction of more and more dynamic and rich client-side experiences. More real-time data, right? No one builds or outputs a page today that is not enhanced with JavaScript on the client-side in some way. So the trajectory that we're headed is because we have a compiler, we can now kind of end up with that result that you would have hand-rolled otherwise, right? And even better because we can output some HTML that you couldn't output by hand, right? Like we give you super minified HTML, super minified CSS, only the CSS that you're actually using on the page because of our CSS modules support, and then optimizations for only the critical CSS, and then optimizations that are coming for lazy loading JS. As you scroll through the viewport, we already have prefetching as you scroll through the viewport, meaning that we load the rest of the application. But then we can also give you this, like, basically different routes of scripting throughout the page that will be lazy loaded. And then at that point, you don't even have to worry about how much JS you use because the JS only gets loaded just in time. So imagine that you build a blog where you have lots and lots of content and then your footer has a very expensive script, right? Let's go back to that Moment.js. I accidentally included Moment.js example. Let's say that you're using Moment.js to render the year copyright 2020. For whatever reason you're using Moment.js to render that. Maybe because you wanted to render the year adjusted to the user's time zone. Time zone so that during the New Year's Eve some people get 2019, some people get 2020. Now, in the world that we're experimentally headed toward, it wouldn't even matter if you ship Moment.js because the root of dynamism only exists in the footer and gets loaded only by the time you get there and also preemptively as you're on the page. So imagine almost like a website being a picture and we land that picture above the fold instantly from the edge. You begin scrolling and then we start prefetching other parts of the application, not just of that very page, but also the dynamic entry points of that very page itself. So what you end up with is a system that almost can never be slow. That's kind of what our goal is with this optimization. It's like, how Limiting the developer doesn't always end up being an effective strategy because you've probably seen, I believe it was Addy Osmani from Google that contributed the coloring of the webpack bundles when you run webpack build. And when we look at the data of the broad web, we don't see that that really stopped developers from shipping. Oh, the bundle is yellow, I'm going to take another look. So really what we've been investing in is what are automatic ways that we can make the reduction on the JS that's necessary to be loaded just an automatic optimization. And it's not so much on pushing back to the developer and punishing them for working on a feature or writing code.
I guess, yeah, in the end it always comes down to just making it automatic in a way. Correct. Which is really interesting. I mean, after even just hearing this, I'm definitely more interested, 'cause I work with Next.js, but I also work with a lot of, I've worked with at least a lot of just Create React App applications, because we decided that we thought we needed more dynamic data coming in. Maintain data between pages, but I mean, at the end of the day, I guess Next.js kind of handles that or allows you to handle that as much as you want.
But— Yeah, some people choose Create React App because they wanted to use Redux. And the idea of a global store doesn't bode well or go well with a system that tries to optimize for isolation of the pieces in some way, right? But what we did that kind of, I mean, this is kind of like Constraints are the mother of invention. We wanted to retain very, very speedy page navigations on the Vercel dashboard. And instead, what we did, instead of trying to think of a global anything— the word global in some ways also gives me, always gives me pause, right? Because I don't want, uh, you know, a developer is working on page number 152 to have to keep global requirements on their head. Like, it's scary. It's like, oh, if I issue this, I have to think about what side effects it has in the rest of the system. And that's the problem with global stores. You literally cannot slice them because then they stop being a global store of state. But the requirements— and I always think about product requirements, I never think about technology requirements— the requirements for me And a lot of users, I assume, that have gone with Redux was they wanted snappy transitions and snappy interactions. In some cases, if you really study the rise of Redux, you could argue you needed better dev tooling for inspecting deltas of state. So there's a few— you can trace a few kinds of lines of demand for that. Technology which coalesce at some points.
Yeah. For instance, the fast refreshing, when you were showing me that earlier, when you mentioned that earlier, I immediately thought back to Redux DevTools where when it first came out, that was the most amazing thing where you could load in a previous state and it just worked.
Totally. Yeah. So it's always been a combination of I want some product results, I want some engineering constraints, and I want some developer tooling. Right? There's always been those kind of three prongs. Now, on the tooling, it's always been a case that you also want to see the evolution of your React state and component state. It's not just that you want to see your global store state. So I think that one is a little bit moot. The one that I always took a lot of interest in is performance. Right? I, like everybody else, want very, very fast websites. Websites and applications. So we wanted that for our dashboard and what we did is instead of storing state, we started analyzing the problem as a caching problem instead. And that's a very important distinction to be made because when you're dealing with caches, and earlier I talked about what Vercel does automatically to populate this global caches of pages and then revalidating them automatically and the developer doesn't have to think about any of this. I always want caching to be automatic because it's too easy to do it wrong, right? Like it's one of the hardest problems in computer science is caching validation. So we came up with this idea of a React hook where you say, you know, get me /user to get the user state and then as you navigate through the system /user and the result of that hook is always cached and it's always returned from memory. So then you go, okay, but that's shitty. So like, what happens if I log out? What happens if the username changes? What happens if this and that? Like, what do we do is every time the cache is read, we aggressively revalidate it in the background. So what this allows us to do is that it removes that global knowledge. Now everybody can write code that says, "Get me the user." It doesn't matter. Now if you're navigating back and forth, you read it from cache. This is how every native application behaves, right? Like when you work, when you are playing around with a native app and you navigate through panes or you tap on something, Data that's already been fetched is always there synchronously. But what I didn't want to fall for the trap of, okay, now you have to invalidate your cache manually. So what we did is we— and we call this library SWR because it stands for stale while revalidate, which is a part of an HTTP RFC. It's a form of cache control. So this has worked tremendously well for us because We got that speedy changes throughout pages and yet— and now no one manages any global state and very importantly, we denormalized everything. So we're not saying that you have to be aware of what every other page in the system is doing to that data. And we're embracing this idea of eventual consistency, right? I'd rather give you certain pieces of data instantly rather than wait on a brand new read from the server and then they can eventually converge. And this is super important because this is the natural state of any website regardless. If I go and go to my profile page on an application and I get some data, and I close my laptop, right? By the time I reopen it, well, the data is stale, right? It's not updating in real time. Like I have to press the refresh button, whatever. So what we did with this hooks, and this is why it's interesting that earlier we talked about reentrancy, is that we subscribe to all the events in the web browser that might indicate user intent on getting the latest version of that data point. So for example, we subscribe to the, page visibility events, we've subscribed to a tab becoming focused or not, we subscribe to the reconnection of the internet of the device. So if you made a lot of reads on your website on the client side and you're using SWR, by the time you regain internet connectivity, boom, you're you now have the most up-to-date state. And what we're really fascinated by is that not only did we have to— not only did we throw away Redux, we also got a lot of the benefits that are typically associated with GraphQL subscriptions, for example. The idea of keeping data up to date automatically. And we've even gone beyond, right? We, like I said, we can reconcile state very aggressively and very easily. So for example, in that example of opening your laptop's lid 2 weeks later, SWR always converges to the desired state. And this is kind of how we navigated that Jamstack space, right? Like we have some markup that has already been pre-generated and then how do you get data on the client side? Well, we use these hooks. And they basically have no limit to how dynamic the data can be once you use that library, which by the way is like 1 kilobyte.
Oh, wow. So useSWR handles all of this on its own then? Like it kind of subscribes to all those events and I've seen examples on Twitter. I haven't had the opportunity to check it out, but I have seen a lot of—
useSWR? Yeah, .sh if you want to check out, which will soon be .versel.app. But that's where we kind of created some of these examples. One of the findings also that we made is like, because we only do, for example, the polling of your data while the page is being rendered, it's actually pretty cheap on the server. Like, a lot of people think, oh, like, well, we revalidate aggressively. Yeah, but you know, that's maybe a handful of extra API calls and our backends are really good at handling API calls and returning data from memory. Especially modern databases are so good at scaling read throughput. So what we traded off is, okay, no one needs to write this global store madness. We optimized for user experience because now everything is really performant. And now everything is real-time and converges to the same state without needing a specialized data layer. So much so that SLR doesn't care about what the data fetching function is. It can use Fetch, you can use GraphQL if you want, you can even use it as a way of managing IndexedDB state. So I'll tell you a really interesting story. When we were working on our dashboard, we wanted to, we said, we wanna have the fastest dashboard in SaaS. And I don't know if we're quite there yet, but I'm really happy about where we are lately. And one of the things that we had as a constraint is like, we're gonna use Jamstack. So when you go to our dashboard, you're gonna get a static HTML page. So then that means that we have to start like, okay, if that is our constraint, we have to start thinking about "Okay, how do I get the data as soon as possible?" Right? So one interesting thing you're going to see if you inspect their HTML is their link rel="preload" tags. And then I was talking to the Twitter.com guys and they use the same technique. Their link rel="preload" tags that are anticipating the requests that React is going to make later on. So React is going to invoke these hooks They're going to go and make fetch requests. Those fetch requests were already made by just HTML and the web browser as the HTML was being streamed from the edge. So that's optimization number one. So what happens later is like, okay, React comes to life, this skeleton for the page has already been pre-rendered into HTML, but as React comes to life, all these hooks start getting— start firing to get all this dynamic data. So what's really neat about this is that we turn a technology that is very much commonplace, which is fetch and HTTP requests, and we kind of made them work really, really efficiently in parallel. All the hooks that are not depending on each other fire in parallel. So it almost feels like you're streaming data. Even though you're not really streaming because you just got a static page downloaded from the CDN.
Yeah, it makes a lot of sense. I mean, it's almost like you're pre-populating whatever you can and then you just fall back to an API request as soon as you need new data.
Yeah, and this kind of gives the developer the ability to, again, you gotta have something that's pre-rendered and then when you have to enhance it on the client side, you can basically just use React Hooks and get all these benefits of what I call user personalized data as well, right? So one of the constraints of Jamstack when it comes to pre-rendering is that you can only pre-render things that fit public caches, right? You can pre-render blog posts, you could even pre-render in multiple languages, you can pre-render maybe even geolocated content that you can give someone in the United States some content, someone in Canada some other content. But what all this has in common is that nothing is private, right? Nothing was specifically for Guillermo Rauch and contains private information, right? And that's great because what that constraint did is that now we shifted all of that that's user-personalized and private to the client side. And now we don't have to worry about two security contexts. As long as our API is secure, the JS gets executed in the secure sandbox of the web browser and it's the same JS for every visitor of that cohort. And now they can just make API calls. And it's the same way that a native application works, which have been very notoriously secure over the years. And now, with that ability to execute that JS on the client side, you can add any level of personalization that you want for that specific user session. So in our case, for example, on all our pages, we render the user state, whether you're logged in or not. And that goes for all our marketing pages and all our dashboard pages because they just execute this client-side hook. That says, "Get me the user information," and then we render that proactively— we render it later on the client side. So every page just arrives to this completeness result in a manner that's very consistent and the markup is always downloaded from the edge, which means the first paint is always instant. The user is never blocked and looking at a white screen while your server is doing some work. So you can't have your cake and eat it too, you know, these days.
Yeah, like I just invalidated my own cache and then as soon as I load the page, every page loads instantly and then the login works pretty quick. What you mentioned about the Redux issue is kind of funny because that is my major gripe with Next.js up until now. Has always been using Redux and then having to revalidate that store or rehydrate that store server side. And then making sure that we weren't doing anything that somehow resulted in shared data between users.
I'm glad we covered CSS and we covered a bunch of things because I've always found that our usage of Next.js has been so, boring, but for a good reason. We always use React State. Nowadays we're just using Hooks. We never use any state store. Even though we have quite complicated systems. One of our pages is the logs of your deploys and there's lots of real-time data and other pages have complex form flows like our import flow. For importing a repo into Vercel. We've never used MobX, we've never used Redux, we've never used any of those things and we've never really needed them. And by the way, the React team has always consistently agreed with us. This is a problem with— or problem, it's a good thing, but this is a thing with very massively popular things is that everyone adopts their own kind of philosophy. Around them. But our philosophy has been always pretty consistent that we want to use the primitives that are being, being given by React. This is why we've never had a themes, um, a concept in Next.js, because at least personally, I've never seen how that's not a problem that fits the domain of React as opposed to the framework. We've always tried to make the framework very lean And with CSS, our take has always been try to use CSS. So we support— we always supported styled-jsx and now we support importing CSS modules and so on. We've always tried to be boring but for good reasons. And when it came to this specific challenge of how do you make data fetching consistent and super fast across pages, we wanted to retain that constraint of like, well, let's try to use the platform. Let's not try to add more and more and more overhead to even what do you need to learn to add some dynamic components that do data fetching and at the same time not have the developer have to reinvent the wheel, right? And we're pretty happy with where we landed. Now, as I said earlier, React itself is in a lot of evolution. The React team is working also on data fetching primitives for components. So that's our other kind of alignment that we've always had is like, we kind of know where the React team is headed and Next.js does a really good job at aligning itself well for the future. So because we never want to have a situation where a lot of people have bet on Next.js and then it takes a direction that doesn't make any sense with the future of React itself. That's why we've always strived to be very, very lean with the overhead that the framework adds. The worst thing you could have is you put in a lot of investment into this framework and then the very thing that was attracting you to it becomes incompatible.
Yeah, I found that to be the case with— I mean, it's evolved now, but back before, when it stopped being as well maintained, Meteor kind of had that same sort of issue where early on, at least, it came with its own templating and all of that, and as the community kind of moved towards different libraries, it just kind of fell apart, and every application you were building in it, there was no concise way to do it.
Totally. It happened with npm, right? For example, there were Meteor packages And then people were using npm, right? So that's kind of our biggest thing, right? The framework is so popular now that the only thing you hear is feature requests. So we have to have this really good balance between, you know, sometimes it really does come down to saying no to things that are good ideas if you know that they're not going to be a good idea in 6 months. You know, like that's the tricky thing. And sometimes articulating that can be a little tough, but on the opposite side, you know, we've added so many things that React really never had, like a very easy to use router. And those things, you know, have become sort of invariants of the web. Like our goal was always, you know, Next has to output pages that are accessible via URLs. So we know that's never gonna go away and it's gonna be compatible with whatever system that comes later on. So that's always kind of been our hypothesis. In fact, one of the things that we always would think about in the beginning was like, let's even strive for a world where Next could, at least portions of Next.js can be compiled down to web components. Because I do think that there's a lot of merit in that technology. I don't think, you know, it's— this is the thing that happens with frameworks, right? And this is why having a compiler and making that your starting point is so useful, is that as platforms evolve, well, sometimes you can just ship less code and you can take advantage of the code that has already been preloaded. On the device. And what I found, and this is kind of like a lesson in software engineering for me, is you can never compete with that. You can never compete with a web browser that's already booted and you already preloaded a ton of code, right? It's the same principle that makes Next.js very hard to beat in terms of like page navigation times, right? Like you open a page and we're already prefetching the next one. It's very hard to compete with that. If you put two pages side by side, legacy system, Next.js system, I consistently see that the Next.js one outperforms via very simple things like prefetching.
Do you think that— 'cause I know that there were some examples of, for instance, Gatsby, the prefetching was able to beat the performance of just a static HTML page. Do you think that does Next do the same sort of thing? The same optimizations?
Yeah. And bundles of the JS that Next.js preloads are smaller too. So in this case, and again, it's always a matter of looking at it for your own specific use case, but in this case, Next.js actually would probably be both. But the point is exactly what you said. Having this higher level platforms sometimes enables this kind of optimizations that are just hard to compete with. The hand-rolled web is not in a good shape right now because you're just not gonna get these things like preloading the code. But the same is true for the code that you ship to the client side. If the browser has already loaded all the code for a certain thing and then you try to reinvent that thing with your code, well, you're just gonna lose every time. It's just a matter of physics. Yeah, I see that with components, as I mentioned, with like, oh, you're loading all the code for, you know, a custom select box and then the browser already has one and they allow you to change it with CSS, you're just not gonna win. There's that, even as I mentioned, because caches can be slow. So caches are not, no free lunch either. And I see that even with fonts and web fonts, right? Like the browser, and the operating system have a hyper mega cached version of the Atlas, the texturized Atlas of the system UI typeface, right? So it's very hard to compete with that, right? Like the freaking texture is already in the GPU and you're starting to download an unknown font from a third-party CDN. You know what I mean? It's just so hard to compete with that. Now, does everyone have to worry about this hundreds of milliseconds? Well, I would argue for very sophisticated use cases you do and a lot of those cases web fonts lose. But then there is also the side of creativity and like, well, web fonts sometimes look freaking great, right? So being aware of where you spend your performance credits is still a really good idea. But that's kind of like one invariant that I've found that always helps me to reason about these things is like, well, are you competing with something that's already loaded by the time you begin downloading your alternative? Well, that's always going to lose.
Yeah, I guess the moment you reach the network, it kind of is in the hands of God at that point, really.
Yeah.
You don't know what's going to happen.
And this is why I'm so— enthusiastic about what we're doing with our edge network because as I was reading that article today about how the cache on your device can lose to the network, it brought back a lot of memories. We've discussed this extensively with the Facebook team about how they've also done experiments. We did our own experiments where the network was outperforming IndexedDB. I lost my train of thought earlier when I was going to share this story of One experiment that we did with SWR is, well, SWR can take any asynchronous function, right? So you can say, okay, use SWR/user, fetch. So what we did is we built fetch with IndexedDB because then we can aggressively revalidate once we read from IndexedDB and we ship that. So what we did is our idea was like, okay, you're going to come back to Vercel and come /dashboard, we're going to have everything there. It's going to be like a native app, like when you reopen Instagram and all the photos and all the comments and everything that you last saw were already there. And then we added our telemetry system to this and we instrumented the crap out of it. So we instrumented, we traced every asynchronous function call, we traced time to first contentful paint and all other important metrics. And we saw that it was a regression relative to just going to the network in a huge number of cases. So that's what then led to the alternative investigation path of like, let's try to make the network request instead as soon as possible, even by the time, you know, the HTML is streaming in. And that just gave us kind of what we wanted, that idea of like, hey, load come to the site and get all the data in one go, that almost feels like a real-time stream from the server. So going back to the edge network point is that what I find is that making no assumptions about the contents of the device leads to the best engineering possible. It's almost like you're always working in favor of your worst case scenario. That also applies to CDNs, right? You think your CDN that's going to your server full origin is great because, "Oh, it can cache." But are you sure it can cache in 150 locations for every single page and that you're not going to get a lot of misses? Well, the data becomes really blurry and hard to understand at that point. So you're better off assuming that it's not going to be in cache, right? You better assume that maybe there's an alternative design that would allow for the pages to never be missed. So a lot of our investment goes into that direction of like, think about the network as being the most important and fundamental thing that needs to be instant. And don't put your chips on the power of the device or other things like that. We've seen the single-threaded single-core performance of CPUs on mobile devices throughout the world have not improved. Like, Tim Cook keeps making our CPUs so fast, they're faster than our MacBook Pros. But for the rest of the world, interestingly, the networks are improving. So I, here in San Francisco, have worse internet than one of our employees in India who has way better LTE than I do. But the devices are not going to be, for the most part, until at least in a few years, they're not going to be iPhone 11 Pros. So this idea of streaming pre-rendered content that is not even traveling to origin with very fast loading JS that makes no assumptions whatsoever about contents of the cache is a system that will make the web orders of magnitude faster for the everyday publisher. I'm not talking about Facebook that has an SRE team of thousands of people. I'm talking about making the web, the fast web accessible to everybody. That has not really happened yet and this is kind of what we're working on.
Yeah, that makes a lot of sense because I guess like, yeah, when we think of like— so one of the questions that I wanted to kind of I wanted to bring up here was, what was your opinion on infrastructure as code? And, you know, because it seems like there's two camps that are kind of evolving over time, right? We've got the serverless, the Jamstack, and that sort of environment. And then, we've got these other DevOps-oriented infrastructure as code, Kubernetes deployments, and being able to deploy an entire system to the cloud. Through a scripted environment. And I always kind of imagined that there has to be a middle ground where you have a boilerplate and you should be able to get your environment deployed and you've got a templated version or some sort of whatever for your backend system.
Yeah. That's a good question. I always tell people when they ask, "Oh, are you thinking about—" "Uh, what do you think about infrastructure as code?" I always tell them like, "I prefer infrastructure as no code." I really think that, I really think that, you know, to be truthful, like I think that the web has to learn a lot about, you know, the entire experience end to end from developer to recipient of iOS, for example. Like the developer is working on an app that will, you know, in a few weeks reach potentially billions of Apple devices is not worried about how Apple is orchestrating the CDN infrastructure to deliver their blocks of code to the end users. They just trust that Apple will do a good job and that that job will get better over time. And indeed it happens, right? I've noticed this with native app servers. I'm like, it used to take forever. Now Apple has invested a lot of their edge caching functionalities. Recently they even put out a project, I believe it's called edge.cache.apple or cache.edge.apple, where they're promoting for ISPs to start caching the native apps right in the neighborhoods, right where people are. So that's what I think effective software architecture should look like. The developer is concerned on the user and on expressing their creativity. And the infrastructure is just part of the air and it's fast and reliable and always there. Now, Apple is a walled garden and they have lots of terrible ideas about how they— lots of great ideas and lots of not so good ideas about what makes it into the App Store, what, you know, this and that. And the web is open and it's fantastic. But I want to make sure that at least for our own little sector of the world, that we maintain that level of quality when it comes to the infrastructure and that we enable those optimizations to also happen over time. And I think infrastructure as code is kind of a regression in that way because now you materialize your infrastructure in a— hard, fixed in space and time, like JSON file that then someone has to maintain, or YAML, or whatever it is. And things unsurprisingly don't get so much better over time because now you've checked in into your Git repo the responsibility for both. Before, the Git repo could have been just your application. Now, it's your application plus infrastructure. And when I think about delivering great experiences to end users, I think, you know, creating a great application, a great website is already hard enough. We covered a number of subjects, even like the decision of whether a custom font should be used, right? Accessibility. Like, these things are hard and take a lot of effort. I want to make sure that we spend all our effort in those things or on the cohesive application and correct application of the design system. And the evolution thereof. If we focus on those things, then the web becomes really, really competitive. And I'm talking about like taking over the world competitive where like you reuse your skills that you learned for Jamstack today, not only for websites, but in the future for any kind of web app and in the future, any kind of app, period. We certainly have that intention with Next.js. That's another thing I think about a lot is like, we're here today solving some fundamental problems of the web being slow, but the sky's the limit with how far you can go in terms of making the experience of developing a Next.js site more of a visual experience that is even more approachable to people with not as many engineering skills. But even further than that, there's no reason for the web to not be able to overtake every single app on your mobile device. It's just a matter of time. It happened with Electron, right? We used to write code for many platforms and so on. And nowadays, the web is freaking rocking it, right? Even a lot of people would knock down Electron because of the Slack app. But now the Slack app is one of the fastest apps, at least for myself, it's one of the fastest apps I have, and other apps that are native are not so good. Yes, I always look at Sketch, kind of, it feels slower and slower every year. Totally, and as I said, like Figma's a freaking 2-megabyte, you know, WhatsApp bundle. Amazing things are happening and I think the trajectory of the web is such an amazing one. And yeah, you know, enabling all those, people to produce for it. It consistently remains, in my opinion, the platform with the easiest onboarding, right? Like, you don't have to get a developer license. You code with a web browser to get started. People nowadays make memes with DevTools. Like, everyone knows how to make the web. It's a good place to be.
Do you think that Next.js will eventually get into sort of like the React Native and native applications sphere or?
I think eventually, not so much with hard native stuff, but I've talked to a lot of the big Next.js customers, like Trulia, for example, where they kept telling me, I'm this close to ditching all our native views for properties so I can just load the Next.js view. I haven't followed that very closely, but They were certainly experimenting with it. A friend of mine that works at Credit Karma told me that it did happen for them. So there's broad categories of views, not the entire app, but broad categories of views that imagine the benefits that I just outlined. The property gets downloaded from the edge and it's reliably there in 20 milliseconds. Oh, and it can sometimes outperform the cache of your mobile device and it's consistent and you can update it however you want without redoing the entire application, right? We have to re-download the entire application. So I would even turn the question upside down and say like, well, in some ways it's already happening, right? Like I wonder how many of these kinds of, you know, Next.js pages are already being loaded in that way. I know of a bunch for large apps and I think it's going to continue to happen. And it should happen because there are certain things that native does that are, again, hard to compete with if you've already downloaded, it's already preloaded. But the things that are in— and this is kind of the paradox of Jamstack, right? The property page is a great candidate in kind of a Trulia or Zillow or Realtor.com, all of which, by the way, are powered by Next.js. So if any of those property changes, the data is obviously dynamic, but you kind of want to have those be incrementally statically generated because then you get this instant edge download and super fast download times. But if you were to do that by going to a server, in that case, it might be hard to compete with native. Now, if we're talking about is like, "Hey, that page is like 20 milliseconds away and now you have the freedom to deploy it on your own and regenerate it on your own," then native starts becoming less and less compelling because now you can match the performance. In some cases, you can even exceed its performance because again, the HTML plus CSS CSS web that doesn't have a JS bottleneck, it's very hard to compete with because it's just like a streaming wire format. You know what I mean? Like, it's hard to like— sure, like if you're parsing JSON versus parsing HTML and then mapping the JSON to the Native Components or whatever, like it's not so clear to me that like Native has the web beat in a very strong theoretical way even. But then there's the practical economical reasons, right? Like now all of a sudden you're creating your pages with the same skill set that your entire team has, delivering the same payloads or even payloads with slight variants for like Android or iPhone, whatever. And you can do this at a massive scale for every device on the planet. Then I think the web wins again, just for pure economic reasons. But again, the tough thing with native is there is this mega power law of we're all always just using Facebook, Twitter, and whatever. And when you have such a concentration, you find that they can afford to go down to the level of writing hand-rolled assembly if necessary because a slight change impacts the behavior of billions of users. So I don't think we're going to compete there. In fact, I would argue that no one that has any high-level interface can compete. I don't know if you heard about Messenger got rewritten in C and funny enough, all the custom components got thrown out because of the law that I mentioned earlier that if they use native platform primitives, even for them, going from, let's say, Objective-C or C++, I don't remember what the previous target was, to their new version in C, they reduced binary size drastically and they started using more of the native platform. So going back to the idea of don't write your custom select on web, well, don't write your custom select in iOS either. So that law still holds. It's a very fascinating article that Facebook put out. And then what was interesting about that, the findings there too, is that they just went and rewrote it absolutely from scratch just to get a slightly faster boot up time for me, but at the scale that that app is operating in, it's night and day boot up time difference.
Whereas if you're a small startup or if you're only serving so many customers or if you only have such— if you're a traditional brick-and-mortar business and you only have 2 or 3 developers, you don't have the capacity to deal with that level.
I think where web is going to— is that big medium and big long tail is where web is going to start making some really interesting progress. Progress over in this coming decade. We have a lot of customers in e-commerce. Next.js is used for, again, creating all kinds of pages, but there's a lot in e-commerce. There's a lot of news websites and they also want to have their native apps because at the end of the day, it becomes kind of like a practical bookmark for your favorite provider of choice, whether it's some brand of shoes that you love or your favorite news website and so on. And that equation, even though it's not a small startup anymore, it kind of starts to wear on the decision makers of those companies. Like, oh, do we now spin up two new teams to, you know, we just did this massive React effort, "Do we spin up two new teams, one for Android, one for iOS?" So that's where I think we're gonna see very much growth in React Native and Ionic-type apps that get distributed as native but they're loading progressive web applications and hybrids of these. So like apps that boot into React Native and maybe there is a very optimized native view and then parts of the other views are just glorified web views.
Yeah, I guess you could incrementally upgrade that. I mean, you could just deploy whatever Next.js website you have as a progressive web app.
I'm pretty sure, and everyone on the internet is listening to this can fact-check me, but that incremental idea, I'm pretty sure is what Amazon did. And if not Amazon, a lot of e-commerce providers like them. So there are plenty of these where like, they were like, okay, we need to go to mobile tomorrow. Okay, we have this super complicated system, we're not gonna rewrite it overnight. Okay, launch a WebView and then incrementally improve it, right? If necessary. And like, if you take that as the baseline, then you might get to the point where like you're not incrementally replacing the web as much because now it's all of a sudden doing a really great job. And I know that Google has done lots of interesting studies about like, When companies created PWAs, they ended up outperforming some of the engagement metrics of the native apps. And that's just the credit to great tooling that they used, great care and great engineering on their side. Something that was interesting about that Messenger rewrite thing was So much of what we do also has to do with this care for the detail, care for the output sizes, care for not repeating code. And there's no magical technology that replaces that care. I guess going to my point earlier, the magic that we're trying to bring is that if you care less about infrastructure, now you have more time as a developer to actually do that work that is not necessarily always all that fun, but it has to do with digging deep and seeing, okay, what am I shipping to the end user? I saw a great tweet the other day also by one of the core contributors to Go, and he was saying, "Oh my God, the Go compiler is shipping all this nonsense into my binary." He had not just blindly trusted the Go compiler, which is, by the way, it's a freaking amazing thing. And he was like, there's 110 kilobytes in this static binary that my Go compiler output that is redundant and unnecessary. And here's the workaround that I found for not including that. And this is kind of what I find consistently in great engineering outcomes. There's a lot of care for the size of the output. Size, I mean, not only on the output size of like, oh, how big is the JS? Size in terms of memory usage, size in terms of, you know, or the lengths of all the important metrics. I want to call out too that the Chrome team did a great job with an announcement that they made this week that they called the Web Vitals. And they really came up with a very constrained and simple system of 3 metrics. Like, what are the vital metrics that you look at when you analyze the performance of anything? And yeah, paying close attention to those vitals is kind of the right thing to do. And there's plenty of optimizations that we're constantly making to the framework, but having the affordance of getting that time to measure the key metrics of your product is always the right investment to make. And it doesn't really matter what platform you're using. Like I said, this is kind of why infrastructure to me, the more we can reduce that burden from companies and teams is— I always think if we succeed, people are creating better products, they're creating better websites. And that's why we analyze all these metrics at a grand scale, right? From Next.js 1 to Next.js 10, we're going to publish this soon, but It's pretty amazing how much faster we've made the web. Even from Next.js 8 to Next.js 9, some of the biggest retailers that we serve became like 40% faster. And the metrics are well understood, right? If you're faster, you convert better, you sell better. So it's really nice to be operating at a scale now where we continue to ideate all this optimizations and so on, And then people just yarn add and update their dependency and all of a sudden they're doing their business better. It's a very motivating thing for us. Yeah, it seems like the—
it really does seem like the future of the web is just being able to update your dependencies and benefit out of the box from those changes and you might need to make some minor modifications but I noticed with Next, the migration path always seems very simple, very straightforward, which is—
Yeah, we're very, very, very committed to backwards compatibility. In fact, when we added the static data fetching hooks, we retained support for the more generic getInitialProps data fetching hook and every path is an incremental path for everybody. So if you wanna make a page static, we tell you delete getInitialProps, which means signals Next.js that there's no data fetching to be done so we can output HTML. Or we tell them, opt in to getStaticProps and now you can fetch data at build time. So it's always been a lot of care for that type of experience of like, hey, I actually did this recently and it's pretty crazy, but when I announced Next.js at React Conf, I built a deck with Next.js, kind of like my slides all built with React components. And that was like, you know, one of the, I think it was even pre-1.0, it was like Next.js 0.something. And I took that same codebase and I, I tried to run it, I think, probably even this year, maybe like January of this year, and it just worked. The only thing that didn't work was someone deleted a dependency from npm that I was using. But other than that— You got left-handed. Yeah, exactly. On the Next.js side, everything was good. And then I think it was some transient dependency of some date library that— but within seconds, without any codebase changes, things were going really well. And it was kind of that realization that it feels nice that you can even go back in time and your code is— and this is kind of why also the web is so awesome, right? I'm sure that you try to boot some old app on iOS and just, you know, unless it's recompiled or something like that, it just doesn't work. With the web, things can really persist forever. That's certainly one of our intents with our deployment system. Teams can go back and visit previous versions of their pages and sites, just like you would do with Git and GitHub. So that idea of preservation is also very important to us.
That's amazing. I mean, as a developer, I really appreciate it because it makes my life a heck make it a lot easier. Yeah. I realize that we've been going for quite a while here. I was curious if you— just as like, I guess, a last kind of wrap-up question, if you had any recommendations for people who are getting started, I guess, whether in web development or in development in general. I know that you got started a lot with open source and contributing directly, which to me is incredible. That's very daunting. And I was just curious if you had recommendations for people early on in their career. They want to really dig in. They might want to be in your position someday, maintaining one of the largest frameworks in the world. Maintaining a pretty impressive cloud company. Do you have any early-on recommendations? I know that this is kind of off topic from the rest of the—
No, it's great. I would say it also touches on what we just talked about, is this idea of have a working hyperlink to something. That's, I think, one of the most important starting points. Put your work out there, put your products out there. Obviously, I always recommend to people go to nextjs.org/learn, which guides you through creating your first blog and just a simple few pages. But the more important idea is, and I'm a big, big fan of the #100DaysOfCode, kind of hashtag has become popular on Twitter. Where people are constantly sharing what they're working on. And a lot of them, what I noticed, I think a lot of those people are going to be great and very successful engineers and product builders because they're constantly sharing interesting things that they wanted to build. And I think that's very important. It's like, the problem with a lot of tutorials is the tutorial has configured a goal on your behalf. So with Next.js, we try to build something in our tutorial that most people would want. But the interesting thing after you complete that tutorial is like, oh, I wanna build a little widget, I wanna build a little tool, a little clock, a little workout tracking app, or I wanna put out some statistics about COVID-19 that has become a thing lately, obviously. Something that has a user-focused and product-focused goal, so that then you can work backwards to the technology. And then almost always you will inevitably find the solution. Obviously, some things, some goals you can figure are like too much out there, and then you have to revisit them years later, uh, when you're ready. But for the most part, what I've seen to be incredibly successful is like people that set out to make a shareable unit of work. This is why I'm such a big fan of the web, because like you publish immediately, you're always publishing, right? Um, and but also that has some meaning, perhaps meaning that is relevant to your personal story, like some skills that you already had that, you know, kind of mixes well, uh, with, with, uh, engineering, uh, some artistic endeavor, uh, another, uh, project to, to follow in this in the sense is, I think it was called 180 Days of Code by a woman named Jennifer DeWalt, where every day she wanted to build a quick little widget or animation or whatever. Like one is like TikTok, a game, or whatever, like that chess, or every day she had an idea for something simple to build. Okay. And all those are still live, and this is like years ago. Now she's a co-founder of a company. And that became to me like, wow, that's the model. If I were to recommend to anybody that they learn to code, it's like, it shows the consistency of like, hey, you have to stick with it. And it takes a lot of time. But it also has this component of, I can share what I'm building. It's not some folder on a project's directory on your computer that gets abandoned and never saw the light of the day. And starting very, very, very small. Another counterintuitive thing is like, it's okay to reinvent things. So going back to your question about contributing to open source, it's totally fine to contribute redundant, quote unquote, redundant things to open source. Like you're literally cloning something that already exists and you're doing it your own way. Even more so than contributing documentation, that's also very good. I started with ModTools with some documentation changes, but I always wanted, I was pushing myself to how can I make a dent on things that are shareable and will impact a lot of people with the code that I write. And then open source kind of became the thing I became obsessed about. And then obviously it's still the case.
That's really great. I love that. Thank you. I love the 100 Days of Code hashtag because I always see people just like really transforming over the course of that journey because a lot of people do it.
Yeah, it's fascinating.
I mean, there's a lot of people that do it when they're more like a little bit further along, I guess, and then actually I think that that would be something maybe I should try.
Totally. Like, I've seen, I've seen all kinds of people doing it. It's a really fun experiment.
Yeah, I mean, it is really interesting. I can imagine it pushes, uh, your level of creativity because at some point you're gonna have a day where you just—
right.
Yeah. Well, thank you very much, uh, Guillermo.
Um, thank you so much for having me.
Do you have, uh, anything that you might want to shout out?
Yeah, so by the time the podcast comes out, obviously I think Next.js, the newest release with React Refresh, will already have been out. It's Next.js 9.4. But what I'll call out about that release is, especially if you take the Next.js.org/learn tutorial with it, is it's just very, very pleasant, snappy, real-time local development and it just It's quite an interesting feat. It fixes a lot of interesting issues that have sort of plagued the React world for a while, like really good error messages, really good stack traces. It's approaching perfection. There's a few little things that we're working together with the React team on exposing from the guts of React to get that to a level of perfection or close to perfection. But yeah, we're really proud of it and give it a shot.
Awesome. Yeah, I'm going to check it out later this week. I'm really looking forward to it.
Thank you. Thank you.
More from Guillermo

Guillermo Rauch at Founders in Arms Live: Simplicity, Focus, and the Bet That Built Vercel

The Man Who Built a $9B Dev Platform Thinks You're Overcomplicating AI | Guillermo Rauch

Inside v0: How Guillermo Rauch Is Building 100 Million Engineers | Lenny's Podcast - EP.89

Architecting for model step-changes: A fireside with Vercel's Guillermo Rauch

Keynote Interview: Vercel's Guillermo Rauch on the Agent Era | Azure Cosmos DB Conf 2026

Vercel CEO: 70% of Our Traffic Is Now AI Agents "Nobody Was Prepared" | Anthropic, OpenClaw, OpenAI

Why being "terminally online" is more important than ever, with Vercel CEO Guillermo Rauch

Argentina Week 2026 | Argentine Talent Powering Global AI | Guillermo Rauch & Hernán Kazah


