Kaelan Cooter: Hello. Welcome to PodRocket. I'm your host Kaelan Cooter. Ben is absent, doing important startup stuff. Here we have fellow engineer Chris Potash, and our guest today is Miško Hevery, the crater of Angular. Miško Hevery: Hi. Kaelan Cooter: Hi, how are you doing? Miško Hevery: I'm doing good. Yourself? Kaelan Cooter: Fantastic. So here we want to hear about all of your new projects after creating the most popular library that changed Frontend. You want to start us off? Miško Hevery: Sure. I don't know if we'll call it library. I think it's more of a framework. JQuery is a library, right? And I guess it's a pedantic difference, but the difference is, are you in charge of calling it or is it in charge of calling you? Right? So frameworks like Angular definitely are in charge and they call you in whenever they feel like it's necessary. Kaelan Cooter: Sure. Miško Hevery: Yeah, Angular was created back in the day, when there weren't really any frameworks, right? It was a Wild, Wild West of building front-end UIs. JQuery was a state-of-the-art, and it was amazing. JQuery is still, to this day, probably the most used library ever, but I think Angular filled a niche that didn't exist, and so it became super, super popular based on that. Kaelan Cooter: So Angular has been around for quite a while, and even went through a pretty monumental rewrite. Can you tell us about the design differences, or I guess you could say, lessons that you've learned from Angular, and how do they influence what you're working on today? Miško Hevery: Yeah, so three years ago I was giving a keynote at NG-Conf, and I explained a particular problem, and I'm going to do some visuals here. And the particular problem that I explained is that all of our current generation of frameworks are, what I termed back then, replayable. And what I mean by that is that frameworks start in this category here, where they server-side render, and they really want to get into the interactive stage, right? They want to make sure that you as a developer can go and click on buttons and do something on the UI. Miško Hevery: And so the question is, how do you get from here to here? And so the server-side rendering goes and sends the HTML to the client where you need to bootstrap it, and this is the hard part, because in order to bootstrap the application, it's easier to go backwards. It says, in order to have the application be interactive, what we really need is we need DOM listeners, right? We need DOM listeners to be installed all over your UI so that the application actually is interactive. Miško Hevery: Now, the DOM listeners themselves are actually stored inside of your templates. So we actually need to have the framework run the rendering phase of the application for the page to be interactive. But in order to run the rendering, you need to have the state of the application, right? Because the rendering is really emerging of the state and the templates, and so in order to have the state and the templates, you really have to download essentially all of the app, right? So this fat arrow really represents this idea that in order for a framework to bootstrap the current application that you have, you essentially have to download all of the code. Miško Hevery: And the reason I call it replayable is because the framework has to replay all of the work that the server just did, right? The server executed the rendering phase. The server executed the fetching of the state and the merging of the phase and producing the HTML. All of this work that that is shown over here just happened on a server, but none of it can reused, and so the result is that everything has to happen on the client and the client has to replay everything. And I'm going to argue that all of the current technologies that we have today fall into this category: that they are replayable. Miško Hevery: And when I was giving this talk three years ago on a stage, or maybe it's more like four years ago now, I was talking about this idea that we really want to have frameworks to be resumable, and so that's the bottom part of it here. And so we started with the same place. We server-side render, and we have to go to the bootstrap. However, the big difference here is that in the case of a bootstrap, it's super tiny. It's less than a kilobyte and less than a millisecond to execute. So it almost is nothing. And you can go directly from here to the interactive state. And the reason you can bypass all of the stuff in between is because the resumable frameworks can serialize all of the information that is needed by the server and take you over to the client. Miško Hevery: So I was presenting this idea of reasonable framework three years ago, and I was hoping that something would happen in the industry, and somebody would take me up on that and would actually go and start building something along these lines, but nothing of course happened. Miško Hevery: So about six months ago, I got into chat with a company called Builder.io, and we specifically were discussing this particular problem. And the thing that they're describing was, hey, we're trying to build these super-fast e-commerce websites, and we do everything right. We worry about the size of the images. We have CDN cashing. Everything you can possibly imagine, we do right, and we have actually tooling that generates all those stuff. So it's not like we rely on engineers to make sure that the right thing happens. We have tooling to make sure that everything happens correctly. Miško Hevery: And what we discover is exactly what you're describing here: is that we get stuck in this replayable world, that in order to get the page to be interactive, huge amounts of code has to download, and we have this double downloading problem, right? Once we downloaded everything as HTML, and now we are re-downloading everything again as JavaScript, and not only are we re-downloading everything, we are rescuing everything that the server just did. Miško Hevery: And so the discovery they had is that no matter how much they tried to make sites amazingly fast, and by amazingly fast, I mean, getting awesome page-speed scores, and no matter all the best practices that they did, they would end up in this bad situation. And you would think that this is unique to a particular thing, but if you look at the e-commerce in general, you'll notice that just about every website has a pretty bad score on Google page-speed. And the reason for that is because, well, they're all using the same technologies, right? And because everybody's using the same technology, they're ending up in the same exact problem. Miško Hevery: And so this gave birth to this idea of Qwik, Qwik being a different framework that specifically worries about: how do I make the whole thing reasonable? How do I get into the situation where I can do work on a server, place a CDN over here so everything is fast, have the bootstrapping code that is absolutely the teeny tiny, almost nothing to speak of, and directly take me to an interactive mode? And only when you start interacting with the page, do I then download more code and more templates, and only on as-needed basis, rather than having this huge, big arrow here representing all of the code at once, having these small arrows everywhere in the life-cycle, bringing code on a totally as-needed basis. So that's the idea of Qwik. Kaelan Cooter: So basically like a fundamental rethinking of how server-side rendering works? Miško Hevery: It is a completely fundamental rethinking about how it works, and I really want to stress the difference between this replayable world that essentially we are in today, and it doesn't matter which framework you choose, you always end up in this replayable world versus, this resumable world of the server actually serializing all of the information you need into the HTML in such a way that the client can just resume and continue. Miško Hevery: Now, there's a second part we discovered when we started working on this. So it's a bit of a tangent. I apologize. And then what we discovered is that even if we render the page using Qwik and we got these amazing scores, the moment you start installing Google Tag Manager or HubSpot or any of these third-party tools that everybody does, it gets destroyed. Miško Hevery: As a matter of fact, if you create a blank page, nothing on it, just completely blank, and you throw in Google Tag Manager, that alone puts you on a precipice of what Google page-speed will consider 100 out of 100. So that alone is what trips you over, and as you keep adding more and more scripts, the situation gets worse, and there are e-commerce websites where, I'm not exaggerating, they have 15-plus scripts that they install, and obviously that results in a horrible performance. Miško Hevery: So what we realized is that, yeah, you could go and chase this mythical 100 out of 100, but unless you can solve the third-party problem, you can't really make a good site. And so this is where the second project came in, called PartyTown. And the beauty of PartyTown is that we know how to execute something like Google Tag Manager without modifying any of the code in a web worker. And this is something that everybody has been trying to do forever, but nobody knows how to do it, and the reason for that is because, well, the communication channel between a web worker and the main threat is asynchronous, but all these libraries are written in a synchronous fashion, and so they just don't want to execute. Miško Hevery: And so the tricky part in PartyTown was basically tricking the browser into believing that the communication channel between the main thread and a web worker is indeed synchronous so that all of this code can actually run. So now, if you can combine these two things together, if you can combine PartyTown and you can combine Qwik, you can actually get in a situation where no matter how big your page actually gets, you will get 100 out of 100 on a mobile device and unbelievably snappy websites. And so this is the goal that we're trying to get to. Kaelan Cooter: That's great if you're one of those developers that that's your primary concern, but I guess the counterpoint would be that not many developers actually care about getting 100%. It's more of a... Miško Hevery: Well, developers might not care, but certainly the companies care, right? The companies spend a lot of time and effort, and I think Google has basically said now that they're going to penalize or rather grade... Your SEO ranking will be dependent in part on your page-speeds course. So if you have a competitor that is equivalent in all other aspects, but you can be faster on your page-speed, you will be ranked higher, and so I think that's important. Miško Hevery: I think the situation we're currently in is that all websites essentially suck, and so it's like cold war in a sense like, we all suck, and as long as we all agree to suck equally bad, nobody's going to get penalized. And so I think we're in the situation. The goal of Qwik and PartyTown is to break out of the situation, right? To say, hey, if we can build some amazing sites that are super quick in terms of startup speed, not in terms of actual running speed, in terms of startup speed, then we can get in the situation where it's going to start an arms race, and people will actually start caring because they'll say, "Hey, it is indeed possible. Look, some somebody else has actually done it. And not only has they done it now, they're getting advantage of SEO that we're not getting." And so now it actually creates an incentive. Miško Hevery: The other thing I wanted to point out about developers is that developers use existing frameworks, and these frameworks come with philosophies. And the problem is that all of the existing frameworks, they basically say, "Lazy loading? Not my problem." None of them actually have lazy loading as a core tenant of what they do, it's not a fundamental primitive of what they do. And you can see this in everywhere, Angular, React, Vue. It doesn't matter which one you pick, they all say, "Of course we do lazy loading, just go use dynamic import or this or that. Not our problem. Figure out some other way of doing it. Of course we're compatible." But the truth is that unless you write the code in a specific way, in a way that is friendly towards these dynamic imports, the whole system just doesn't work. And you'll actually discover that it's actually quite difficult to do. Miško Hevery: I actually have a demo that I can show you about this. So this is where we are today. And I think we're what I call a monolith kind of a stage. I basically say that all of the standard frameworks are kind of in this category. And the way we start off is we start off with server-side HTML is sent from the server and rendered by the browser. And so you essentially end up with something like this. You have your application, each box represents a component. And currently it's gray because I want to demonstrate the fact that it's not interactive, it's non hydrated, and it's essentially inert. And so the next thing the browser has to do is it has to download the application JavaScript, you have to go and download all the code. Miško Hevery: And then once you download all the code, you have execute the JavaScript. And that causes couple of these boxes to turn blue. Because this is where you're essentially installing the listeners and making these boxes fully interactive. Now, the thing is, developers are trying to add lazy loaded boundaries. And so they thought that they're helping the situation and they added a lazy loaded dynamic import in these locations, as you can see over here. But actually, it doesn't help. Because as long as the component is visible on a screen, the lazy loading boundary doesn't do anything because a framework just has to cross the lazy loading boundary, download the missing code, and finally execute and hydrate all of the components, and eventually gets you a fully interactive page. So a lazy loaded boundaries are good on route level, but they're not actually helpful on the page that I'm actually viewing. Miško Hevery: And so the problem is that if you have a application that is super complicated, like for example, Vrbo, I have some friends who work there and we were just discussing how much effort they actually spend in making sure that the landing page is fast. It's specifically because they have this problem that have huge amounts of code that has to go hydrated on the landing page. And there is no shortcut, in the sense that all of the code has to be downloaded and execute because all of it the user could possibly interact with. So now there's a new kind of a thing called islands, and this is popularized by Astro. And the idea is that your app is divided in kind of these yellow boxes, and each yellow box is actually in a independent application. And so if you go and interact with a particular box, then you're only rehydrating this box, but not the rest of it. Miško Hevery: And so that's a great improvement. However, you have a new set of problems. And a new set of problems is that while here you have a single application, and then as a result, components can easily talk to each other. One of the things that frameworks provide is they inter-component to communication. The moment you have multiple applications on this page here, frameworks don't provide an inter-application communication channel. So you need to have a way of actually having these components communicate. So for example, if I go interact with the middle one, certainly it hydrates and everything interacts, but now how does this component talk to the upper page up here? So now let's get back to Qwik. And so one of the things that Qwik wants to do is it wants to be completely lazy loaded, in a sense that all of the components are inert, they're grayed out. And only when I interact with the particular component, only that component gets rehydrated. Miško Hevery: So only the code associated with that component gets downloaded. Now, the thing to point out over here is notice that me interacting with a particular component does not force the parent components or the child components to be rehydrated. So when I interacted with this component, only that component gets interacted. When I interact with this component, only this component gets hydrated. And notice, there's components in between the parent and this sub-child that are actually inactive. And this is where the power comes in. While in the original application here, we had to basically bring all of the components into hydrated state at the very beginning, and there was no choice about delaying anything. In Qwik, you can actually delay things by piecemeal. So you can think of Qwik as being kind of Astro and steroids, where every single component is its own little thing. But here is the difference, while in Astro, because of your separate application, you don't really have a good inter-application communication channel, Qwik provides this communication. Miško Hevery: And so Qwik, for example, understands that if I interact with this component here, this bigger component over here has to get awoken. So notice when I interact here, the other component also got woken up. It's because Qwik understands this communication channels and it can do all of these operations. And similarly here, if I click here, notice one of these components up here will also wake up. And that's kind of the big difference is that not only can Qwik rehydrate itself on a individual component at a time basis, but it also understands the relationships between the components and the communication channels between the components. Speaker 1: So I guess my number one question is this sounds pretty great, what's the catch? Miško Hevery: What's the catch? Okay. It's a good one. Everything is a little different. So you of write your code in a slightly different way. And we can go into many, many details about this. Actually, let's do another demo. Okay. So here's a standard to-do application. Let's see, let's open it up. And we have our component. I will kind of explain everything in a second. The cool thing here is that here is the state of the application all serialized into here. And the other cool thing here is that really only about one kilobyte of code actually executed so far. And only thing we executed is we set up a global listener on the route, on the document itself. And it basically says, "If you click or interact with the page in any way, the global listener wants to be notified." So if I go into this input box right here, that that's this input box right here. Oh, I'm going to make the font bigger. I apologize. Here we go. So here's the input box right here. Miško Hevery: When I go and start typing, notice it has a property that says, "on:keyup." And this is what the boot loader, which is one kilobyte, looks for. And it says, "Oh, if you start typing here, I need to go and download this piece of code here." In this case it's a qMockModule#symbol_9. And so it knows that it has to go download this piece of code and execute it. That's all it knows how to do. And if you look at the script tag, the moment I click on something, that script tag disappears. That's because me clicking on or activating this thing and downloading this piece of code, caused the system to kind of consume the state of the application and then distribute it wherever it belongs. So what's the catch? So let's go to what the code looks like. Miško Hevery: Oh, sorry. Wrong file. Here we go. So here is what the code looks like. I don't know how about you, but I think one of the things that React really has done well is the fact that React components are extremely lightweight. In other words, they're essentially the cost of a function. You could just pull them out, put them anywhere, extract, et cetera. And I think that is a big reason why React is so popular, is just because it's so easy to make components. So I've tried super, super hard to make Qwik components as simple as react. However, there are a couple of constraints. And the specific constraint is that React and many other frameworks, not just React, I don't mean to pick and React, have this particular problem, is that they heavily, heavily rely on closures closing over other variables in state. Miško Hevery: And the moment that happens, these functions essentially become unbreakable. It is impossible for the system to disassemble this stuff into pieces. And I think a lot of people have this idea that one could, at least in theory, write a sufficiently smart compiler that takes your monolithic application and breaks it up into pieces and allows you to lazy load it. I'm actually of the opinion that's a myth. You cannot have that because we already have a sufficiently smart compilers and those are called developers. And even if you task the developer with the goal of saying, "Take this application, it's too big, it's monolith and go break it down," you will discover that you'll be faced with many months, if not many years, depending on the size of the application, of effort to refactor this and redo it. Miško Hevery: And the answer isn't having better tooling. The answer comes down to refactoring the code in a way so that it is possible to lazy load it and break it down. So the big difference with Qwik is that it is designed from the ground up to be done in such a way that things can be broken up. So if you look at this to-do application, it says, "Here is a piece of code which knows how to render itself, a standard JSX." All of this stuff is pretty straightforward. Now what's interesting here is that notice that you'll have these Q hooks all over the code base. And what the Q hook essentially is, is a dynamic import. And what it allows it to do is that it can go and highlight it, the tooling can highlight this and can go and create a constant and enclosing scope. So in this case will be to-do app on render. And where did it put it? Oh, it put it up here? Yeah. That's not where I would like to put it here. Miško Hevery: So let's put it next to it. Okay. So it is able to break this out, like so. And it can place an export in here. Oh, now you complaining that the order is wrong. Fine. Okay. Here. Make you happy. So we can do this kind of refactoring. And the reason we can do this kind of refactoring is because all of these Q hook functions are specifically designed not to close over any variables. And once this function is refactored into a separate thing, we can move it into a separate file, we can break it out into lots of different files, combine files together, keep statistics and the order in which the user needs them and so on and so forth. So the whole trick here is that Qwik forces the developer in writing code in such a way so that tooling can indeed do all of this trickery to move the code around, something that I'm going to argue is not possible with the existing set of systems. So that's basically the idea behind Qwik and how it works. Kaelan Cooter: Doesn't seem like too much of a barrier. Miško Hevery: We tried... So this is like our third iteration of this API. It is definitely simplified a lot. And we tried super, super hard to go after this goal of having very lightweight components. But of course, they're not as lightweight as React, and they cannot be because if they would be, they would have the same issue, like other framers would have, which is that we wouldn't be able to refactor and move things around into pieces. Miško Hevery: But yeah, I agree with you. I don't think that the barrier to entry is that high. It's very low. And we specifically designed it to be as low as possible. And we can do this kind of trickery. Miško Hevery: So if you look at a header, which is a little more complicated example, not only can we pull up the render function, but notice that render function in itself also has a listener, which we can pull up as well. So in this way, we can take components and disassemble them into a lot of different pieces. So you can imagine that a component has a lot of listeners. It has different hooks, things that happen on initialization, on shutdown and so on and so forth. And all of these things can be broken down into separate, independent functions that are written in such a way that they can be laser loaded independently. And that's kind of the whole magic behind it and how the whole thing works. Kaelan Cooter: Wow. Yeah, definitely a change. I like the style, and the API definitely seems like it had a lot of thought into it. Kaelan Cooter: Another question, since Qwik, due to the way is designed, I guess by necessity, you would be firing off a ton of network requests. Is this maybe a concern on certain locations that have- Miško Hevery: Yes. Yes. So let's talk about that. So I love it because it's very predictable. Everybody asks this question as the first question that comes to their mind, and I love it. Okay. So here's the difference. The way to think about it is that the problem with existing frameworks is that they kind of prevent you from breaking the code base into pieces. It's really, really difficult to insert dynamic imports. And even if you insert the dynamic imports, usually they're not in convenient places and so on. Miško Hevery: So the difference with Qwik is that Qwik takes the opposite extreme, which says, just break the whole thing up into thousands of little pieces, as small pieces as you can possibly imagine. But of course, you end up in the world where you have too much network traffic, and it's too much that you don't want. Miško Hevery: So Qwik also comes with, for lack of a better word, I'm going to call it a jitter. And the idea is that the Qwik can keep track of, as the end user of your application is using the application, Qwik can really keep track of which of these symbols need to be loaded at which point. And it can report this information back to your server. And so the server then gets a statistical view of, oh, typical user goes and does these operations on my site. And I have to download all of these symbols in this particular order. And this information can be fed into a bundler that is specific to Qwik, and this bundler can then say, great, I can arrange the symbols in this particular order. And as a rule of thumb, we know that if a bundle is about 20 kilobytes, it's a good kind of balance between network and the responses, etc. And so it tries to stuff as many symbols as it can into the 20 kilobytes and then says, okay, when I've kind of exhausted the 20 kilobytes, it starts a new bundle and does the same exact thing. Miško Hevery: And so what you end up with is these set of chunks that you know need to be loaded, statistically, in a specific order. You need to know the chunk A goes first, chunk B goes first, chunk C goes first, and so on and so forth. And then you can go to the PartyTown and say, hey, when the application starts up, I want you to load all these chunks in this specific order and do it on a web work or thread so that we don't actually negatively impact anything. Miško Hevery: And so the result is that the application comes up. You had this one kilobyte bootstrapper code that goes and sets up the global listener. Is about out another 300 bytes or so of code that actually sends information to the web worker. And the web worker starts loading all these chunks in a specific order. And then once you want to interact with your application, it's everything ready to go. And you have dials, and you can decide, oh, I think 20 kilobytes is too small or too big. And you can choose the dial, and you can fine tune this stuff. Miško Hevery: This is something you cannot do today. There are no dials to fine tune. If you decide that you will have a big of a chunk, and you want to break it down, well, it's kind of a head scratcher, like where do I insert dynamic imports into the system? And if you decide that you've created too many dynamic imports, then again, you have to go back and refactor your code and be like, I need to remove some. Miško Hevery: As of right now, the dynamic import is the mechanism by which you decide how chunks happen. And there's a couple of problems with that. First of all, frameworks are not really friendly towards dynamic imports. But the bigger problem is that, at the time of writing a dynamic as a developer, I really don't have enough information to know is this a good place to place it? And so kind of the beauty of Qwik is that it can place them everywhere, but then it keeps kind of statistical information to kind of retroactively figure out, okay, I think the ideal list is this. And you can even go more crazy, and you can say, I see that there are different kinds of people that come to my sites. There's maybe first time visitors that will browse around, and they'll use the site in this way, but there's returning visitors that actually know what they want, and they'll go here. And so now I can create different set of chunks for both of these. And I can do tricks like this that just isn't possible in the existing frameworks. Miško Hevery: But in order to make all these things possible, you need to have a collaboration. The framework has to understand these laser loaded primitives as a core tenant of what a framework does. And you need to have tooling that can take advantage of this. As of right now, frameworks are like, not our problem. Somebody else solve this. Chris Potash: I'm curious if you could talk a little bit about kind of the adoption process for companies starting to use Qwik. Is there a way to start using it in the context of your existing applications that are maybe written in Angular or React, or do you kind of need to have fully beyond the Qwik stack to really get these benefits? Miško Hevery: Yeah. So that's a good, a good question. So let's talk about where, or kind of my motivation. So I work at Builder.io. I'm a CTO over there. And the thing that I think is different here is that I think Angular was written in kind of the build it and they will come mentality in a sense that we just thought that the world needed this, and so we built this. And it turns out we were kind of lucky in a sense that when we built Angular, there was a vacuum. Nothing existed in this particular thing. And so Angular became super successful, mainly because it was the first, and it solved the problem that nobody had solved before. Miško Hevery: But today there are lots of different frameworks that solve the same problem. And I'll argue that, for the most part, you are really just debating the syntax between these frameworks. They all do approximately the same thing. They all perform approximately the same way. And no matter which one you choose, you'll be fine. Miško Hevery: So, but Qwik is different beast. It doesn't try to be more of the same. Instead, it says, no, no, no. I am solving something that these other frameworks are fundamentally unable to solve. It is not a feature that one can go and add to existing frameworks. It's not like you can go to React and say like, gee, that sounds like a good idea. Let me add this feature back in. And the reason you can't add it back in is because in order for you to have this kind of laser loading capability, you need to solve the specific problem of being able to take functions and pull them out. Miško Hevery: But in order to do that, you have to make sure these functions don't have closures. They don't close over things. And of course, if you look at the code that you have written all of the existing frameworks, you realize it's all about the things you're closing over. And so, as a result, you're going to realize that you can't just like add a feature because any such change would be such drastic change, that it would fundamentally change what the framework is about. Miško Hevery: Okay. So that's kind of the difference. At first, I really want to make a point that Qwik is in a different category, and it is solving a problem that the other frameworks just cannot solve. The other thing that's different is that Qwik isn't being built for the sake of being built. At the end of the day, Builder.io is a headless CMS company, visual CMS company. And what we do is we try to enable people to, to build sites in a non-coding way, drag and drop kind of way. Miško Hevery: And one of the things we want is we want to make sure that the code we generate is super fast. And one of the things we noticed is that we know how to generate code in React, Vue, Svelte. Any framework you can possibly imagine, we know how to spit out the code base for that framework. And because it's a drag and drop tool, we can generate all of them, and we can see their performance. And what we see is that they all have the same fundamental characteristic, and it's all governed by the fact that they all have to have a reconciliation, rehydration phase or whatever you want to call it, that causes you to redownload everything. Miško Hevery: And the only thing that's quick is HTML, but HTML is not interactive. And so this is where Qwik comes in is what we want is we want to allow our customers to be able to build sites that are fast like HTML, but interactive like other frameworks. And this is where Qwik comes in. Miško Hevery: So Qwik's primary goal is to solve a company's need, but we want to do it in a open source fashion so that if it's useful to us, it could be useful to anybody else. But you see how it is kind of different approach than it was back in the day that we did Angular where we just said, hey, let's just build this because we think that this is the right thing. Miško Hevery: Here, we are primarily building something for our own needs, but we're doing it an open source way. And so the idea is that we will be able to go to our customers and say, hey, we notice you're currently serving your content on whatever, React or whatever the technology stack you happen to have. Would you like to push this button? We can produce a Qwik site for you. And notice that if you push button, we will go to a hundred out of a hundred on Google paid speed on mobile, and we will solve your problems with third party scripts and AB testing and everything else. And you're just going to have an amazingly fast e-commerce landing site. Are you interested? Kaelan Cooter: That's quite a persuasive offer there. I'm kind of wondering where you see the future of tooling like this. Do you see Qwik being kind of like a foundational piece that becomes like what Next.js is, for instance? Or do you see people adopting Qwik, or something like it, like they did with React? Miško Hevery: Yeah. So we're really trying to solve the e-commerce world first. And something like Next.js is going to be a requirement. We are trying to figure out how do we fit with respect to Next.js? In one side, I'm very much of the philosophy of if something's already built, and it's working, let's try not to rebuild it again. Miško Hevery: However, at the same time, Next.js doesn't have this idea of this kind of lazy loading stuff. Next.js is a framework that's built around this idea that oh, you compile a bunch of code and you produce a bunch of JavaScript and then you break it into chunks and then you feed the chunks at the bootstrap and so on. So Next.js, I am all for reusing everything that we can. So we're heavily looking on whether we can reuse Next.js. The trouble with Next.js is that it makes a certain set of assumptions about how frameworks work and about this idea of bootstrapping your application. It creates your site, service side renders its, sends it to the client, and then it basically performs bootstrap. Miško Hevery: One of the interesting things about Qwik is there is no bootstrap. If you think about it, bootstrap is this idea of there is a single entry into your application by which you kick the application off, but in Qwik, when you resume something that was already running on a server, where exactly is that point of entry? If I go back to this to-do demo application, which is right here, what is the point of entry? Is it me typing in here or me clicking on one of these buttons or X-ing one of these things? These are all different entries that require you to start with downloading a different piece of code. So to fully take advantage of something like this, you need to have a system which can kind of take advantage of it. So we're kind of trying to figure this out, whether we can reuse something Next.js, or is kind of the philosophy so fundamentally different that it's not quite compatible with it? Kaelan Cooter: I think what most developers are looking for is not necessarily all of the server side rendering capabilities in Next.js, but really all of the many diverse features that it offers and the fact that it all offers it in one place and you just install it and it does it very fast. So I think if something like Qwik were to take off, developer experience, I guess, would be the one thing that changes that. Miško Hevery: Yes. Kaelan Cooter: But going back to PartyTown, which by the way is an awesome name, I would like to talk a little bit more about that, because it's not so often that I see genuine development in the web worker space. It's been around for nine years now or something, something ridiculous like that, but for some reason it has not caught on as much as I would've thought. And I guess I'm wondering your thoughts on that space in - Miško Hevery: Yes. Yes. So yeah, PartyTown. You're right, web workers have been around forever. However, I think what people discover is that asynchronous communication between the web broker and main thread is such a huge hurdle. And it's so incompatible with the existing way of writing code that in the end, it's really difficult or impossible to kind of reuse anything. And it's essentially impossible to just take a piece of library or code and just throw it out to the world and expect it to run in the web worker, because web worker has no DOM, has no API that's missing out of it. And the communication channel between the main and the web worker is asynchronous. Miško Hevery: So all of these basically add up to so much that I think most people just either give up or the use cases where this is interesting just isn't that big enough so they just kind of ignore it. So kind of the uniqueness of PartyTown is that we are able to take existing code as is, without doing anything to it, and just execute it in a web worker and have it actually work and perform. And the big realization or the big aha moment, which I think escaped lots of people in front, and it certainly escaped me and I was really amazed when Adam Bradley came up with this, is that there actually is a synchronous communication channel between the main thread and the web worker thread. And without that synchronous communication channel, the whole thing is for not. You just can't do it because you would have to rewrite the code or what have you. It just is not a feasible thing. Miško Hevery: But the synchronous communication channel makes it possible. Now you might ask yourself, "Hey, synchronous communication channel, that means that one side has to block while the other side does work. That sounds like a horrible idea." And I think this is one of those places where we naturally convince ourselves that this is a horrible idea. So then we just apply this blanketly as a statement that's true under all conditions. And I want to say it is true, but only under some conditions. So let's clarify. The condition under which this is wrong is that if you block an operation and the user has to wait, if you do that, that's bad. Don't do that, do something else. But on the other hand, if you take a thread that is running offscreen that the user can't see and you block that thread, so what? It doesn't matter. The user doesn't care. Eventually it will continue. Miško Hevery: So why go through kind of the hoops for it? So the trick is that what we want is we want to have a synchronous communication channel from the web worker to the main thread, but not the other way around. Under no circumstances do we want to block the main thread. That's just bad. Don't do that. But we do want to block the web worker thread so that we can pretend and we can proxy all of this stuff. So what a PartyTown really is that is one humongous proxy that proxies all the API from the kind of the main thread onto the web worker thread. So it's not specific to DOM operations or anything like that. So really anything that's available on a window will be available in a web worker, but of course, any kind of communication channel like that has to be asynchronous, so what gives? Miško Hevery: So what gives is that back in the day, Microsoft introduced XML HTTP request, and they actually allowed for asynchronous blocking calls. Why in the world they added this, I have no idea. This was a bad idea to begin with, but they added this. And it turns out that that thing is still in there to this very, very day. So you can actually make a blocking call by calling HTTP request, getting some URL, and say that the response should be synchronous. And then your code will block and patiently wait. So now that you have this primitive, how do you use this to talk to the main thread? Well, you can send a request to some URL, and then you can have a web worker that intercepts the request and then talks to the main thread on your behalf and figures out what is it that you're looking for, and then takes the response and sends it back as an XML HTTP response, to which the web worker thread can then perform the operation. Miško Hevery: So if the code in the web worker says something like document.title, because it wants to read the title of it, then by all means, go ahead and read that particular thing and you will get the value because it will be able to ... to the code, it looks fully synchronous, because a document is going to be a proxy. You will do a get operation on a title. Underneath the get operation is going to set an XML HTTP request and do all these shenanigans and get you the result to you. It will look fully synchronous. And as a result, you can run in the web worker thread. And it's huge, because a lot of these third party scripts, like Google tag manager, Intercom, Hotspot, and so on, they have pretty expensive boot up processes and they negatively impact your application. So what you want is you want to move them over to the web worker thread and says, "You boot up on your own time." Eventually you're going to be up. It doesn't really matter when, and then when you're up, let me know. Chris Potash: I'm a huge fan of how this works. I think this is a great, for lack of better words, a hack, almost. Miško Hevery: It is an awesome hack, yes. Chris Potash: That's great. I'm curious if you see kind of more ... I think this makes a lot of sense for third party scripts, but what about more core application, kind of moving more of that off of the main thread? I think a lot of other platforms do that. They have a dedicated data thread and then they replicate things on the UI thread to keep that fully unblocked. Do you see something like that in the future? Miško Hevery: Yeah. I mean, we've gotten to the point with PartyTown where we can actually run full on React applications in the web worker thread and they execute and they work. What you're going to discover, though, is that obviously the communication channel is not cheap so the app kind of runs slow. So the question then becomes is the cost of communication channel really worth the trouble? And that's to be seen. I much rather subscribe to this idea of breaking your application into something like Qwik into lots and lots of small pieces, and then figure out how to run these small pieces. That's my personal opinion. Kaelan Cooter: Yeah. And then you get the Atomics API and - Miško Hevery: Yes. Kaelan Cooter: - [inaudible 00:45:06] buffers that have been promised for years now and have still not been delivered, but I'm definitely a fan of this hack. I'm going to probably take a look at it myself. Miško Hevery: Thank you. Adam is awesome. Kaelan Cooter: Yeah. Sorry, I've never done this before. Do you want to plug something? Miško Hevery: My only plug here is the shameless plug of go checkout Builder.io. It is a pretty cool way. What it is is you as an engineer, you can basically define a component with whatever framework you happen to have and say, "This component right here is owned by the marketing team," and they can do whatever they want. They can go drag and drop, add columns, buttons, et cetera. But I know at the end of the day, it is this box they're controlling. And into this box, you can actually register your own component so that the marketing department can drag and drop your own things and make it reusable. And I think that's kind of pretty exciting, because engineers don't have to get bothered by like, "Hey, Monday night, make sure that we show 15% sale." No engineer wants to do this. So I think something like Builder.io Solves a very good need. Kaelan Cooter: Sounds exciting. Thank you for coming on. It's been great talking about such an exciting improvement in front end build tooling, so thank you. Miško Hevery: Thanks for having me. It was a lot of fun. Brian: Thanks for listening to PodRocket. Find us @PodRocketPod on Twitter, or you could always email me, even though that's not a popular option. It's Brian@logrocket.