785

June 21st, 2024 × #react#nextjs#vercel

What’s Next for Next.js with Tim Neutkens

Discussion with Tim Neutkens from Vercel about new React features like the React Compiler, React Server Components, and tools like Next.js and TurboPack.

or
Topic 0 00:00

Transcript

Scott Tolinski

Yeah. Well, I mean, we could start off with some of the the hottest new stuff, which, I guess, is the compiler.

Scott Tolinski

So, you know, I Wes, first and foremost, I know I know, you know, this is a React thing and not a Next. Js thing, but I'm sure you all are very tightly integrated into this.

Scott Tolinski

What does the React compiler do for those people who might not be aware of what it is and what it does?

Guest 1

Yeah. So, if you watched the recent ReactCon keynote, if you haven't watched it, I'd highly recommend you to to watch it because it it's definitely a much better explanation than than I will ever be able to do, I think. Mhmm. Yeah. But in in essence, it's like, in, like, 2018, React Hooks were introduced, that there were a whole lot of Hooks. Right? So, like, use state, use memo, that kind of thing. We're really, like, in the end, like, that they didn't have the ergonomics that you want, eventually, like, when you're writing this code. So they were, like, created in a way that you can, like, incrementally get rid of them if you were to build a combiner, at some point.

Guest 1

That's really what the React team did. So they they went, ahead on, like, a pretty long journey. I'm not sure exactly, like, how long they've been working on it exactly. Many years, I think. Yeah. Something like 4 years, which, which also causes, like, people to to doubt, like, we'll ever, like Yeah. Come. Right? Like, are we ever going to have suspense? Like, that kind of thing. Right? Yeah. But now in the, like, last few, like, 2, 3 weeks ago, they they announced that the React combiner is now both open source, so you can, like, view the the source code.

Guest 1

And it's in, in beta, so you can, like, try it out. They didn't recommend you to ship it to production yet, but they are shipping ESLint production themselves, in in, like, Instagram and, and which other places at Meta to, like, really, like, dogfood, the system, that that gives you, like, exposure to a lot of, like, different types of code. Right? So, like, it's similar to, like, anytime you start building, like, compiler that transforms the original source code into something else, they're they're really cases and and they're trying to catch all these cases. So, that's why it's, like, released early so people can try it out. Okay. I mean, like, what it what is it? Which is the initial question.

Topic 1 02:47

React compiler does automatic memoization

Guest 1

It it basically does memoization for you, automatically.

Guest 1

And and Node just for the like, the the basic case is, like, I have a value that is, like, derived based on some state or some, they're basically the things that you would usually, like, call, like, use malware for that kind of thing. Those are the things that I can having summary acknowledge, like, I can manually add them and, like, make rendering better. Right? Like, the don't rerender this thing. But it goes much further than that. So like it it goes into like, I I was talking to Salman on the on the Vercel team that works on the, like, Vercel website recently. I was, like, showing him the React compiler, like, side to side to to what like, if you don't have it enabled.

Guest 1

It Wes, like, I thought this is always, like, how React worked already. So why are you showing me Yeah. This new thing? So, like, another way that I look at it is, like, it makes the assumptions that you had around, like, how React renders a bit more, like, the the reality with the compiler.

Guest 1

Because you don't have to think about, where do I add memo? Where do I add, like, use callback? Where do I make sure that things don't rerender? And instead, you just write my, like, product logic and and, compiler can figure out, does this thing need to be memorized? Does it not need to be memorized? Because, like, the the other side of things, like, early, optimizations. Like, you're at some point, you're you get so into React so you get over this. Like, it's it's like this meme where where you go to, like, peak and then, like, back to to, like, not memoizing anything. Like anything. Yeah. So I guess, some point you're like, I know React so well. I'm going to memoize everything. I'm going to, like, mainly add use memo everywhere, use callback everywhere because I don't want anything to change, like, between renders. And that's not always the best way to do it in the end. So, the React compiler can just, like, take your original source Node. It can basically optimize it in in various ways by, like, memoizing more bits. So it's not just the, like, state being minimized or, like, specific, like, derived, state as Wes, but it's more like it can memoize your j s x as well, for example. So, like, in some cases when, like, some input values change, only a part of your JSX tree needs to change. Oh, okay. And it can, like, automatically

Guest 1

So the the lesser known one is that, so it doesn't fix that, I think. Or I'm Scott a 100% familiar with this. So, like, don't pay me down a little bit. The I don't think it fixes the the context one, but it does fix the the other case, which is, like, prop drilling. So when you're writing an app that is, like, I I get, like, a a prop that I'm passing through, for example. Yeah. Anytime the prop changes, obviously, the component needs to render.

Guest 1

But then, like, if the prop is only used in, like, Node place, for example, like, in like, you have 2 components that are next each other and, like, you only pass the prop to to this, like, other component. It would also rerender the the 1st component that doesn't use a prop because of, like, completely rerendering the entire tree under the component. Mhmm. With these changes, it doesn't actually do that anymore.

Guest 1

And it's, like, more like, that is what I was saying. Like, it feels more, like, than the natural way of you you would expect it to go, which is, like, I'm not using this prop here, so it doesn't rerender, but actually did rerender previously.

Guest 1

Yeah. So it will depend. Like, if you if you have, like, smaller apps and, like, like, smaller component trees, like, it's less likely that you'll see problems per se. It's it's more of an, like, optimization that you just get for free.

Guest 1

On larger apps and, like, that was the case that they gave for Instagram, for example, that it would just, like, output code that is more performant than any, like, engineer going manually, like, optimizing it.

Guest 1

And if you look at the like, there's a playground as well. That one shows you each individual step of the compilation and, like, how it optimizes it. And if you look at the output, it's just, like, output that you would never write yourself. Like, it's it's stuff that is, like, use memo on my JS and, like, like, not exactly, but, like, that is the the conceptual way, you think of it if you don't have the playground, in front of you right now. So it's, like, just things that you would never do yourself or, like, usually, you would never do Vercel or you're at this, like, peak. I'm going to memorize everything.

Guest 1

When the React compiler goes stable. Right? Because right now it's, it's still in beta.

Guest 1

Once it goes stable, you wouldn't have to think about this anymore. And, like, there's, some optimizations that it doesn't do today, but there are some that that are like, when you, like, put in some input Node, you're like, by the way, this is things that I could have done myself, but I I'm actually not doing. So, like, one example issue, define a a variable, like, const a is 10, like a string or integer that you put in.

Guest 1

That is just, like, constant. Right? Yeah. It can actually, like, reason about that and, like, move it into the place where it's used instead of, like, having it in the, like, the function scope where it it is continuously re instantiated, because of the, like, rerendering, for example.

Guest 1

to Next. Js for a second too. Like, given that you said this this stuff's all in

Scott Tolinski

in on preview and it's coming from the React team, does does Next need any modifications to take advantage of this stuff once it is launched? Or are people going to be able to use this with whatever compatible Next. Js version with the React version when it's fully released?

Guest 1

Yeah.

Guest 1

For sure. Like, you you have to, so it's using some APIs that are in React that are also not available in, like, React eighteen, for example. So, like, you you'll have to use React 19. So, like, today, you have to install, like, React 19 RC.

Guest 1

If you're using AppRider, you don't have to install, like, React itself because we we ship with, like, the version of React that that you need. Mhmm.

Guest 1

But in practice, you need React 19 because of, like, specific APIs. There is a polyfill for it, but, like, generally speaking, probably don't want to use it. I just use the, like, latest React, instead.

Guest 1

And the, and then the thing you have to do in next is that, like, it JS using a a bevel transform today.

Guest 1

Important thing to Node is, like, it's not a bevel trend. Like, a transform in the sense that you would usually think of, like, I'm going to take my input and give some output.

Guest 1

It does generate some output, but in between there's, like, a different combiner that is, like, has a reasoning about, like, Vercel AST. But it could also support, like, SOBC in the future or, like, any other, like, parsing and, like, ASD transform, basically. So on that side, like, it means that we have to add Vercel, because, like, we we've been on this journey to to move away from bevel for for the compilation, for Next. Js, using SWC instead, which is significantly more performant, for, like, individual file compiles.

Guest 1

But now we have to add back, Vercel for for this case at least until they, like, start, like, a a registry ride or something like that. That that's already been experimented with by by the team as well, by the React team. In practice, like, if you're using Next. Js, all you have to do is upgrade to the the React 50 or the Next. Js 15, RC and upgrade to React 19, which is something that they'll just tell you to to upgrade because, like, we we also depend on that. And then, you have to enable experimental React compiler through and install the compiler. Because, like, compiler right now is in in beta, so we want to make sure that you can upgrade it yourself so you can get, like, the latest improvements to it whenever you want instead of, like, being in lockstep with Next. Js itself. Yeah. That doesn't sound too painful,

Scott Tolinski

at all.

Guest 1

Yeah. It's, it's definitely a hard it's been a hard one to explain to people, as you've probably seen, online. So Wes released, server components in Next. JS, like, one and a half years ago or like slightly over 1 year ago now.

Topic 2 12:28

React server components replace getInitialProps and friends

Guest 1

1 half years ago for, like, the the initial, like, beta release of it.

Guest 1

We could try it out for the 1st time. I really like React server components Yarn, like, like, the like it's said in the Node, but, like, you render React components on the server slightly different from what you did before. So, like, Nextiva's, since the very first version had, service at rendering.

Guest 1

Service at rendering is, like, taking React components generating HTML.

Guest 1

React Vercel components is more of a, like, step before that that basically replaces everything that you did with get service or props, get static props. And then, like, it's able to render React components as part of that.

Guest 1

There's a much better and, like, deeper and, like, more high level explanation of this in, Deno talk at ReactCon. Pnpm definitely recommend looking at that.

Guest 1

And that that one talks about, like, React for 2 computers, which is like I'm running React on 2 computers. Like, 1 1 computer is, the, like, the server, basically. And it like, it doesn't start out there, but, like, it that's where I don't want to spoil the the entire talk. But it's like you basically end up with, like you have a like, 1 computer is your server. The other computer is, the the browser, and you can move logic between them in, like, whatever way you want because everything is 1 rendering model. So you're still using React. You use, like, pretty much everything that you're familiar with.

Guest 1

The only difference is that now React has this primitive that allows us to render on the server only, which is, like, something that we couldn't do before.

Guest 1

That unlocks some other, benefits. So, like, one of them is that you can now do data fetching on the Vercel, whereas Wes you don't need, like, special, like, framework API. So, like, we initially coined the get initial props pattern where you can Node, like, data fetching on the server and on the ESLint. And then, like, later on added, like, get service Node, get static props, get service side props, get static props.

Guest 1

Get service side props is, was just like a way to say, before my React rendering starts, I'm going to get like like, the framework is going to call this function. And then, like, I, as the application developer, can, like, write some logic that gets data from from anywhere. So that could be database or, like, an API or anything like that.

Guest 1

And then we pass those as props into the component.

Guest 1

Now with server components, that step is basically, like, replaced with a full React render. So that means, I can write components, those components can do data fetching, and they can render other components, as well as, like, interactive components that are like, the ones that you wrote before. So if you're familiar with React, like, it's it's just an additive, feature basically on top of everything that you already knew, that allows you to do even more than that we we would ever, like, have hoped hoped for when we started Next. Js, for example. Yeah. Which is, like, I can now do data fetch in my components or, like, deeper into the React tree.

Guest 1

I could share, like, libraries that do data fetching, and, like, provide components for that. And it is fully portable in the React ecosystem as well once, like, more frameworks started off Tingus. So, so one example of that is, like, Remix is looking into server components.

Guest 1

The, Redwood folks are looking into server components. And, like, at that point, you basically have a React's combined income. Right? That is encapsulating both, like, ESLint side behavior as well as Vercel side behavior.

Guest 1

And, like, one example of that is, I can build a, like, MySQL admin type React component Yeah. And that's portable between, like, all frameworks that use React, Scott of components.

Guest 1

And I it can pass in, like, props there and they can be interactive as well. Right? You can add, like, interactions using server actions or things like that as well. Yeah. It's it's really exciting to me that

Guest 1

Yeah. It's really cool to see the, like, obviously, like, when when we just released it, there there was, like, a lot of, like, pushback. Like, oh, things are getting more complicated.

Guest 1

Mhmm. Mhmm. Why do I need to know about this used client thing? Or, like, what are client components even? Why is this a new thing? And, like, those were not even, like, the new thing. Right? So they they were, like, the thing that you already had.

Guest 1

Just give it a name, basically. Right? And then server providers are the fully new thing where you had to be like, I want to use Scott. Right? Like, let me call use state so that I can, like, click this button and then, like, something is, like, shown or something like that. But We can't do that on the server because, like, obviously, the server, like, doesn't have this interaction model of being able to, like, render and then, like, rerender at some ESLint, as part of, like, running on the server. So, there's, like, new constraints on that environment. And and that was, like, what what was, like, especially confusing to people coming from, like, I'm only using, like, clients that react, and and they're, like, moving to I can only do certain things on the server type thing.

Guest 1

One of the cool things that we're seeing now at, like, at this point JS that the like, some of the CMS providers, for example, are starting to look into how can I provide better components? How can I provide, like, RFC enabled, features? Like, one great example is, like, payload CMS is, like, building their entire editor as React Vercel components with server actions and and all that. So what they allow you to do is, like, they they allow you to bring the entire CMS as a React component.

Guest 1

So you can, like, pull that in, give it a config, and a config is, like, unifying your React components, and it could be, like, client compo like, client components as well.

Guest 1

And those, can adjust behavior in the CMS itself. So you can, like, build, like, override particular, like, fields in in the CMS, which is really cool to see as well.

Guest 1

Similarly, like, Sanity is doing something like that as well.

Guest 1

It's just like, we're we're finally at the stage where, like, people are, like, coming around to it and and they're, like, seeing, okay, this this thing actually does make sense for my case or, like, it still doesn't make sense for my case, but maybe only the client's navigation optimizations or, like, specific features of React that are, like, enabled by this, like, transitions and and things like that.

Guest 1

It definitely feels like the React's gone. So, like, if you're into React, I highly recommend, like, watching literally all the talks, like, the in the entire live stream, which is, like, 8 hours long.

Guest 1

All of them were super high quality. I did it, myself. Don't do it in 1 1 sitting, I would say, but, like, generally speaking, like, the the talk that Dan gave clarified, like, circumstance click for me now. It's, like, the general thing I I heard from people.

Guest 1

And similarly, like, you're you're seeing, like, other, like, like, explanations of, like, how is this, like, making sense to me now in in, like, my particular case. So even if you're building, like, an SPA, you can still leverage, like, suspense and transitions and, like, async transitions, for example,

Guest 1

Yeah. So it's it's kinda like the misconception is, like, where you start migrating. So, like, the the the Wes you start migrating is, like, usually people are like, I'm going to use this for this small component on the page that JS, like, like, a button that doesn't need interactivity, right, or something like that.

Guest 1

However, the, the entire model is built on the other way around. Like, you're introducing Vercel components at the place where it gets service IP Wes. So that's, like, before the the actual, like, like, client components rendering.

Guest 1

What that means is that if you want to start migrating, the 1st place where you start is Node so much at this, like, granular level per se. It's more the the outer layer of the of the app. So when you start migrating, the first thing that you do, and there's many ways to do this, but, like, the the first thing that you usually do is, like, you go into, like, page dot d s x or page dot Wes. Usually, people like TypeScript nowadays, but, like, you can still use JavaScript as well if you want.

Guest 1

The first thing you do is, like, you you add, because you already have this page with TSX or, like, maybe you're using pages writer and it's, like, index.js or something like that. Yeah. So you create this page GitHub TSX and you don't add use client there. What you do instead is you write a component and then import another component and in that component you add use client.

Topic 3 21:51

Migrate pages to server components from the outside in

Guest 1

That's it. So what that means is that now the the outer layer is a server component, and the inner, like, component you're rendering in that server component is a client component.

Guest 1

So, yeah, like, the migration story, you already have a website, like, Syntax, for example, which was built on on Nextiva's, before.

Guest 1

Mhmm. You you basically just take that that, like, page you had in the pages writer.

Guest 1

And usually that 1 head gets static props to get service type props. So the way to think about it is that the component you're adding JS, like, page. Tsx, that one is the one that is doing the get server side props or get server side props that you previously did.

Guest 1

So instead of, like, having that specific, like, export function, get service props, what you do now is you move all that logic into this async server component that is the the page itself.

Guest 1

So you move all that logic down, and then you create a separate component that is just the the VNAV Wes, like, rendering before. Yeah. And that separate component, you add use client, and you pass all the props in same way that get service Bos passes them them in, like, that that we do in, like, Natchez's, internals, basically. Right? Which is just like you pass the props. Like, literally, you can just add the props object there. You spread on onto the, onto the item. Then, like, the next step there is, there's many ways to do this. But, like, you can say maybe that 1st component that that is using the props is also not interactive. It doesn't have use client or it doesn't need to use client because it, like, it doesn't have use state. It doesn't use, effects or anything like that.

Guest 1

So what you do at that point is you say, I move it Deno one one more level. Right? So, like, now we're Deno to maybe if if that page looks like the the the shell of the page, like, header, the the content, and then the footer.

Guest 1

Maybe only the the, like, the content doesn't need it, but the header and the footer do need, like, some interactivity that JS, like, use data, use, use effect.

Guest 1

So what you do at that point is you just move the use client, like, deeper and deeper until the point where you're like, it doesn't really make sense anymore to do this.

Guest 1

And then for the 1st, like, iteration of it, you're done at that point.

Guest 1

I think at least that's my opinion on on, like, migrating, like, these NexSys apps.

Guest 1

The the the misconception that people have is, like, my Nextiva app in Page Strider is bad. I need to move to AppRider to then, like, move everything to the server.

Guest 1

You don't have to do that. You can just use, like, client components. Client components are fine.

Guest 1

I think in the, like, what when we released server components in NextShares, like, we talked so much about what server components can do that, like, the it was lost that, like, client components are fine and they're part of the same model and you should be using them still. Like, there's no reason that the interactivity of, like, clicking buttons or opening menus or popovers or anything like that is server side behavior.

Guest 1

You can still use all the features of React.

Guest 1

ESLint components, are are totally fine, basically. Right? So at that point, you're done for now. And then what you can do from that point on is, like, you you can say, maybe some of the things that are in my header are actually things that can render on the server and they need data from the server.

Guest 1

So what you do initially is you're passing, like, maybe you're fetching all the data for the page, which is what you did in in get service props, synthetic props. You're passing all the data from the page, like, done into, the these, like, other components. Right? So you're you're passing into your header component, hey.

Guest 1

This is the data for the header, for example.

Guest 1

So what you can do it at that point is they can move the data fetching further down or or, like, if that if that's at all possible. It doesn't have to be that way. Right? Like, you can also say, I'm still going to do all my data fetching at the top.

Guest 1

But you do get some benefits from moving them down at that stage. So at that stage, you can say, I'm going to introduce suspense boundaries to show more, like, loading states in my page, for example. My content can come in later than the header, for example, that kind of thing.

Guest 1

So what you can do at that point is you can introduce suspense boundaries, like, slightly deeper in the tree while the rest is still ESLint components. Then you already get a slightly better experience because you can get the header, the footer, but then, like, the content has a loading Scott like a skeleton or or like some kind of spinner or anything anything you want really, because you can provide your own loading state there.

Guest 1

But, like, at that point, you've already improved the experience of your app. It streams in, like, faster. You you get, like, faster times first byte, slightly better core app files, that kind of thing.

Guest 1

And then you can say, maybe I need to start moving some of my other, like, parts of the header, for example, to be, partially server components, partially client components.

Guest 1

So one of the very interesting things is that it's a one way street, like, it's like a a door which is like a hole to the the other side of the, to the other machine, to the other computer, which is the the the client.

Guest 1

So now you can say in my server components, I can pass data to my client components. Right? I can pass data to the browser, for example. Even though there's still, like, random HTML on the server, I can just, like, pause, these props that I it's similar to what get started to prop Right? So you you just, like, do some data fetching and you pass it to the browser as well. And if you ever looked at the connections app, you you would see, like, underscore underscore next data,

Guest 1

Yeah. I I think that started with the get static props, get service props already a bit.

Guest 1

There Wes, like, a lot of, like, cases that you can model in this way. The only thing that was missing was, like, a primitive for, what do I do when I do interactions? So, like, interactions could be, like, ESLint set interactions, like, state and, like, effects and, like, on click and Yeah. Kind of thing. Or it could be interactions that involve the server. So, like, things that are, like, submitting a form or things like that. So we never had, like, strong opinions on what form library to use or, like, how to call forms. Like, what we told you instead is, like, Wes serves our props for fetching data.

Guest 1

It's, like, the the get Yarn. We never had the post part. Right? Like, we never had the, like, how do I post stuff to the server? Yeah. We introduced API routes for that. So API routes Wes, like, pages API.

Guest 1

You put something in there, you get, like, a Node. Js request response handler and then you can do produce anything you want because it's just like a Node. Js request response handler, kinda like express, basically. Right? And that allows you to, like, write some logic that's, like, update the database.

Guest 1

However, then you have to model this, like, logic of, like, I write to the database. Now I need to get the the new state back to the client. Right? So now at that point you're, like, I fetch the API, I get a response back. Now I have to read the response Bos, and then I do some mutation on the client side state. That that model is fine overall. And, like, if you have an external API or anything like that, you can still do that with App Runner. Like, there's nothing wrong with that as well. Yeah. You can totally build that.

Guest 1

You can even, like, use the server components to seat the data in and then, like, have, like, SWR, React Query, or anything like that to, like, revalidate the data and do fetches there and that kind of thing. That is, like, more like what we do. We've got service props. Right? Like, initial data and then you can, like, update it on the client side. Mhmm.

Guest 1

However, we also wanted to provide, like, a better way to do the entire cycle. So, like, the entire cycle is I render a page, you, like, you request a page, I give you the page and now you want to, to, like, search or, like, submit some form or anything like that.

Guest 1

And for that, we we work with React team and some of the folks that, that worked at Vercel on the React team as well to to basically figure out, like, what is this better API for this look like? So there there was, like, some prior art, like, Remix loaders, that that have, like, post functionality.

Guest 1

There's, like, SvelteKit that has, that has, like, a similar, like, actions type primitive.

Guest 1

And and we were, like, yeah, this makes sense, but I also didn't think it makes sense for, like, just for Next. Js. Right? Like, we we don't want to have, like, a primitive in in, like, Next. Js itself that is, like, we no longer need primitives for for, like, data fetching. Why don't we also have primitives for for, like, mutations? Right? Like, how do I do some kind of, like, I don't like, it it eventually was named actions. Right? So, like, how do I do some action that either updates the the database or updates some, like, state or anything like that? When that is done, I I see the state reflected in the in the UI. And really that's, like, a hard problem. Right? So, like, in on the surface, it sounds like an easy problem. It's, like, I just fetched the API, set the state, and then it's done. But then you forgot the, like, my my database is Node. My my API, response wave of 500, maybe, like, a network connection is bad and just, like, cancels and we have to retry and, like, all those, like, tiny, things that you have to think about. Yeah. All it's edge case all the way down.

Guest 1

And they're all not integrated to React. So, like, React is not aware of, like, any of that. Yeah. It it just, like, knows about the on click or the on submit.

Guest 1

And on submit is also not tied into React. So, once I throw an error in my on submit, it doesn't actually like, it it just goes into the void, basically.

Guest 1

It goes into Sanity, and that's, like, the Yes.

Scott Tolinski

There we go. Thing.

Guest 1

They're just plugging Sentry here.

Guest 1

Yeah. And that is the the thing that we wanted to solve. Right? So, like, there there JS this, like, interplay between maybe I want to show, like, optimistic Scott. Maybe I want, no optimistic state, which is which can be the case as well.

Guest 1

Maybe I want to submit and only show, like, the new state once it actually is fully done and rendered.

Guest 1

And how does that tie into the server story? Right? Like how does this tie into going back to the server and, like, getting some result back. And that's where we eventually, like, added saying Wes, that was, like, collaboration between React team, Nexia's team, and, like, a bunch of others, on on, like, this API to basically give us the ability to, like, we have this door to from the the server to the client, but now we have a door back from the client to the server.

Guest 1

And that door is, is 2 ways. So the interesting thing there is you you can, like, pass data, but in the same request, it can actually give you back the entire rendered, like, news, like, the new page as well.

Guest 1

And that's why we introduced, like, refill and this is Nexa specific. So, like, we found late pod, we found a tag.

Guest 1

If you call those in the server action, what happens is that once you, like, add a form that, like, takes your name, for example Yeah. And you click submit, it will call that server action, which is, like, a function that runs on the server.

Guest 1

But if you call resolidate pods at that point, it can actually rerender the page, like the page that you're specifying to also have, to basically rerender the entire page. So like at that ESLint, it means that in single round trip, you can submit new data, update the database and then automatically trigger NextGen to basically say, hey, render the entire page again because there's new data. Right? Like, the data has changed.

Guest 1

And then we can send it back and update the, the the page in place.

Scott Tolinski

Yeah. I had a Wes. You mentioned a couple times that, you know, working closely with the React team, and I know that there are React team members at Vercel. How how tightly does the Next. Js team, like, work with the React team typically? Is that, like, a a really close partnership? Is it a You guys gotcha. Downstream or Yeah. You gotcha. What's going on? Yeah. What's going on there? Yeah.

Guest 1

Yeah. It's really, not secretive at all. It it's just like, yeah, we have some folks like Sebastian, Andrew, and Josh that work on the React team. It's a separate team. So it's not part of NextShares, in the in the org chart, but we're, like, next to each other in the org chart at Vercel.

Guest 1

That's the React team at Vercel. Right? So, like, there's React team itself JS, like, many, like, external contributors as well as the the folks at meta that are working on, like, React Compider, React Native, that kind of thing. And and, like, a lot of the the, like, technical implementation side of things for for, like, some of the new features that you've seen have come out of Vercel as Wes. Like, some of the, like, more well known but also lesser known ones. So, like, if you've seen, like, Josh, Josh was part of the keynote, who works on the Wes at Vercel.

Guest 1

He gave a talk on, what was called React float, like one of the secretive code names. But that that was, like, the thing that allows you to, move any, like, element that should be in the head to the head. Mhmm. Mhmm. So if you've used, like, React helmet or NextHat or anything like that before, it's just part of React now and you don't have to think about it. And you don't have to think about it in so many ways that are so complicated. It's, like, reason about that, that you could just couldn't make it work before. Like, there was only like, the only way that we could do it was, like, making it part of React itself. Yeah. And and that the reason for that is streaming. So, like, for rendering the entire page, it was fine.

Guest 1

But now that we have, like, streaming, there there's, like, specific constraints that we have that allow us to to basically say, we need to start streaming the head early on, but then we need to fill in, like, the the blanks later, basically.

Guest 1

And adding a feature into React for that was super, important because now all all framers can just, like they don't no no longer have to worry about this. Like, in migrating to React server components, we we removed so many, like, features from Next Wes that we freeze that to mainly, like, juggle, basically. Like, head management, injecting script tags, injecting, CSS.

Guest 1

Like, that kind of thing is all, like, handled by React itself now. Mhmm. And that brings many benefits. Like, one of them is, like, that you get, suspense CSS or suspense, like, images and scripts, which means that React can hold off rendering anything until the CSS is actually loaded. Yeah. And that was, like, one of the issues that we had a ton because, like, we would inject into the into the hat, for example, and then, like, we would assume that it is loaded at some point, but we can't really, like, hold like, we can't tell React, like, hey. Don't render. Right? Like, React is in charge of rendering. So so that was, like, one of the main things that, like, we we ended up contributing to React itself. Async transitions were were, like, Node that, like, Andrew works on a bunch.

Guest 1

So we we end up, like, talking, like, day to day, like, like, our our teams end up talking quite often. And it's mostly because of, like, behaviors that, like, our teams ESLint while implementing some of these features that that, React team has thought of and and want to implement.

Guest 1

A lot of it's, like, ironing out, like, APIs and does it actually make sense and and that kind of thing.

Guest 1

And then we also have the like, similar to Meta, like, we're also dogfooding, like, Next. Js at, at for sale itself. So, like, for sale JS using, like, almost always the latest version of Next. Js. Node. And it brings, like, issues with it as well because, like, obviously, we're the 1st ones to hit bugs and and that kind of thing. Yeah. But man. Yeah. In doing so, we also can prevent, like, other people running into them using, like, early release, cycles and that kind of thing. So I would say, like, overall, React team is pretty large. We end up, like, talking to other, like, people, inside of React team for some of the, like, server components and, like, server actions and transition stuff. Like, I end up talking to to Andrew and and Josh quite a bit. Sebastian is, like, more we're doing, like, architecture works, like, making sure that like, he he architect the app rider, as Wes. So we work the bench together on, like, what does this router look like? How does this thing tie into React Vercel components? Like, Node one had built a router that that is, like, compatible with server components yet at that point. So we we had to, like, figure out and and transitions as well, by the way. So, like, React transitions was, like, specific thing that we we had to add support for, like concurrent rendering, that kind of thing.

Guest 1

So we ended up, like, building a a special writer that wasn't, like that hadn't been done before.

Guest 1

Zinguella love prior art on on looking at this, except for, like, what they build at meta as well,

Guest 1

Yeah. I don't know when. I don't know I know if it's like, as far as I'm aware, they want to add it. Yeah. But, and I'm pretty sure I'm not leaking anything with this. No. No. I've I've asked publicly before, and they say, yes. It is the plan to make them work on the client as well. As far as I remember the late I am not fully in the know of on this, but, like, as far as I remember, the latest, like, blocker on this was a async context.

Guest 1

Yeah.

Guest 1

I'm I'm not sure if you've seen that proposal. It was basically, like, async local storage, which is not local storage.

Guest 1

Like, the the quick explanation is async local storage is a way to basically pass data across, like, the the async, context stack.

Guest 1

The way that I've explained it to people is, like, it's kinda like React context where you can, like, pass values, like, somewhere higher up in the the, like, tree of, like, the JavaScript running. And then you can read those values further down.

Guest 1

And async context is the the official, proposal for, like, bringing that into the the JavaScript spec.

Guest 1

I'm not sure why that is a blocker per se and, like, if that even is a blocker. Yeah. I wasn't understanding why that was a blocker to have it. But I mean, that's something to do with, like, rerendering. And, like, if you create a promise, that promise needs to fully resolve at some point, and and that needs to be tracked in some way, but I'm I'm not sure exactly. Like, I I'm not in Node this. Okay.

Guest 1

Yeah. It it's literally cookies and headers. So you call cookies or you call headers, and you got, like, a cookie store, header store back, like, header object. React uses it for the the the cache API as Wes. Like, the the new like, the the one that you can call, to do dupe in the same rendering, on on the server.

Guest 1

I think it's, like, part of that, actually. Like, the the React React cache doesn't work in in the same way if you need to, like, across the this rendering, basically.

Guest 1

So that might be one of the the blockers. Because otherwise, like, if you do data fetching and you warp to dedupe it in some way, you just can't because it it's just not, like, tracking that in in this way. Mhmm.

Guest 1

So so maybe something like that. I'm not sure. Yeah. Okay.

Topic 4 45:41

TurboPack is a rewrite of webpack for faster builds

Guest 1

Yeah. It's it's definitely a a long journey on a Webpack.

Guest 1

When we released Next. Js, it it was initially built on Webpack. And this JS, quite some time ago. So 2016.

Guest 1

Mhmm. We we've been around, as they say, in terms of framework land. Like, we we survived for a long time.

Guest 1

Similar to the rest of the industry, like, basically, what what is happening, like, over these 7 years is that people start building larger and larger and larger apps on, on on these frameworks. Right? So like it's not just on action, it's also on, like, Nuxt and other frameworks. Mhmm. So what we see is that people just end up pulling in more more modules, more Npm packages, more, like, larger, like, UI libraries. So, like, URL libraries, you might you might think of, like they they're probably shipping, like, 100 components. Right? But, like, if you look at some of the newer, like, libraries, like, I'm not gonna try anyone here, actually.

Guest 1

Like, some of the new libraries are shipping, like, 10,000 reexports. Exports. Right? Like, they're shipping, like, 10,000 different components that you can import.

Guest 1

But in order to process those, we need to compile all those 10,000 modules and then say which one JS actually used. And, like, skip like, if you count it, like, skip over a bunch of these. Oh. And sometimes you do, like, import star as, like, some library name and that means we have to compile all of them. Right? Like, that kind of thing. So as the complexity of, like, JavaScript applications keeps growing, we're we're basically, like, hitting these limits of of Webpack itself, of, like, some of the the newer vendors even.

Guest 1

So what what we started out with is, like, we're we were basically evaluating, like, does it even make sense to keep, like, running a Next. Js or or, like, running Next. Js on Wes or should we use some of the, like, newer vendors that came out or anything like that? And then, when we look at the complexity of the apps that we already get, with Nexus today, as well as all the complexity of, like, extra bundling for Vercel components, client components, like, multiple passes.

Guest 1

Maybe you want to deploy on the edge or Node chairs, and then, like, there there's, like, just, like, a complexity in in the amount of modules that get processed. Mhmm.

Guest 1

So one example of that is, like, if you have a client component, like, as JS you probably know Node maybe another one knows, client components render on the server as Wes. Yeah. To render HTML to to basically speed up the initial render.

Guest 1

In order to get there, we need to take your module and your module is like importing, say like large icon library that is the like 10,000 React ports, for example.

Guest 1

Now Wes need to process those 10,000 modules for the server as well as for the client because they're in different conditions. Like, they they get, like, different optimizations. They need to be, like, maybe those, like, for the browser needs to be Wes 5 or just, like, the the server can be, like, whatever. Like, Node just firstly running, that kind of thing.

Guest 1

And that means we have to process all of them pretty quickly.

Guest 1

But what it means to practice it instead of 10,000 modules, you're processing 20,000 modules. Right? And and that, like, stacks up really quickly as you get, like, more and more modules into your client components, into serve components, that kind of thing. So we really have to build, like, a a solution for how can I, like, optimize these very large graphs and, like, make sure that everything is, like, processed in a way that is, reliable as Wes? Because, like, for Webpack, like, doesn't support running both server and client compilation in the same compiler.

Guest 1

So what we do for webhooks is we run 3 compilers.

Guest 1

Wes run 1 for the the server, 1 for the client, and 1 for hatch. Like, hatch is the, like, special target where where, like, you get a slightly more constrained environment.

Guest 1

In order to do that, like, to to coordinate that, like, we have to manually coordinate.

Guest 1

Like, you start now, you start then, type thing. Like, this one is done. Now we need to trigger this other one.

Guest 1

And and we just knew that that wasn't, like, as reliable as we wanted to be.

Guest 1

So eventually, we we started building, TurboPack or would turn into TurboPack, which JS, like, a single, like, the idea was to be we create a single module graph that can span the Vercel, client, server components, client components, edge, like, whatever you run into.

Guest 1

And it can just process all of these modules, in parallel because, like, Wes is limited to single core right now. You can you can add some parallelization, but, like, it it's not super it doesn't speed up things that much.

Guest 1

Wes leverage all the the latest, like, compiler technology or, like, transform technology, like, SLBC.

Guest 1

Yeah. We implement caching from the start. It's like one of the issues that, like, Webpack had from the start was that they didn't start with, like, it was a research project by Tobias. Like, the the original story of of Webex is pretty interesting as Wes. But, like, it turned into this thing that everyone used, but in in this, like, from the start, it wasn't built to be this thing that everyone used.

Guest 1

So over time, they had to, like, optimize a lot, add more caches, add ad hoc caches into the system, add disk caching on top of it, and things like that.

Guest 1

And what we did for TurboTax is we started out with the caching layer. Like, we we need to have, like, a task runner caching layer that is, like, as solid as it can be so that you basically get reliability from the start across, like, parallelizing across, like, many, CSS.

Guest 1

Yeah. Like, caching for disk, that kind of thing. And then we can build, like, anything we want on top of that. So we we basically build, like, a library called turbo engine. Mhmm. Turbo engine is the thing that is, like, powering, all of, all of Turbo Pack and, and potentially in the future also Yarn of the Deno, because they recently rewrote everything in Rust.

Guest 1

And the way that this works is that anything that you write in in Rust, you can, like, basically annotate with this, like, function directive from turbo engine and that makes it cache by default automatically.

Guest 1

It it knows when to rerun Wes you, like, do this IO, for example, and it it just, like, automatically works out of the box with that.

Guest 1

What you get with, like, having this caching layer is that now anytime you make a change, we can quickly recompute, does this thing need to be, like, what thing changed and what thing needs to be recomputed? And we only recompute that, like, narrow part of the graph.

Guest 1

So that means that anytime you make, like, initially initial compile, it still, like, compiles all your modules. Right? Yep. But then when you make a change, it can just, like, recompile only the CSS or it can recompile only the, like, tiny part of the JavaScript that needs to be recompiled and then applied it on the server, like, applied on the on the client through, like, fast refresh or anything like that. Okay. It's like one of the the the the goals Wes also to bring, like, fast refresh down to to, like, sub 100 milliseconds or so. Oh, yeah. Oh, that's awesome. For for, like, pretty much all changes, except for server components, because server components also needs to render, like, on the server. So we re re re enter the entire page. In that case, if you're changing, like, client coupons, it's, like, near instant, basically. Right? The problem we had with Webpack was that, like, it's not near instant when you have these, like, 20,000 modules or 30,000 modules. Yeah.

Guest 1

Because that, like, graph of changes is, like, massive in in the the Webex case. So, it would take 1, 2 seconds before you see anything on on the screen. And if you were unlucky, you would get, like, a much larger recompile and and it would take much longer than that even.

Guest 1

So that was one of them. And then the other is that most of the things that people are complaining about are not recompile times actually. It's it's the initial compile. Mhmm. So which is like, I boot up the server, I go to a page, how long does it take me to show that page? And we were compiling those on demand. Right? So that means, we're basically shifting the work from, like, you boot up the server, and then you wait for 5 minutes, which is, like, what you would get with some of the, like, initial, like, versions of, like, compilers that were built on top of webpack, for example.

Guest 1

Instead, what we do is we we only, like, start compiling where you actually request, like, a page and we only compile the the stuff for that page. For that, the parallelization JS, like, a big, optimization as well as having persistent caching. Yeah. It's like parallelization we have nailed down and that works. What is really interesting is that for for the Vercel website, what we saw is that, on on some of the slower pages, webpack, with a cache, like disk caching would actually be 10% slower than Turbo Pack doing everything from scratch.

Guest 1

So that that was, like, one of the interesting, like, wins that we had in, like, comparing it to to, like, running it against, like, cold webpack would be even, like, better, obviously.

Guest 1

But the, yeah. So that was, like, one of the things that I was really interested to see. And this is without us having persistent caching ESLint.

Guest 1

So that's what we're working on right now, to have, like, persistent caching so that if, Scott starts to work on the syntax website, like, he makes some changes, might not be working pnpm every day. Right? So you make some changes, you you push them to, to production, and then you you've, like wind down the server. So you you, like, control c and you just go ahead with your day. And the next day you come back and you start up again, you have to wait, like, this initial compile time again because there's no discussion yet. Now when we have this discussion, you can just, like, go from the point where you left off. Right? So, like, the the last time you ran the the compiler.

Guest 1

And now you might be thinking like, oh, but this might make sense for builds as well. Right? Because my builds are in the cloud and Yeah. Maybe they can, like, store all that and then, like, restore it and make my builds almost instant because you just told me about this, like, smaller graph that can just recompile changes.

Guest 1

Well, that yeah. That's the case. So, like, we we can do that with TurboTax as well. Nice. Once we have TurboTax built Yeah. That's something we work on right now. It is, like, 83% of test passing on on the Nexus, mother repo. Wow. And, what that means is, like, your recompiles for for production builds are going to be not blocks on recompiling the code itself anymore. Like, they're gonna be, like, blocks on, like, static generation being slower or things like that. So you put that together with Turborepo, which may skip all your Npm installs and all that, and you could potentially be having,

Guest 1

Yeah. The the idea is I mean, like, personally, I grew up in the, like, FTP era. Yeah. Right. Yeah. Like, I I just throw stuff on onto, onto the platform, which JS, like, I'm literally editing in in production. Right? Yeah. In my Dreamweaver, like, editor is just, like, connected to to production. Yeah. FTP right into the box and hit save. Delete. Yeah. Yeah. Delete.

Guest 1

Vercel, like, there's, people that, that I've talked to that that are slightly younger than me, like, literally slightly because I'm not that old, but, that just never did that. Right? And they just like they're like, yeah. My compiles take, like, a few minutes, and then, like, it's live. It's still, like, magical. Right? Like, Mhmm. It's one of the things that drew me to to working at Vercel. It's, like, so magical when you did this, like, Node command and you would just see a live URL. So it's something like similar to how you did it with the the FTP, Bos as well.

Guest 1

However, now you get all this, like, benefits of, like, isolation of environments. So you can, like, send this to your colleagues and that kind of thing. Yeah. Without actually bringing down fraud. Right? Like, changing things that that are, like,

Guest 1

I think I have, like, 1. I'm kinda into, sci fi series. Oh.

Guest 1

And if you're into sci fi series, I highly recommend Apple TV, plus, which is like, for some reason they're just keep they keep putting out more sci fi series.

Guest 1

We we don't have particular like here in the Netherlands, because I'm not from the US, like they don't have like specific like sci fi channels like the the sci fi channel itself. Mhmm. That kind of thing. It's like a lot of that JS it's, like, on Apple TV. Oh, yeah. I don't think I realized how many different sci fi shows they had because I I guess JS silo considered sci fi or,

Scott Tolinski

foundation for all of mankind in creation?

Guest 1

Wow. Yeah. It's it's, it's pretty crazy. Like, overall, I I'd never thought of, like, Apify before, and, like, I opened it once, accidentally. I was like, this is interesting. There seems to be, like, quite interesting, like, series on there. So, like, silo JS pretty good.

Guest 1

That that site but it's all Vinay made a lot of deals with, like, book, authors as well because, like, they're just based on the books a lot.

Guest 1

They're now also getting, like, into the the, like, documentary about controversial thing that that happens, like, like, the Hollywood con queen, started watching recently, which JS, by the by the creators of the fire festival Oh, really? Documentary and things like that. That. Yeah. Those are there there's some pretty good stuff there. So if you're interested in in sci fi, Foundation is really good as well. It's it's definitely, like, they keep bringing out, like, more of those.

Guest 1

I'm not sure. Like, there must be someone in, like, Apple HQ that's like, I I love sci fi anymore.

Scott Tolinski

I bet. Yeah. Yeah. I wonder if they have the serious data on on podcast listens too because I know that Hollywood Scott Queen podcast was really

Guest 1

really hit. So I wonder if they saw that and were like, oh, this would be a good docu. Cool. Awesome. And shameless plugs, what would you like to plug to our audience? The Turbo Pnpm RC or, like, the, yeah, the Turbo Rec RC. Yeah. So we we have the Nexus 15 RC, which is, like, new features using, like, React 19, some caching improvements as Wes. If you, like, didn't like the the previous caching, we we disabled most of it, and it's all up there now. Mhmm. We're we're definitely, like, listening to to feedback there.

Guest 1

It was just, like, too complicated from the start. Like, we tried to make it very similar to, like, pages rider with, like, automatic static generation but it became, like, complicated in the cases where you do want to be dynamic. Right? So, like, they're just, like, better defaults now. You can opt into more static behavior once you want to, like, optimize more, basically.

Guest 1

It's purely based on feedback, and and, like, just giving people the the thing that they want to to, like, build better websites. Besides that, yeah, is an RC for development now. So that means please try it out. If you have any issue, like, literally any issue, if it's slow, anything like that, tweet at me or, open an issue on GitHub. We're actively working on it. We we have, like, 30 open issues, left so far before, like, development is fully Deno.

Guest 1

And then we'll shift to, to, like, work on builds as well and, like, bring you that, like, persistent caching and, like, FTP like builds and things like that. So I'm excited for that.

Guest 1

I have 1 more, shameless plug as well, which you'll you'll like. Yeah.

Guest 1

No worries.

Guest 1

It it's about Sanity, actually. So Oh, okay. Let's hear it. I'm not sure if you know, I think his name is Luca.

Guest 1

So Luca on the, like, Sanity, Next Genes SDK team, has been doing some contributions to Next to basically allow us to, allow Sentry to to reason about service and errors. Yeah. That are then sent to the client with a special, like, digest. I'm I'm not sure if you've seen that in in actions, but, like, we need to hide, like, all the the data. Because we don't want you like, a service error, you don't want that to end up in the client because, like, in some cases, that contains anything that could be secret. Mhmm.

Guest 1

But now Sentry can actually reason about that particular, like, error that happened on the server as well as the thing that happened on the ESLint. So that thing you saw on the ESLint. So you can actually mark the session as, like, this is the error that was related to that particular, like, digest. So you can search for the digest in in the UI as well, which is pretty neat.

Share