
Qwik with Misko Hevery
Miško Hevery explains Qwik’s approach to high-performance web apps, touching on hydration, signals, and lazy-loading strategies for improved UX
Episode Description
Miško Hevery explains how Qwik's resumability, lazy execution, and signals eliminate excessive JavaScript to dramatically improve web performance.
Episode Summary
In this JavaScript Jam live session, Miško Hevery, CTO of Builder IO and creator of Angular, joins hosts Scott Steinlage and Anthony Campolo to explain the philosophy and architecture behind Qwik. The conversation begins with Miško's journey from computer engineering through Adobe and Google to Builder IO, where frustration with web performance led him to create Qwik. He frames the core problem as too much JavaScript executing on page load and argues that existing frameworks treat lazy loading as an afterthought rather than a foundational primitive. The discussion covers Qwik City as a meta framework, the server dollar sign feature for code collocation, and how Qwik differs from partial hydration approaches. A notable exchange with Theo Browne explores the spectrum from server$ to tRPC to GraphQL in terms of backend-frontend distance. Community members raise practical questions about migrating from Next.js, handling third-party scripts with Partytown, and the visible delays that aggressive code splitting can cause—which Qwik addresses through speculative prefetching via service workers. Miško then explains how signals enable fine-grained reactivity that avoids unnecessary code downloads, why resumability fundamentally differs from delayed hydration, and how closures are serialized across server and client boundaries. The session closes with a look at upcoming features like out-of-order streaming and micro front ends, demonstrated through a Cloudflare-powered demo.
Chapters
00:00:00 - Introductions and Miško's Background
The JavaScript Jam hosts welcome listeners and introduce the show's format as an open, beginner-friendly live conversation held weekly. Scott Steinlage and Anthony Campolo introduce themselves as the Edgio team behind the show, setting a casual and inclusive tone for the discussion ahead.
Miško Hevery then shares his unusual path from a computer engineering degree focused on transistors and CPU design all the way up the abstraction stack to web development. He recounts working at Adobe with Flex and Flash, then moving to Google where he created AngularJS and Angular, before eventually joining Builder IO—a no-code visual editor that can embed into any framework. His restlessness after years on Angular motivated the search for something fundamentally new.
00:07:41 - The Problem of Too Much JavaScript
Miško explains that Qwik emerged from a simple observation: web startup performance is proportional to how much JavaScript executes initially. He draws an analogy to Lighthouse telling developers to reduce JavaScript without explaining how, comparing it to telling someone to simply make more money. He argues that relying on developer frugality isn't sustainable and that tooling should solve the problem automatically.
The conversation touches on how existing frameworks added lazy loading as an afterthought rather than building it into their core design. This means developers can only lazy load code that isn't currently needed on the page, which still forces hydration of visible but inactive components. Qwik's approach is to delay code execution as aggressively as possible and make that delay automatic, so developers never have to think about where to place dynamic imports.
00:13:08 - Qwik City and Code Collocation
Anthony asks about Qwik City, and Miško clarifies the distinction between Qwik's approach and partial hydration before explaining why the team reluctantly built their own meta framework. Qwik City exists because the end-to-end problem—bundling, code splitting, serialization, prefetching, and deserialization—needs to be solved cohesively rather than piecemeal, which existing meta frameworks couldn't accommodate.
Raees asks about the server dollar sign feature, prompting a discussion on code collocation—the trend of mixing server and client code in the same file. Miško traces this lineage from Next.js's getServerProps through tRPC and explains how Qwik's marker functions enable developers to define extraction boundaries themselves. Theo Browne joins to refine the framing, proposing a spectrum of backend-frontend distance where server$ is closest, tRPC sits in the middle, and GraphQL is furthest out.
00:22:05 - Community Questions on AI, Version 1.0, and Ecosystem
A listener from Nigeria asks whether JavaScript can be used for AI work, and Anthony explains the distinction between training models in Python and consuming AI APIs from JavaScript. Tino asks when Qwik will reach version 1.0, and Miško responds that the primary blockers are documentation quality and developer experience polish rather than technical features, noting they are getting close but won't commit to a specific date.
Raees raises the challenge of migrating large enterprise e-commerce sites from React and Next.js to Qwik, given the smaller ecosystem of community components. Miško acknowledges the gap but frames it as an extrinsic factor that will improve over time, highlighting Qwik React as a bridge that wraps existing React components in an island architecture. Ellery adds that Qwik likely has the most correct architecture and shares a proof-of-concept where aggressive bundle splitting in Next.js improved total blocking time but introduced noticeable interaction delays.
00:33:18 - Speculative Fetching and Service Workers
Miško explains that the interaction delay Ellery experienced is expected when retrofitting lazy loading onto frameworks not designed for it. Qwik solves this through a service worker that speculatively prefetches bundles into the browser cache before user interaction occurs, ensuring clicks feel instant. This requires the framework to maintain a runtime graph of all bundles and their relationships—something no existing framework provides.
The discussion highlights how Qwik tracks real user behavior to statistically determine which bundles to download first and in what order. Unlike traditional systems where changing bundle structure means editing source code with dynamic imports, Qwik treats this as configuration. Anthony references Builder IO blog posts on speculative fetching, and the group explores how this concept has no direct analog in other frameworks, making it both powerful and difficult to explain to newcomers.
00:38:24 - Framework Comparisons, Partytown, and Third-Party Scripts
Jen Junod joins and asks which app developers should build to compare frameworks, leading Miško to note that framework differences only emerge at scale with hundreds of components. The conversation shifts to third-party marketing scripts, which Raees identifies as a major source of JavaScript bloat in production e-commerce sites. Miško discusses Partytown's approach of running third-party code in web workers but acknowledges its limitations.
Ellery questions whether Partytown is the right solution compared to server-side tagging approaches, and Miško agrees that moving scripts server-side would be better but notes the ecosystem isn't there yet. He shares the idea of a certification program where third-party providers would test their scripts against Partytown, and mentions that Builder IO has currently prioritized Qwik development over Partytown improvements. The group also distinguishes worker$ for developer-written code from Partytown for third-party code.
00:53:11 - Signals, Fine-Grained Reactivity, and Runtime Performance
Dev Agrawal asks about Qwik's runtime performance after initial load, and Miško explains the two dimensions of performance: startup speed and update speed. He describes why coarse-grained reactive systems like React conflict with resumability, since the first state change would force downloading and executing most of the application. Qwik uses fine-grained signals that allow surgical DOM updates, often bypassing the virtual DOM entirely when changes are non-structural.
Miško positions Qwik's runtime performance between React and Solid.js but argues that runtime speed is somewhat of a red herring—most frameworks are fast enough once running. The real win with signals is that they prevent unnecessary code downloads, not just unnecessary re-renders. He explains how signals work through proxies that let the framework track exactly where values are consumed, enabling precise subscriptions rather than blanket re-rendering of component trees.
01:11:27 - Resumability Explained and Closure Serialization
Anthony asks Miško to summarize his "Resumability from the Ground Up" blog post. Miško walks through the key challenges: locating event listeners without traversing the component tree, restoring state without re-executing components, and distinguishing resumability from delayed hydration. He emphasizes that hydration rebuilds the framework's internal state while resumability transfers it via serialized HTML, eliminating the need to re-execute any component code.
A listener asks about closure serialization limitations and garbage collection. Miško explains that closures can serialize anything the system supports—JSON types, promises, maps, sets, and other closures—by separating behavior from state. He describes how the Qwik loader uses event bubbling with a single global listener to avoid calling addEventListener for every component, and how this enables setting up listeners on the server that only materialize on the client when interaction actually occurs.
01:31:49 - Design Philosophy, Micro Front Ends, and What's Next
Miško shares his design philosophy of picking extremes—aiming for 100% code coverage at runtime so that every downloaded byte gets executed. He explains that starting from this aggressive goal and working backward forced solutions that wouldn't have emerged from incremental improvements to existing architectures. This led to building a custom renderer since existing synchronous rendering pipelines couldn't handle the promise-based lazy loading Qwik requires.
The conversation turns to post-1.0 plans, including out-of-order streaming and micro front ends built with Cloudflare edge workers. Miško walks through a live demo where separate edge workers render different page sections—menu, shopping cart, hero image—that are server-side included and become independently interactive on the client. The session wraps with community thanks, shout-outs to the Qwik Discord, and announcements about upcoming JavaScript Jam events including a collaboration with Remix Conference.
Transcript
00:00:00 - Miško Hevery
[unclear]
00:00:28 - Scott Steinlage
Welcome. All right. Yeah.
00:00:33 - Ishan Anand
Yo, yo, yo.
00:00:39 - Scott Steinlage
There we go. Welcome, everybody. How's it going? Welcome to JavaScript Jam Live. We do this every Wednesday at 12 p.m. Pacific Standard Time. Yes.
00:01:00 - Anthony Campolo
Oh, yeah.
00:01:01 - Scott Steinlage
And we have a lot of fun. We have some great people join us, regulars. There's Jen. She's one of them. She's in here quite often. But yeah, I just wanted to thank everybody for coming today. I just wanted to say, whether you're a beginner or whether you're an advanced learner, because what are we? We are, as engineers, as developers, lifelong learners, right? So there we go. It went away. All right. Sorry, I was getting a phone call. I need to put this thing on focus mode, y'all.
00:01:47 - Raees
[unclear]
00:01:47 - Scott Steinlage
Come on.
00:01:48 - Miško Hevery
[unclear]
00:01:49 - Scott Steinlage
I'm new to the game. Told you. Lifelong learner, right? Lifelong learners, that's what we are. And so whether you're a beginner learner or an advanced learner, we just want to say thank you all for coming. And it doesn't matter who you are, come join us up here on the stage. Just feel free to ask any questions you want, state any facts, opinions, whatever. We'd love to hear it. All you gotta do is request to come up, and we'd be more than happy to have you on. But we do have today a special guest, and we're going to be discussing, I'm sure as you saw from the title there, a little bit about Qwik. So kind of excited about this one, Anthony. I'm going to go ahead and make an introduction to myself real quick, and then you can introduce yourself, and then Miško can go from there, and we'll get started. I'm excited. So my name is Scott Steinlage, and I am the technical community manager for Edgio and co-host of JavaScript Jam here.
00:02:47 - Anthony Campolo
Hello. My name is Anthony Campolo. I am a developer advocate at Edgio, and we are super happy to have Miško here with us.
00:02:58 - Miško Hevery
I guess it's my turn. Hi, I'm Miško. I am a CTO at Builder.io, and yeah, I'm so happy to be here, so happy to chat with everybody. Hi, Jen. I've been on your show before. Yeah, so let's talk about things related to Qwik and web and things of that sort.
00:03:15 - Anthony Campolo
Yeah, I want to give you a shout-out for being on Jen's show because Jen was, and kind of still is, getting into the industry, and you went on and taught
00:03:25 - Miško Hevery
her how to write.
00:03:26 - Anthony Campolo
how to write a counter, which for someone of your stature is kind of funny, but also shows that you're very humble and willing to work with beginners. I think that really speaks a lot to your character.
00:03:39 - Miško Hevery
I am new to this as well, and so happy to be on Jen's show.
00:03:46 - Anthony Campolo
Cool. Well, yeah, we're going to be talking about Qwik today and any other things you want to chat about with Builder. I've been kind of looking at the Builder.io blog posts and some of the topics that you had recently been looking at that I thought might be interesting to get into. But before we start checking those out, we should start with a little bit of your background and Qwik 101.
00:04:14 - Miško Hevery
Yeah, sure, we're happy to jump into that background. Let's see. I actually have a degree in computer engineering, which is kind of weird because the thing that I got my degree in is how transistors work, you know, all the way to the low level, like how CPUs work, the lowest possible level you can imagine. And somehow, over the years, I have slowly transitioned to higher and higher levels because computers are just a bunch of abstractions, right, all the way to the top. And so somehow I ended up in the web, which is pretty high abstraction. Right. And normally when you type A plus B or something like that inside of your web browser, you don't really think about all the insanity that happens underneath to add two numbers together. So yeah, I have kind of a strange background. I actually kind of like it because I kind of joke that I'm probably the only JavaScript engineer that knows how transistors work. I'm sure there are plenty of others, but it's not a common thing in IT.
00:05:13 - Scott Steinlage
Hey, I love working on some things. I have personally soldered some custom boards together with capacitors, resistors, chips. Yeah, interesting thing.
00:05:28 - Miško Hevery
So there you go. I used to have a big poster of a chip I laid out over my bed, but my girlfriend, now my wife, she decided that that didn't really fit the bedroom, and so it's no longer there. But anyway, somehow I ended up in web technologies, and I actually went to work at Adobe, and there I learned Flex and Flash. And then I ended up at Google, and I learned that building web apps is just a big marshaling problem of how do you get your data from the UI to the database and back from the database to the UI. And so this is where I kind of worked a little bit on Angular, AngularJS, and Angular. And I'd done that for a pretty long time. And then like two years ago or three years ago, something like that, I was just like, I just need to try something new, something different. Either that or I'm going to become institutionalized. And so I kind of went out and looked for a bunch of other things. I ended up at Builder.io. What really spoke to me is this idea of a no-code editor.
00:06:34 - Miško Hevery
What Builder.io does is basically... I'm sure you guys are familiar with Wix. Wix allows you to kind of drag and drop edit for building websites, right? But Wix forces all of that to be hosted with Wix. You cannot take the site and put it in a custom application or something like that. And so Builder.io is kind of the same exact idea as Wix, except that you can actually embed it into your custom React, Angular, Vue, Svelte, Qwik application. And I think that's kind of what's unique and interesting. Anyway, so while at Builder, I came to my old habits, so to speak, and I was just like, we need to make the web faster. What's going on is just craziness. It's too slow. And the big realization is that it's relatively simple in the sense that the startup performance of the site is just proportional to how much JavaScript the website has to execute at the beginning, right? And so if you decrease the amount of JavaScript you execute, then your site obviously starts up faster.
00:07:41 - Miško Hevery
And so Qwik kind of became this journey on how do you not ship so much JavaScript to the browser? And so that's where we are today.
00:07:53 - Anthony Campolo
Yeah, I find that this is very much in the zeitgeist right now with JavaScript. A lot of people are concerned with performance, both in the framework world and outside the framework world. I think it's interesting, you look at someone like Alex Russell, he's really giving a similar message to you, but he is saying less so that we should have a performant framework, so much as we shouldn't have a framework at all, or you should kind of build your own bespoke one for the needs of your specific project. So why do you feel that we should architect these frameworks to be performant instead of just using native web components?
00:08:36 - Miško Hevery
I think a lot of people are coming to the same exact conclusion. And the conclusion is that there is too much JavaScript.
00:08:42 - Ishan Anand
Right.
00:08:42 - Miško Hevery
It's kind of an obvious conclusion, but it's also a conclusion that is kind of difficult to make actionable. You know, I always kind of joke that when you go to Google Lighthouse, right, it tells you decrease the amount of JavaScript. And it's like, yes, yes, I understand that. But how? What's the magic button that I can push to get less JavaScript? Right? It's kind of like you go to somebody and they say, well, you know, I decided that your problem is that you're poor, so you just have to make more money. It's like, yeah, I get it, but how? What's the magical thing to do here? And so I think what Alex a lot of times talks about is this idea of, like, let's just be more frugal about things. And I think being frugal is kind of difficult. Like, yeah, I get it. You could be more frugal and be more careful, etc. But at the end of the day, we have things to deliver, we have other distractions, etc., and so we just want the tools to solve this for us. And so my take on the whole thing is that our tools should be helping us.
00:09:46 - Miško Hevery
And I think we're kind of in the world where the tools are somewhere between not helping and actually actively trying to sabotage us. It's not intentional. It's not like we intentionally designed these tools this particular way, but we kind of ended up in this world because we didn't really understand the web ecosystem or the web world. And we came to the web world from kind of the desktop application world, right? In the desktop application world, the concept of lazy loading is just not much of a thing. And so you don't really design your framework to kind of take this into account. And if you look at most frameworks today, they have lazy loading. It's true, they have that. But it's kind of, I would say, an afterthought. Lazy loading was never inside of version 1 of any of these frameworks. Lazy loading was something that was added later on, and because it was added later on, it's not like the core primitive of what these things do. And so there's all kinds of, I would say, clever ways to lazy load the code, but all of them essentially have this particular problem, and that is that you can only lazy load code that is currently not needed, which seems kind of obvious. But what it means in practice is that if you have a component that is currently on your page, you have to have the code for the component, even though that component might not be doing anything, might not have any behavior, or it might already be rendered and it never needs to be rendered again.
00:11:19 - Miško Hevery
But just the way the existing tools work and the way hydration works, that code has to be present on the client. And so the mental exercise that Qwik is trying to do is to say, how do we delay the code as much as possible?
00:11:35 - Scott Steinlage
Right.
00:11:36 - Miško Hevery
And just take it to an extreme and have the tools do it automatically, so as a developer you just don't have to think about it.
00:11:45 - Anthony Campolo
Awesome. I'll give a shout out to Raees, who just joined us. You want to introduce yourself?
00:11:52 - Raees
Hey, yeah, sorry. My name is Raees. I am the product manager for Edgio Sites. I work at Edgio with Anthony and Scott and some other people here. Yeah, just listening in and being inspired. I have a couple of questions that I'll save for later, though.
00:12:15 - Anthony Campolo
Yeah, I told Raees he should definitely make it for this one because he's someone who actually has worked quite deeply with Qwik and has kind of scoped it out for some production apps. So I was like, you should definitely hop up here and ask some questions when you have them. Yeah, feel free to jump in at any point. We're just doing kind of like the Qwik 101 right now, and then we'll get into some deeper questions as we go. So we talked about Qwik, we've talked about kind of the problem it's meant to solve, and it seems like it's aiming for a similar thing to partial hydration. How do we manage the amount of JavaScript we have? Same thing with server components. So there are a lot of different ways that we're trying to approach this problem. And then there's also Qwik City as well. So you should talk a little bit about how Qwik City fits in here.
00:13:08 - Miško Hevery
Yeah, we can talk about that. But first, sorry, I'm going to be a little bit of a stickler, and I will try to very politely correct something here. You just said partial hydration.
00:13:20 - Anthony Campolo
Well, I know it's not partial hydration. I'm saying the thing you're doing and the thing partial hydration is doing are both trying to solve the same problem, but I know they're doing it differently. So you can go into that.
00:13:30 - Miško Hevery
Yes. No, no, no, absolutely.
00:13:31 - Scott Steinlage
Yeah.
00:13:31 - Miško Hevery
No, I just wanted to make it clear. It solves the same problem, right? The problem you're trying to solve is that way too much JavaScript is being executed on initial page navigation. Right? That's fundamentally the problem you're trying to solve. And there's a lot of different approaches you could take. And Qwik was basically designed from the ground up to delay-execute the code extremely aggressively, as much as possible. And that's kind of its trick. That's the thing that it's trying to do. And the argument here is that if you can do that, then you can greatly lower the amount of JavaScript. So anyway, Qwik City. Yeah, let's talk about Qwik City. So we built Qwik, and we originally didn't want to go into the business of building a meta framework. We were kind of hoping that we could either reuse Next.js or Remix or one of the existing meta frameworks that are currently out there. But it turns out there are a lot of details that matter. And so whether we liked it or not, we ended up building a meta framework that can take advantage of Qwik.
00:14:38 - Miško Hevery
And one way to think about it is Qwik City is kind of like Next.js to React. So Qwik City is to Qwik in the same way, but it takes the problem in a slightly different way. What's unique about Qwik City and Qwik, or you can really think about them together as just Qwik, is that they really want to solve the whole problem end to end. What I mean by whole problem end to end is: how do you make the bundles, how do you break up your code, how do you lazy load the code, how do you make sure that the lazy loading is pre-cached so that you don't have hiccups on a slow network or intermittent network, how do you serialize the data, how do you deserialize the data on the other side, how do you wake up the application? Basically, all of those pieces that are related are solved as a cohesive problem set. Whereas if you look at the existing systems, they solve the parts in pieces, or maybe they don't. So for example, Next.js really relies on existing technologies to create bundles, but because it relies on existing technologies, it means that as a developer, if you want to have a lazy-loaded boundary, you have to think about it.
00:15:50 - Miško Hevery
You have to put a dynamic import somewhere in your codebase. And if you don't put that in, well, then you know that particular bit can't be lazy loaded. Whereas with Qwik, you don't have to think about it. It's just automatic and natural. So the problem we're trying to solve is that we would like to have an environment where the whole part of serving a web application in the fastest possible way is available to you, solved out of the box. You don't have to think about it as an afterthought.
00:16:22 - Anthony Campolo
Awesome. Welcome to the stage, Daniel. Did you have a question for us? And if they're not here right now, Raees, if you want to hop in with any of your questions, feel free.
00:16:36 - Raees
Yeah, so actually, as Anthony mentioned, I actually built a production website, a small production website, with Qwik. And while we were actually building that, some of the APIs changed, and I was trying to basically see the documentation in GitHub and see what was going on with the APIs, and I found out that you guys are working on server$, I think it's called, or something. I would love to know what the motivation behind that was. It seems like it should have been done by other people as well. Are other people, other frameworks, doing it as well, or is Qwik City the first one to do this? And what was the inspiration for that?
00:17:33 - Miško Hevery
Yes, I believe you're talking about server dollar sign, right?
00:17:35 - Raees
Yeah. Yeah.
00:17:36 - Scott Steinlage
Okay.
00:17:38 - Miško Hevery
Yeah. So I think there is a general trend towards what I call code collocation. This idea that as a developer, we have some code that runs on the server and some code that runs on the client, but we don't really want to think of it as two separate things. We really want to just have a single codebase. So we want to co-locate our server code together with our client code. And if you look at it, existing frameworks already do this. If you look at Next.js, there's getServerSideProps. If you look at Remix, I forget off the top of my head what they have, but they have a similar mechanism where you can fetch data. And basically all meta frameworks have a mechanism where you can essentially execute code that is server-only code, meaning it talks to a database or a file system, something that can never be on the client, but have a way of making sure that when the bundles are created, that code doesn't end up on the client. Right. And so this is a trend that I think already has existed for a while. Nothing has changed in it.
00:18:35 - Miško Hevery
And so I think what we're looking for is just a more natural way of mixing server and client code. So once we have getServerSideProps, once we can get started, other people have tried to push this idea even further. So tRPC is another example of, hey, I have server code, I have client code, how do I make sure that the type information flows through it, and so on. Before something like tRPC, type information wouldn't flow between the server and the client. And so if you just take this idea even further, then you end up with something like server$, where you have an underlying system that knows how to break up your code in such a way so that you don't accidentally ship server code to the client, but it's written in such a way where the semantic meaning of what server$ is is left in user space, in the developer space, meaning that I could implement server$ or I can implement worker$ or any one of these other load-data-on-a-server-dollar-sign kind of things. And so what Qwik, I think, kind of pioneered, and what is kind of unique to Qwik, is this idea that you have a marker function that can take code and break it apart so that you as a developer can decide, well, what does it mean for these two parts to do? Do I execute the part in the same location or the location on the other side, etc.?
00:20:05 - Miško Hevery
So we call this idea code collocation and code extraction. And so server$ actually kind of fits an interesting niche where you want to just make a call on a server, and so you want to have a simple way of doing it, but you don't necessarily want to reach for something more heavyweight like tRPC. tRPC has other advantages in that you can have different teams working on the API side and different teams working on the client. There's a backward-compatibility story in the sense that you have to make sure that, because there's a version skew between the version that's in the browser versus the version that's on the server, you want to change your APIs in such a way so they're compatible, right? So tRPC allows you to do all of these fancy things, but maybe sometimes you don't need it. Sometimes you just want something quick and simple to kind of get you moving. And so something like server$ is an interesting stopgap measure. So what we're doing is we're making it easy for people to co-locate server and client code together in the same file, and making it easy for us to communicate between that, and we think for like 90% of the use cases it's good enough.
00:21:16 - Miško Hevery
And for the more complicated 10% of the use cases, well, there are other tools out there that you can kind of hop in and use. And I think, I see Theo is also over here, and I know Theo has been pretty outspoken about tRPC, and so you can probably jump in and have some opinions as well.
00:21:37 - Anthony Campolo
Looks like Daniel's got his hand up. You want to hop in?
00:21:42 - Daniel
Hello. Good evening. Sorry, good evening from Nigeria. So I have a question. I write Python and I use that for artificial intelligence, but is it possible for someone to write AI with JavaScript? Is it really possible? I know you can write it with C and Python, but is it possible with JavaScript?
00:22:05 - Miško Hevery
This is not my area of expertise, but go. Go for it. Yeah, yeah.
00:22:10 - Anthony Campolo
So when you're talking about AI, there are different things you can kind of talk about here. There's actual training, like the models themselves, which is typically done in Python, but you can do some of this in JavaScript. There's a JavaScript TensorFlow library, or you can write JavaScript code that's going to hit an API, like OpenAI's API. And with that you can write a JavaScript application that will be hitting essentially AI services. So for the most part, that's what you'll be doing. You won't really be coding so much direct AI stuff itself in JavaScript, but you still work with AI tools in the language of JavaScript.
00:22:55 - Miško Hevery
Does that make sense?
00:22:58 - Daniel
Yeah, kind of. But, you know, trying to build stuff like a convolutional neural network or a computer vision project, I have full interest in AI. I've been working with AI for quite a long time just using Python. So I don't know. I think I know of TensorFlow.js, but I don't know if you can do everything Python can actually do. It just sounds weird. I don't know.
00:23:28 - Miško Hevery
Yeah, yeah.
00:23:29 - Anthony Campolo
I mean, we're not really AI experts up here, unfortunately, so I think that's probably about all the words of wisdom we can give you. Theo, you've got your hand up.
00:23:41 - Theo Browne
Howdy. I wanted to chat a bit about the tRPC stuff just because I agree with parts, but not necessarily the whole. I think the framing that I've grown to take on is, what's the distance between your backend and your front end in a developer experience way, where collocation is obviously a huge win in that the backend code that your front end uses is right there, and when you use a primitive like server$ to generate those functions, you end up with a lot of the type-safe behavior that you would expect from just writing and calling functions in TypeScript. Traditionally, I find that when we look at stuff like REST and GraphQL, there is an abstraction there that makes the distance between the backend and front-end code feel much greater, and you have much more mental overhead to work with when you're making those types of changes in that relationship. The benefit of that cost is that you now have a backend that can be used for multiple purposes across multiple clients. And the split actually makes the team split better too. One of the points Miško made that I don't necessarily agree with is that tRPC helps the backend and front-end teams be separate.
00:24:49 - Theo Browne
I actually think it's uniquely poor in that. tRPC is a first-class backend for front end. What we're describing here with server$ is a first-class backend primitive in your front end, and I think the distance between those two things is not very great. I would consider tRPC closer to a server$ type than I would to GraphQL, simply because command-click, go to definition works as expected. And I think the magic of tRPC isn't that it's more like GraphQL or more like an RPC. It's that it represents this unique in-between where you get a lot of the DX wins from both, and the ability to use your server across multiple platforms and clients.
00:25:33 - Miško Hevery
I just want to add something. I agree with everything you said. Do you think it would be a good characterization that you kind of have layers, right? Like server$ is by far the closest in the distance, and then tRPC is a little further away, but still pretty close, and then GraphQL would be kind of the furthest out there, right?
00:25:53 - Theo Browne
Exactly. This is the framing I've been trying to take on more, and while doing it, show the benefits that you get as you leave further out the circle.
00:26:01 - Miško Hevery
Yeah, it's a trade-off, definitely.
00:26:06 - Speaker 8
Awesome.
00:26:06 - Anthony Campolo
Looks like we got real_007 has their hand up. This is a first-time caller.
00:26:14 - Tino
Hello.
00:26:15 - Miško Hevery
Hey.
00:26:17 - Tino
Hey guys. My name is Tino, and I have a tricky question for Miško, but I don't know if he can answer. So my question is, as far as I know, Qwik and Qwik City are still in beta. What are they waiting for in order to hit version 1.0? What is that one thing that they are waiting for? I don't know if Miško can answer this or not.
00:26:41 - Miško Hevery
Yeah, I can definitely try. I think what we're missing mainly is documentation and kind of polish. What we want is for people to have a good experience. If you come in and you type in qwik create project and do basic operations, it should all kind of work. And right now we're still getting lots of feedback from the community about kind of sharp edges, where things work but you've got to watch out for this and that, etc. And so from our point of view, it is not a high enough standard that we have reached, but we would like to get to version 1.0 pretty soon. Of course, with anything related to versioning and guesses about the future, you're always wrong about it.
00:27:23 - Anthony Campolo
Right.
00:27:23 - Miško Hevery
So I'm not going to pick a specific date, but I'm just going to say we're getting pretty close.
00:27:29 - Tino
Okay. Okay. No, thank you so much for your time.
00:27:35 - Miško Hevery
Also.
00:27:36 - Anthony Campolo
Hello to Ellery. You got any questions for the space?
00:27:42 - Ellery
No, nothing yet, but I will definitely raise my hand eventually.
00:27:48 - Anthony Campolo
Looks like Jen's coming up.
00:27:50 - Raees
Yes. Since Ellery is here, it reminds me, actually one of our largest clients at Edgio is very interested in trying out Qwik. Some of their websites are probably some of the largest e-commerce websites by revenue on the Internet. And one of the problems that we're running into is their existing websites are built in multiple different kinds of frameworks, or you can say backends. One would be Next.js, another is Salesforce Commerce Cloud or something else. And just translating all of the work you've already done in Next.js and React into Qwik is huge. Basically you have to rebuild everything. And the advantage you have with React is there's a huge amount of community work that's available that you can use, and that is not available as much with Qwik. So in general, I'm just asking, how are you seeing the community work for Qwik and Qwik City, and how's the trend line going for open-source components?
00:29:25 - Miško Hevery
Yeah, I mean, Qwik is pretty new. So obviously our community is nowhere close in size to React, but I think Qwik offers some pretty compelling value propositions here, right? And so people who really want to make sure that their sites are fast, and e-commerce is a perfect example for this, might want to explore it now. To help with this, we do have Qwik React, which allows you to take existing React components and wrap them in Qwik. Obviously, you're not going to get all the magical benefits out of the box. Qwik React is essentially creating island architecture. You delay hydrating those particular React components. So it's not resumability, but at least you can kind of work on it together. When I talk about the advantages and disadvantages of different technologies, I like to talk about things like intrinsic and extrinsic factors. And so to me, the fact that Qwik's community and Qwik's documentation and the know-how, etc., are obviously not as high as somebody who's been around for much, much longer, to me these are all extrinsic factors, meaning these are things that will change over time.
00:30:34 - Miško Hevery
These are not fundamental properties of a particular technology, which is kind of what an intrinsic property would be of the system. So yeah, if you want to use Qwik today, you kind of have to really understand the value proposition you're going after and say, hey, this is worth the trouble, because there isn't yet this support system that we have. Having said that, I think we have quite a lot of things already. If you go to the Qwik website, there's a showcase, actually we're just rebuilding this to make it easier, but I think we have quite a lot of existing community support. I'm just chatting with people who are doing image components, who are doing form support, who are trying to do existing component libraries for Qwik. Of course, you can just wrap Material components and so on. So a lot of things, I think, are happening. Authentication with different auth providers, a lot of things are happening, but it's just going to take some time. And so we're at the beginning of the stage. We're not even at version 1.0.
00:31:44 - Ellery
Yeah, if I could just follow on to that. So I think Qwik has probably the most correct architecture. Like if you put a gun to my head and said which thing is the right way to build a website, I'd probably pick Qwik. One thing that we did for this particular client is they're both on Next.js, as Raees mentioned. So we said, all right, let's take some lessons learned from Qwik and see what we can implement in Next.js without a full rewrite. So we did a little POC recently where we said, let's try to go very aggressive with bundle splitting. So let's dynamically import all of the things, basically, and let's defer even downloading the JavaScript on the client until certain components have been interacted with. And this had the expected impact that we anticipated for TBT. So total blocking time had a huge improvement. But then what we did see, there were some visual issues. So one example was when you clicked on the hamburger menu on mobile and you expect the navigation to open up, you have all these flyout menus, images that load in, components, fonts, etc.
00:32:50 - Ellery
There was a visible delay, I'll put it that way. We aren't talking a half second, but maybe 100, 200 milliseconds of delay. So you would tap, and it was long enough that you would be like, did I really tap that? I'm not sure. And then it would show up. So I'm not sure if you or other people have seen any issues where this aggressive code splitting and dynamically loading JavaScript on interaction has had any adverse user-experience impacts.
00:33:18 - Miško Hevery
Yeah, that's a good question. Actually, a lot of people ask that. Absolutely. If you lazy load code on interaction, you will see that, and that's going to be a problem. This is why we actually have ways of mitigating this. And I think what you're discovering is that you're trying to take the lessons learned from Qwik and apply them to an existing system, and then the existing system is not really cooperating, right? Because it wasn't designed for this particular bit. So the way Qwik solves this particular problem is that we have a service worker, and the service worker's job is to pre-populate the cache so that when the user goes and clicks on a hamburger menu and the framework starts lazy-loading the code and lazy-executing the code associated with the hamburger menu, the code is already sitting in the cache, and therefore you don't have the 200-millisecond delay. It's basically instant. Right? And so if you look at existing systems, like for example, you lazy-loaded everything, you discovered, hey, now you have to solve the next problem. And the next problem is making sure that the cache has the right assets, and existing frameworks will not do anything to kind of help you in this department.
00:34:30 - Miško Hevery
Right. It's up to you as a developer to kind of write this. Whereas in Qwik we kind of thought about this problem and said, hey, yes, if you start executing code lazily, you will have a problem of delay. How do we make sure that that doesn't happen? Well, we have to make sure that certain bundles get eagerly downloaded and placed inside of the cache so that when the user does interact, there is no delay available to them. And to do that, now you're in the business of knowing which bundle contains which code, in which order should the bundles be downloaded, do I download all the bundles or only some of the bundles, right? And so again, existing frameworks just have no opinion on this particular matter. And this is where Qwik has an opinion. So Qwik can keep track of the usage of what the user does, and based on that it can provide statistical information to you as a developer that says, ah, people normally click on this button first, so you make sure you download the bundle with that thing available first, and all of this information as to what bundles to download, in which order, etc.
00:35:32 - Miško Hevery
All of that becomes just configuration information to Qwik that is relatively easy to tweak and improve. Whereas if you wanted to change the way the bundles are structured in the existing system, you actually have to go to the source code and either add more dynamic imports or remove dynamic imports. Right? It's not something that's just automatic. So again, I think you're discovering the case of, yes, I'm going to take some of the ideas that Qwik has and I'm trying to implement them in existing systems that are really not designed for this, and I'm running into all kinds of problems or surprises. And now these problems or surprises are your problem as a developer. They're not the framework's problem. And I think that's kind of the big difference with Qwik, is that with Qwik, no, this is the framework's problem, and so you don't have to think about it as a developer. Hopefully that hits it and answers it.
00:36:23 - Ellery
That does answer the question. I need to peruse the docs a little bit and see if I can figure out this service-worker magic. I mean, not that I'm unfamiliar with service workers, just understanding how, at compile time or runtime, we're determining what bundles or scripts should be loaded eagerly because user interaction will depend on them, and making sure that they're available.
00:36:42 - Miško Hevery
Yeah.
00:36:44 - Anthony Campolo
Two of the blog posts at the top are related to this, if you want to speak about it a little more, Miško.
00:36:50 - Miško Hevery
Yes, yes, yes.
00:36:52 - Raees
Yeah.
00:36:52 - Miško Hevery
So we call it the speculative fetching of code. In order for this to actually work, you need an interesting part, which is, I keep discovering that Qwik has these concepts that don't have an analog in other frameworks. So for example, one of the concepts that we have in Qwik is this idea that the framework at runtime understands the graph of all the objects, meaning it understands what bundles exist in a system. And it understands, if I load bundle A, I will also have to load bundle C. And if I want to get a click listener for this particular button, then I know that's going to be found in bundle whatever, G or something like that. Right? So the framework itself understands the graph of the bundles and the symbols available inside of it. And there is no equivalent like that in existing systems. In existing systems, if you take your source code and you feed it through a bundling system, the bundling system doesn't tell you anything about how the bundles are related, what symbol ended up where, you're kind of on your own. Right? And it turns out that having that information, having that graph, is what then enables you to do other things, such as speculative loading of code.
00:38:04 - Miško Hevery
So that when a user finally clicks on a button, you know that the code is going to be waiting for the user in the cache, and there will be no delay, there will be nothing visual that is kind of annoying.
00:38:24 - Anthony Campolo
Yo, Jen, did you have any questions?
00:38:28 - Jen Junod
I do have to remember my question now. And hello everyone.
00:38:34 - Anthony Campolo
Why don't you introduce yourself real quick while you're thinking of it.
00:38:37 - Jen Junod
Yeah, I guess this is the exciting time. And Miško, thank you for being on the show eight months ago. It's crazy to think about that. My name is Jen Junod. I am a developer advocate at Aiven, a developer data infrastructure company. And I also have two shows, one called Teach Jen Tech, where I first met Anthony and Miško. They have both been on the show. Oh, and I see Nick. Nick's been on the show too. And I also have a show called Shit You Don't Want to Talk About, where we talk about mental health and neurodiversity. And yeah, I had no idea about coding back in like July 2022, so we're almost to a year. We are almost there. And for those who might not have been here at the very beginning of the space, Anthony was complimenting Miško on coming on my show and teaching me what Qwik was when I didn't know what Hacker News was.
00:39:42 - Anthony Campolo
What was your impression of learning Qwik at the time? Did it seem overwhelming, or did it feel like just learning another thing, like the way you learned React? Because I feel like with beginners, you can kind of give them any framework and start teaching them, and they're all going to be equally confusing, you know? So I feel like Qwik might have been just like another framework for you.
00:40:06 - Daniel
Yes.
00:40:07 - Jen Junod
Although I would say, when we started going into the dev tools and looking at the load times to compare them, it made a lot more sense because my previous time was at GoDaddy, and of course I always heard of people hating that their websites were loading really slow. So it was really cool to see how the website only loaded what it needed to load instead of absolutely everything, when that could slow down a website.
00:40:47 - Miško Hevery
Nice.
00:40:47 - Anthony Campolo
Yeah, that is, that's the idea.
00:40:48 - Jen Junod
But I do remember my question because I was super excited lately that I built one website in Astro and now I'm building another site in Astro, and I was like, you know, I should probably try a different framework eventually. And I just saw on Builder that you can do Qwik with Builder. So now I'm really excited to try that one out. But this question is for all of you: what app would you say anybody should build to be able to test out and really see the differences between frameworks?
00:41:30 - Miško Hevery
You know, that's a hard question because I feel like the differences between frameworks don't really come through until your application gets ridiculously large. Any framework, when you build a hello world or to-do list or movies app or any of those basic ones, will be just fine, and things won't really break under pressure because, well, there's just not a lot of it just yet. Right. It's when you build a full-size application that has hundreds or maybe even thousands of components, that's where the size really comes into play and all these tricks start to matter.
00:42:09 - Anthony Campolo
Yeah, there used to be something called the RealWorld app, which was kind of like a clone of Medium, the blogging platform. So that's one that used to be really popular to be built in every framework. And then there was TodoMVC, and now the movie app is becoming a big one. This is always a problem: how do we actually find something that can kind of show off the capabilities of each while also finding the pain points? I feel like benchmarking is good for finding out where they break down, but then just building some sort of usable app that has users is a good exercise for a developer to go through because then they have to go through all the different pieces of the framework to make that happen. So yeah, does that kind of answer your question, Jen?
00:42:59 - Miško Hevery
Let me just add something to it. I think something like TodoMVC is great to discover what the developer experience is for the developer, right? It might not necessarily be the best thing to discover when the framework will break under load, but it certainly is great as a developer to kind of learn about stuff.
00:43:21 - Jen Junod
I'm thinking, because of course I'm learning now, I'm basing everything on data infrastructure and learning that from scratch. So I think, I don't know if these two concepts go together, like there are public datasets that we can use, that can be put into... like yesterday's show was about Kafka. Is there something like that that could be used to test frameworks, or is that putting two ideas together that don't really go together?
00:43:56 - Miško Hevery
I think it's not about the amount of data the framework has to show, it's about the amount of code that's associated with that application.
00:44:02 - Ishan Anand
Right.
00:44:03 - Miško Hevery
So you need to get an application that's complicated enough that it has a sufficient amount of code, and a sufficient number of different developers who went through it and refactored the code in different ways. And of course, whenever you do refactoring, you always do it 80% of the way, right? And the last 20% is left the other way. It's only then where I think you could discover how these things actually scale.
00:44:26 - Jen Junod
That makes sense. Thank you.
00:44:33 - Raees
Actually, this reminds me of another problem that we are seeing in a lot of enterprise e-commerce and other kinds of websites that our teams are building, which is that you build a pretty decent website with any framework. It could be Next.js, Nuxt, or any other framework. And then what happens is when it's deployed to production, there's a huge amount of martech, like Google Analytics, tag scripts, Hotjar, other kinds of service scripts that are added to the page, and that is actually where the majority of the JavaScript is coming from. So Miško mentioned worker$, something similar to the server$ primitive that exists in Qwik now. I know that there's this Partytown framework that exists, but the last time we tried to use it, it required a lot of manual work. So are you working on something that would make that manual work easier, or reduce the amount of manual work required to move that into a worker?
00:46:03 - Anthony Campolo
Partytown meta framework?
00:46:07 - Miško Hevery
Yeah, Partytown is definitely the answer I would give here for third-party code. You're right, it is not as streamlined as we would like it to be. It is a hard problem, right? You can't just take code and run it in a web worker and expect it to just kind of work out of the box. So there's lots of hoops and complications there. But yeah, it's the best we have so far in this particular department. Right. As you correctly observed, when you build a large-scale application, third-party code is a huge part of it. And I think Google reports that on average websites have something like 21 different third-party domains or script tags on their page. And that's a lot, right? And so figuring out how to make sure that the third-party scripts can be better about the way they run is something that certainly would help. And so Partytown is the way to do it. Actually, I've kind of come around to the particular point of view now, and I think many of these third-party scripts could be written in Qwik, and I think they would perform better.
00:47:13 - Miško Hevery
Because if you think about it, what all these third-party scripts do on initialization is they just run tons of code. It registers listeners and sets this thing up and the other thing, etc. And many of these things could be simplified if they just weren't there. So the initialization, right, the resumability of the system is kind of what you would be looking for. And if you could do that for third-party code, I think you would gain a lot of benefits. But that's kind of down the line, right? Immediately, I think Partytown is the only real option that's available to us.
00:47:47 - Anthony Campolo
We have a question from the audience. Will worker$ make most third-party code that's not supported by Partytown finally work?
00:47:57 - Miško Hevery
I think those are two separate things. worker$ would be the code that you have written that you want to run on a web worker. Partytown is really for code that somebody else has written and you want to make it run on the web worker. Right. So this is a very different kind of use case. I don't see them as overlapping. Okay.
00:48:19 - Anthony Campolo
Gotcha, Dev. Welcome to the stage.
00:48:27 - Dev Agrawal
Hello.
00:48:27 - Raees
Hello.
00:48:28 - Dev Agrawal
I can go next, but Ellery has his hand up.
00:48:31 - Miško Hevery
Yep, sounds good. Let's do that.
00:48:35 - Ishan Anand
Cool.
00:48:35 - Ellery
While we're talking about Partytown, I just wanted to ask, have you had any large-scale customers implement Partytown? I know it's still a beta product. In my experience with it, I found that it makes simple things faster and complicated things extremely painful. Like if you have a couple of marketing scripts, it probably works well. But for large enterprise accounts that have 20, 30 distinct marketing scripts, things that want to write directly to the data layer, that are third-party scripts, and now you have to intercept that and glue things together, it was pretty tedious to get things going. So just curious if there are any plans to expand that, include support for more third parties, and maybe see it in a live production site that has a bunch of martech scripts running on it.
00:49:21 - Miško Hevery
Yeah. So the hard part about Partytown is that you're essentially emulating the browser in a web worker, right? The web worker doesn't have all of the browser APIs, like DOM, etc. And so you have to do an emulation. And the thing with emulators is that it's easy to get 80%, and every additional percentage point that you want to get in terms of accuracy becomes more and more difficult. And so the thing with Partytown is that it is very, very difficult to get there. I mean, it's possible, but it's just the amount of time you have to put into it is pretty high. And currently, as a company, Builder has decided to put its resources behind Qwik right now because that's a direct benefit to the customers in terms of the code that they own. And so Partytown is not getting as much love as it would deserve. I still think it's a pretty cool technology that can go places, but it is a hard thing because when things don't work, as you point out, the issue you have is that you now have a third-party minified script that is throwing some exception.
00:50:30 - Miško Hevery
And good luck figuring out, in the minified codebase that is not even yours, what's going on, why this exception is being thrown, what particular bit have you not emulated correctly enough that the third-party code is being confused about it? I think the way to get around this particular problem is to almost create a certification program for third-party providers and basically say, hey, wouldn't it be great if the third-party provider would test their own code with Partytown and verify that it works and there were no surprises, and then either fix it on their side or fix it in Partytown while it's not minified? And then that would become almost like a value-add, right? That you could just brag on your site like, hey, our third-party script runs in Partytown, so we made sure that the setup is easy, etc. So I am actually chatting with folks at Google about this to see if we could have some kind of certification program like that. We haven't gotten very far, but I think that's the way to solve this, because solving it by just trying to brutally go through every single discrepancy in behavior puts a huge amount of resource drain on us, and it's not a simple, straightforward thing to do.
00:51:48 - Ellery
Yeah, I was almost questioning at one point whether it was the right solution, just taking compute and moving it to worker threads, versus something like Zaraz or server-side tagging, which I think Google Analytics supports. I think that's probably where the future is, in my mind, that I have one martech script on my site that publishes events with enough data for a wide array of other third-party scripts to consume from, and it just fans out on the server to everyone.
00:52:19 - Miško Hevery
Yeah, absolutely. There's definitely other ways of solving this problem. I think Partytown just takes it from the point of view of, given the world as it is today with these third-party scripts as they are today, what's the best we can do? And so Partytown is the answer to that. But if you're willing to change what the status quo is in the world so that we just move code to the server, yeah, absolutely, that would be a better solution to the problem. But we're not there yet as an ecosystem.
00:52:53 - Scott Steinlage
I don't know.
00:52:53 - Anthony Campolo
I don't know if anyone here watches the show. Party down every time now I hear Party Town, it kind of makes me think of Party Down. Very good show. People haven't checked it out.
00:53:02 - Miško Hevery
I've never heard of it. I'll check it out.
00:53:05 - Anthony Campolo
Yeah, it just had a reboot actually. Dev, do you want to hop in here?
00:53:11 - Raees
Yeah.
00:53:11 - Dev Agrawal
How's it going? So I had a question about Qwik, Miško. You started the space by saying that Qwik is the performant framework, and you reduce the initial bundle size by basically lazy-loading the interactive bits, and they're loaded once the user actually interacts with them. Once they are loaded, there is another dimension of performance, which is when I click a button or when I open a dialog, how quickly do those things appear on the screen? How much work does the CPU have to do to get there? Or when new data is fetched from the server, how quickly is that displayed on the UI? I know Qwik has a virtual DOM, but Qwik also has signals. I was hoping to get some information about what that interactivity looks like. How does it work with signals and VDOM?
00:54:09 - Miško Hevery
Yeah, good question. Yes, definitely. There are two different dimensions here. There's the dimension of how fast can we make the page interactive, and the second dimension is once the page is interactive, how fast can we update? In order to get the page interactive on your site as soon as possible, Qwik has to be super aggressive about lazy execution of the code. And it turns out that if you want to be aggressive about lazy execution of the code, solutions that are coarse-grain reactive, like for example React or Angular, where when you change something in React or Angular you are changing a state and the whole thing then propagates, a lot of code executes. Things that are coarse-grained reactive do not play well with resumable systems. Because what's happening is that even if you can get the page up and running quickly because you delayed executing the code, the first interaction will likely execute 80% of your application code. That's the problem that you're trying to avoid. Qwik, for that reason, is fine-grain reactive. So that when things update, we want to be surgical about what we update. We do use VDOM sometimes, but there should be a big caveat placed in there because the way React uses VDOM is that it starts at a particular component, and by default all child components get rendered underneath it.
00:55:40 - Miško Hevery
Now, there's ways to kind of short-circuit that and make it render less. But the default behavior is that you start at the root and you kind of re-render everything below it. The other thing that happens oftentimes in these systems is that because you put shared state in a common ancestor, oftentimes your root component, or somewhere close to the root component, is where all of your state is. So any modifications of the state tend to re-render this whole tree for you. And so that has a negative impact on performance. Rather, the main issue there is that yes, it's slower, but the thing that we really care about is the fact that it forces you to download and execute a whole bunch of code that you otherwise wouldn't have to. And so while Qwik does have VDOM, it is very good at basically updating just the component itself. So if you have a situation where you have, let's say, three components, a root component and a child component that has a buy button, and another child component that has the shopping cart, right? And so the shared common ancestor is the root component.
00:56:47 - Miško Hevery
And then if you push the buy button, you're updating state inside of the root component, which then causes the shopping cart to update in a common setup. So in default-behaving systems, the way this would work is that you would re-render everything from the root component. In Qwik, what would happen is that because it's fine-grain reactive, the clicking of the buy button would then directly notify the shopping cart and would completely bypass the other components. They wouldn't even have to download. So even though Qwik in that sense has a VDOM, it really prunes the tree automatically for you, and it prunes it quite aggressively. But what we've been doing lately in Qwik with signals is actually taking it to a whole other level, which is that if you have a component that doesn't have a structural change, meaning if you have a component that has an if statement in there, or show A or show B depending on some flag, that's a structural change to the DOM. If your component doesn't have a structural change to the DOM, it only has updating a binding, like current price or quantity or the total.
00:57:52 - Miško Hevery
In that particular case, we don't even have to download or execute the VDOM. So if the change isn't structural, then the whole VDOM doesn't even come into play, and we don't even have to download the component or execute it or anything like that. We can just directly go and update the DOM. So I would say that Qwik, in terms of performance after you initially load the page, is going to be somewhere between React and SolidJS. SolidJS being the undisputed king in terms of how fast you can go, and then React is super popular, but it kind of re-renders too much by default. So that's a pretty wide band. But I would say we're probably closer to the Solid side than to the React side, because we have signals and we have this VDOM pruning that happens pretty aggressively. And so for most of the operations that you will see, you will actually not even bring VDOM into play. But having said that, I want to point out that there are a lot of websites out there written in React, and for the most part, once the application is up and running, they're plenty fast.
00:59:05 - Miško Hevery
Right. And so while, yeah, it's important to focus on runtime performance, I'm going to kind of argue that it's a bit of a red herring in the sense that just about any technology you choose, usually you end up with a site that's plenty fast for you once it's up and running. Right. It's the getting it up and running part that I think we have a problem with as an industry. And so that's the part that really Qwik wants to focus on. But having said that, again, we're going to be still a lot faster than React. We're going to be probably within reaching distance of what Solid does.
00:59:43 - Dev Agrawal
Yeah, that's great. I have just one quick follow-up. So it's great that you mentioned that runtime performance is mostly a red herring because I think a lot of the discussion around signals has mostly been about the DX. So where do you stand on that? Do you think there are DX wins with signals, just apart from the performance?
01:00:06 - Miško Hevery
Yeah, absolutely. I love the DX of signals. To us, the real win of signals is not necessarily the performance, although that's nice. But really it's the fact that signals allow us to not execute a whole bunch of code. And the not executing code, first of all, certainly it's a performance thing that makes the code run faster. But the real benefit of that is that because I don't have to execute that code, Qwik doesn't have to then download the code. The win to us with signals is not necessarily that they run faster, it's that they allow you to not execute and therefore not download a whole bunch of unnecessary code. Right. And so you end up with a smaller amount of code that has to get shipped to the browser.
01:00:51 - Dev Agrawal
Got it. Thank you.
01:01:01 - Ishan Anand
Scott.
01:01:01 - Miško Hevery
We're at the hour mark.
01:01:02 - Anthony Campolo
You want to do a quick station break? And then, Miško, how long do you have to go for?
01:01:09 - Miško Hevery
I think I'm free after this.
01:01:14 - Anthony Campolo
Well, can I just... yeah. Questions? Great.
01:01:19 - Miško Hevery
We can go, I mean, half an hour after the scheduled one, which was 1:30.
01:01:21 - Raees
Right.
01:01:21 - Miško Hevery
Yeah, I have about an hour, so I'm good.
01:01:26 - Scott Steinlage
Okay, cool. Nice. All right, thank you so much. Appreciate everybody coming up here talking. Miško, thanks for joining us today. It's been fantastic so far, and I'm sure it will continue to be that. Oh man, this has been some great conversation. Just sitting here listening to everybody is so fulfilling. So thank you, everybody. By the way, anybody that's up here that's come up here, and maybe they're not on the stage anymore, either way, if you've gotten value from them, please click on their face there. Be sure to follow them, because I guarantee you, if you've gotten value from them here, then you will probably get value from them in other places. So be sure to do that. And hey, you know what? If you want to give JavaScript Jam a little follow, we wouldn't mind that either. By the way, if you're not already part of our JavaScript Jam newsletter and receiving that in your inbox and getting all that awesome value that Anthony writes up every week, you're missing out. You need to go and subscribe and get that in your inbox so that you can keep up with the things going on in the world, in the world of web dev and JavaScript that is, without having to really search around too much. We kind of send it right to you.
01:02:33 - Scott Steinlage
So not just that, it's usually things that we will be talking about in our Wednesday talk. So feel free to go there and subscribe, and we can go from there. Anyway, thank you all so much. Greatly appreciate it. Remember this as well: if you are a beginner or you're an advanced lifelong learner up here, it doesn't matter. We love to hear from everybody. So feel free to request to come up and we'll bring you up on stage. You can ask a question, comment, concern, fact, statement, opinion, whatever. We'd love to hear from you. All right, thank you all so much. And back to you, Anthony.
01:03:13 - Anthony Campolo
Yeah, and if people are interested in Qwik, these kinds of frameworks, then that's really the type of stuff we cover in the newsletter: links to a bunch of Miško's blog posts and podcast interviews and things like that. We also give you a rundown of the weekly podcast episodes.
01:03:34 - Scott Steinlage
So I think Miško kind of dropped out and then I... yeah, so I invited him back up right now. Cool.
01:03:43 - Anthony Campolo
Dev, I'm curious. Oh wait, Dev also is back down as a listener as well. So Raees, what's up?
01:03:50 - Raees
Yeah, I was just going to bring it to Builder.io. And just for context, as I mentioned, I'm the product manager for Edgio Sites, which is a platform for building and running JavaScript websites. And one of the things we are actually considering is, we have an old framework called React Storefront, and it was an e-commerce web-development framework from a couple of years ago that hasn't been maintained lately. And we are considering rewriting that in Qwik to solve these kinds of performance problems that are so common, especially in large e-commerce websites, and then integrating it with something like Builder.io. So I'm just wondering, do you have projects like that already that you are aware of that maybe we can learn something from? Or how does this sound to you? Would you be interested in collaborating, if I plug myself in a little bit?
01:05:06 - Miško Hevery
Yeah, absolutely. Actually, we do have something similar already. So first of all, we have a Discord channel, and people who are actually building websites have reached out to us and they want to collaborate like that. We actually have private channels where we kind of help them out, etc. There is a company that's actually selling sporting goods, and I can't remember the name of it right now, and they're doing something very similar to what you're pointing out, and they're rebuilding their e-commerce website in Qwik. And so they're having a pretty good experience, and when things arise they reach out to us and we help them out. So yeah, reach out to me on Discord and I'm happy to set something up.
01:05:45 - Raees
Excellent. Thank you.
01:05:51 - Miško Hevery
Yeah.
01:05:51 - Anthony Campolo
Do you want to talk about the kind of Qwik community at all?
01:05:56 - Miško Hevery
Yeah, we can talk about the community. Yeah. So, very proud of the community. I think the Discord channel is now about 5,000 strong. We have what we call Qwik Heroes, which are a bunch of people who have been with us for a while, and they're super helpful, going around and answering other people's questions and providing feedback and building cool things. So yeah, I think Discord is a good place to start, and as a beginner you can get lots of questions answered over there for us. And yeah, we're trying to make it easier every day. Right now we're focusing, as I said, on documentation to get it before 1.0, and kind of a revamp on everything. But yeah.
01:06:44 - Anthony Campolo
Sweet. Open floor right now to any of the speakers on the stage. If anyone has questions, feel free. Could be about Qwik or anything else. And if there's anything else you want to speak about, Miško, that we haven't talked about yet, or things that are coming up that you want people to know about, feel free to do that as well.
01:07:08 - Miško Hevery
You know, if people don't have questions, I can definitely talk about something. One thing I find interesting, I kind of touched on it earlier, is that when we talk to other folks who are building websites using Next.js, etc., there's often a vocabulary mismatch. For example, we have these dollar signs everywhere, right? And so when we first try to explain it to people, they're like, well, I don't have dollar signs or anything equivalent like that inside of my meta framework. Why do you need it? It's kind of hard to wrap my head around it because I was able to build sites without it. So why is this all of a sudden necessary? And you know you can build websites without it, right? We've been doing it for a while. But these dollar signs give you a particular value, which is, hey, you get entry points into your system. And then people, of course, are like, well, what do you mean by entry points? Again, it's not something that I can relate to because we don't really have the equivalent of it. And so we're just kind of constantly discovering that it requires a bit of a vocabulary shift.
01:08:12 - Miško Hevery
So, for example, why entry points? Right. Well, if you want to be resumable, or rather, let's back up a second, what's an entry point for a typical application? Well, if you have a React application, there is a main bundle somewhere that you load, and that main bundle has a function that essentially calls a render function. I forget the latest API in React, but there's a render that kind of gets invoked, right? And if you think about it, that's the only entry point that's available in your system. I mean, yes, if you have lazy loading, then there are other entry points. But for the most part, the way React gets a hold of all of your application is that it starts at the root and then traverses all the components and gets hold of the listeners, etc. Actually, it's not true just for React, it's true for any existing system, whether it's Angular, Vue, Solid, etc. The way these systems get a hold of everything is that they start at the root and they traverse the components. If you want to have a resumable system, you realize, well, my entry point cannot be the root component, because if it's the root component, then the only option I have is, well, start at the root component and traverse all the children and look for everything.
01:09:29 - Miško Hevery
And so you need a way of saying, I would like to enter the system in other places, not just the root location. And so Qwik has to solve the problem of, how do I create a system where there are lots and lots of entry points? As a matter of fact, the more the better. And this is where the dollar sign comes in.
01:09:47 - Scott Steinlage
Right?
01:09:47 - Miško Hevery
Really what a dollar sign is, is a way to get more entries into the system, so that when you render a simple counter with a plus button and a minus button, clicking on plus is a different entry into the system than clicking on minus, because one runs code to increment, one runs code to decrement. And so you don't necessarily need to have both of them present at the same time. And so we find that it's really hard to explain to people why we are doing this, why you need this. But once you understand it, you get new vocabulary that is kind of important. And then with it come secondary problems like, hey, as was kind of pointed out, we now need to lazy load things. Well, how do we make sure that as a developer you don't have to worry about lazy loading? How do we make sure that you prefetch everything? And so on. And so there's a lot of concepts that just aren't available in the other frameworks, and that's what makes it kind of difficult for people to wrap their head around it at the beginning.
01:10:55 - Anthony Campolo
Yeah, I find that there's always kind of a vocabulary gap once you start crossing over. Even if frameworks are ultimately building the same thing at the end of the day, a website, the way they get there could be very different and involve different mental models and terminology. You actually wrote a blog post recently, "Resumability from the Ground Up." Do you want to kind of summarize where that blog post goes? Because I feel like this is another word that is kind of a vocabulary gap with Qwik.
01:11:27 - Miško Hevery
Yeah, so I recently have been writing a lot of these "from the ground up" posts where I basically try to solve a particular problem and kind of take you, the reader, through these steps, like, well, let's say we wanted to do this, what kind of issues would we run into?
01:11:42 - Anthony Campolo
I've really liked them. There's been really good blogging on Builder.
01:11:45 - Miško Hevery
Oh, thank you, thank you, I appreciate that. So the idea of resumability is, what if you didn't want to execute any code at the beginning of your application? What kind of steps would you have to go through? And so what that blog post essentially goes through is, well, the first thing you need to do is, okay, so you click on a button and the button has a listener somewhere, right? And that listener is usually buried somewhere deep inside of your JSX. How do you get a hold of it? How do I get a hold of this listener that's deep down? And so let's say you solve that problem. So the next problem you have is like, great, so now you're executing this listener, but this listener has no state, right? It lost all of the information. It's just code. Without the state of the system, how does it know what the current value of the counter is? Do I add 1 to 0 or 10 or 100? What's the current state? And so you have to solve that particular problem. And so you just kind of go through all of these pieces and you kind of realize, hey, all of these things are things that need to be solved.
01:12:45 - Miško Hevery
But there's no equivalent in other frameworks because other frameworks solve this problem by hydration. And hydration just means re-executing everything from the beginning. There is no resumability. So yeah, there's a lot of vocabulary that has to be kind of learned to get there.
01:13:05 - Anthony Campolo
Very cool. Yeah, I've heard you give that pitch quite a few times now, both interviewing you and listening to you on other things. And I think it makes sense at this point. Took a while, but seems to be.
01:13:16 - Miško Hevery
Yeah, also, sorry, I'm going to go on a tangent here. I also find it interesting that a lot of people confuse resumability with delayed hydration, and the two are really different because in the case of hydration, you're still doing all the work. You're just arguing about when the work gets done. Is it now, or a little bit later? Whereas with resumability, that work fundamentally isn't there. There is no hydration, right? And so if we talk about hydration, we need to talk about how do we define hydration. And a lot of people tend to define it as just, make the page interactive. But I think that kind of misses the point. The real point of hydration is for the framework to recover its internal state. And what I mean by that is the framework needs to know, where are the component boundaries, where are the listeners, what is the state of the component, if this state changes, what other component do I have to re-render? Right. This is really what's being rebuilt as part of hydration. And that's the hard part. The listener part is relatively easy to solve and also to kind of get around, right?
01:14:28 - Miško Hevery
Like, yes, at the end of the day we're doing all this work to make the page interactive, but really hydration is about recovering that internal state for the framework. And so the place where Qwik, I think, is unique is that Qwik doesn't go about it this way. Qwik basically said, look, I had the state when I did server-side rendering, and therefore I just need to somehow move that state from the server to the client. So if I can serialize my state into HTML in such a way that I don't need to rerun any of the components, then I can just literally resume where I left off. And if you think about it, existing applications already have that, right? If you look at Next.js, Next.js takes the state of the application and serializes it into __NEXT_DATA__ or something like that. I forget the name of the data that gets serialized inside of the HTML, right? That's the state of the application so that your application can just continue where it left off, meaning it doesn't have to re-execute fetching of the data and re-execute anything like that.
01:15:34 - Miško Hevery
What's missing is to do the same exact thing, but for the framework. And that's the hard part, because you cannot reach into your rendering framework and be like, give me your state so that I can serialize it in such a way so that when you wake up, you can just continue where you left off. And that's the hard part. That's the thing that I think is unique, and it requires getting your head around it and learning about it.
01:16:01 - Anthony Campolo
Yeah, that was the very big Galaxy Brain idea for me the first time you explained this to me. The state of your app and the state of the frameworks, it had never even occurred to me to think about that before, because I'm someone who has used so many frameworks and for the most part can get them to work and do what I need them to do without needing to know too much of the internals. But eventually you have to actually learn
01:16:23 - Miško Hevery
that if you look at two different kinds of frameworks, like let's say you're in React and then you want to go to Svelte, they fundamentally work very similarly. And so while you might need to learn new concepts, it's relatively, I would say, straightforward because these concepts map one to one. Like, how do I hide or show a component? Well, in React, you use this; in Svelte, you do this. And so you have this mental mapping between the two things that exist. Whereas if you come to it from Qwik, sure, we have the mental mapping of how do you hide something, how do you show something. But then when you start talking about resumability, it's like, I don't have an equivalent thing on the other side. So what are you talking about? I'm kind of confused. And this is the part that is hard. And so what typically happens is people say, well, I don't understand what you mean by resumability, but I have this other thing called hydration, so I think you just mean hydration, right? And so they desperately try to bring you back into this thing, and then you're like, well, no, it's not hydration.
01:17:27 - Miško Hevery
Because what hydration does is essentially booting up your framework, right? It's executing all the code so that you can boot up your system. And that bit is the bit that's kind of skipped.
01:17:40 - Anthony Campolo
I think we do this in tech when we compare things, which is we can compare two things because they're trying to solve the same problem, and we can compare two things because they're actually similar to each other. This happened with Redwood and Blitz. Everyone would always bundle them together and be like, yeah, there's two full-stack frameworks with React, and they're totally different in how they worked architecturally and internally, but they always got kind of bundled together. And so it's like you hear this one thing, it triggers this other idea in your brain. But you have to actually think, wait, these are not the same thing. They're two different things.
01:18:11 - Miško Hevery
So what's the difference? Yes, yes, that's right.
01:18:16 - Anthony Campolo
Cool, we got someone else hop up here.
01:18:19 - Miško Hevery
Yep, yep.
01:18:21 - Speaker 8
Hi everyone. Hi, Miško. I've asked a question a couple of times before about Qwik, so I have a new one in terms of resumability. I was wondering that since you're serializing the closure, is there any specific limitation on that serialization? And do you care about the data types that are available in the closure that's supposed to be serialized and reused again once the app is supposed to resume from that entry point? The other question would be, is there any process like garbage collection or anything like that running in Qwik to sort of unhook the closures that are not being used anymore?
01:19:12 - Miško Hevery
Good questions. So the short answer is that the closure can close over anything that the system knows how to serialize. So obviously all the JSON types we know how to serialize, but we can also serialize promises, maps, sets, and of course other closures. So anything that's serializable is something that a closure can close over, and it will just work. And so this is nice because closures can close over other closures, which then in turn can close over other things, and so on. The thing that's hard about serializing closures is that you need to separate out the JavaScript behavior from the state. These two pieces of data need to be shipped into separate locations. One goes into the bundler and the other one gets placed inside of your JSON-serialized state object. And then the system needs to put everything back together. And what gets even trippier is that let's say you're using server$. Well, in that case, you know what your code is, right? That's just JavaScript that's available to you, and then you know what variables you closed over. But now you have to ship that information to the server.
01:20:26 - Miško Hevery
Except the client is running ESM, but the server is running CJS. So you can't just use the same exact code that the client had, because that's not going to work. So you also have to do a little bit of mapping and be like, oh, right, so that closure is actually the equivalent CJS code over here, so let me execute that code instead. And then you have to put the data back into the closure and kind of make it work again. So there's lots of interesting trickery that has to happen in order to make this available. But I think the payback is really, really nice. One of my favorite ways of kind of seeing how you get a payback is that in most frameworks, if you say, hey, I need to listen to a scroll, let's say that I need to listen to a scroll event, the idea that you could set up the listener for the scroll event on the server and then execute the scroll event on the client makes no sense. Like, what are you talking about? Of course I have to wait until I am on the client, and only then can I actually call addEventListener to kind of set up a listener for the scrolling, right?
01:21:27 - Miško Hevery
But what this closure trickery allows you to do is to basically say, actually no, you can, on the server, before you even have a browser or DOM or anything, execute the equivalent of addEventListener and set up, hey, I'm interested in listening to this thing. But then on the client, you don't actually have to do that. You can just continue running the execution of the listener. And so I think that's the goal, the end goal that you're going after, is that you can essentially skip all the addEventListeners that need to happen on a client. And it's interesting because it is one of the biggest gotchas we actually found in Qwik, that people who come to Qwik from other places immediately kind of gravitate to their old ways of doing things. And so if they want to set up a scroll listener, they immediately say, okay, run code eagerly on the client so that I can execute addEventListener and register the closure. And then we have to be like, no, no, no, no, you're missing the point here. You actually want to execute this code on the server and then have the closure only materialize if somebody actually does the scrolling.
01:22:35 - Raees
So in this case is the compiler, I guess, is it looking at all the event listener calls and then instructing the framework to basically invoke them when that event happens? How does that actually work?
01:22:55 - Miško Hevery
Yeah, so this is where the Qwik loader comes in. Actually, the answer is you cannot use addEventListener. addEventListener is kind of your enemy. And so you need to be able to design a system without it. And so the way we get around this particular problem is that the only place where the listener, the addEventListener, exists is inside of a Qwik loader. So Qwik loader is this piece of code that eagerly executes at the beginning and sets up global listeners and relies on the fact that browser events bubble. Right. So if the system notices that somebody is interested in scroll events, then it kind of notifies the Qwik loader, saying, hey, by the way, I need to know about the scroll events. And so the Qwik loader sets up a global listener for all scroll events, and then when the event happens, the Qwik loader tries to figure out, okay, the event happened, let me go back to where the event originated from and see if I can find a special attribute that tells me which closure I have to execute. And if it finds that information, right, then it actually executes the closure.
01:24:00 - Miško Hevery
So the end effect is as if you executed addEventListener on a server. That's kind of how it looks to you as a developer. But of course, in practice, what it just means is that we kind of delayed it and did it on the client. But we also did it in a way where we don't have to... Normally, if you have 10 buttons and you set up 10 onClicks, then you have to call addEventListener 10 times, right? But with Qwik and the Qwik loader, you only set up a single addEventListener at the root for all click-based events for the system.
01:24:38 - Raees
That's very interesting. It seems like, you know, you hear about these conspiracy theories that all the technological advancements are happening because some government has alien technology hidden somewhere and they're just copying that alien technology, because
01:24:56 - Anthony Campolo
it's zero interest rates.
01:25:00 - Raees
So, you know, it seems like you found the perfect architecture in all of these cases and you're just checking the things off the list, like this is the way to do that. And you know, that's very inspiring. The other way this kind of reminds me of another problem that I've been thinking about and I don't understand. This is when you're using signals, the re-rendering happens much less because supposedly the way the signals change is different from the way useState changes in React. I was just wondering, there's very similar primitives in Qwik as well, where there's a primitive called useStore, I think, and then React has useState, and they seem to work the same way. How is it that one of them can result in less re-rendering and the other one doesn't?
01:26:07 - Miško Hevery
Yeah, so the difference is kind of subtle, but it's super important. And the difference is that if you look at it the way React does it, React is unable to observe where the state is being used. Right. Once you call useState, useState returns to you a value, and the moment React returns the value, React fails to have any form of observability into what are you going to do with it. Whether you throw the value away, or you pass it to a bunch of other components, or you use it internally just inside of your component, there is no way for React to know that information. Right. That information is just forever lost. And because it's lost, React can only do the next obvious thing, which is just re-render everything. That's why it's coarse-grain reactive. So what signals and store, and store is kind of just a slightly different signal, what they allow you to do is that when you get back the value from useSignal or useStore, you don't actually get back the value directly. Instead, you get a wrapper, and this wrapper comes either in the form of a proxy or a getter and a setter.
01:27:25 - Miško Hevery
There's a lot of different variations on this particular thing. SolidJS has getters and setters, MobX has proxies, I think Vue has proxies as well. And so what these proxies allow you to do is they basically decouple returning the proxy from returning the value. So now the framework knows when you're actually getting hold of the value. So when you want to get a hold of the value, you have to either get a property or invoke the getter or do something. And that action is information to the framework. And so the framework then is able to basically make a subscription, make a mark that says, aha, I know that this value has been used here, here, here, and there.
01:28:19 - Scott Steinlage
Right?
01:28:20 - Miško Hevery
And so it stores this information in such a way that if that value changes in the future, that's easy. React knows that because you called setState, and all the other signal systems have some similar way of mutating the value. So when the value mutates, now the system knows, okay, I know who to notify to update. Whereas React, or a coarse-grain system, also Angular falls into this category as well, well, now Angular has signals, but before signals in Angular, right, the framework would just be like, I have no idea. The only reasonable thing to do is to re-render the whole world.
01:28:57 - Raees
I see. As I understand it, the magic is happening at runtime looking at the usage of the value and then... no?
01:29:09 - Miško Hevery
No, the magic happens at runtime.
01:29:11 - Raees
It's happening at runtime. My question is, can we add signals to React, is the question.
01:29:22 - Miško Hevery
Yes and no. So yes, because kind of Preact already did it, right? So that definitely can be added, but it requires slight changes in the way you think about the problem. And the question really isn't about, can you add signals to React? It's more like, if we add signals to React, are we willing to change the developer's mental model of what React is?
01:29:52 - Raees
Right, I see.
01:29:54 - Miško Hevery
And so the issue isn't so much a technical issue as that, in doing so, you are asking the developers to think about the problem differently. And is that different way of thinking about it, is it React? Like, React, for example, really, really prides itself on the idea of pure functions, right? It's just a bunch of functions that you call in any order you want and it just kind of works, right? That's kind of their identity. And with signals, that identity changes slightly. And so the question becomes, is that the identity that the core React team wants for its goals?
01:30:33 - Raees
I see, I see.
01:30:35 - Miško Hevery
But signals are also kind of, like I mentioned, a prerequisite for resumability because, as I said, you could in theory resume something like React, but the problem you would have is that the moment something would change, you would be forced to download and re-execute the whole application.
01:30:57 - Ishan Anand
Right?
01:30:57 - Miško Hevery
And so it's almost like you work so hard to get resumability only to like lose it the last inch of the way.
01:31:06 - Raees
I see, because you're not shipping the closure to the front end, you're just shipping the result or a kind of executed function.
01:31:18 - Miško Hevery
Well, so resumability makes sense only if you can guarantee that the amount of code that you're going to have to lazy-execute is not too much.
01:31:29 - Ishan Anand
Right.
01:31:30 - Miško Hevery
And so if the first interaction basically says that I need to download the whole codebase and execute the whole codebase, then it's like, well, why did you do this work to delay it? You're not really gaining anything, right? And so resumability has a strong preference for fine-grain systems.
01:31:49 - Raees
I see. Yeah, thank you, thank you for that.
01:31:57 - Miško Hevery
You know, you asked me, is this alien technology? No, it's not. But the way I think about this particular problem is that you set a goal for yourself. And for the case of Qwik, the goal is very simple, which was delay execution of the code. And so then you can ask yourself, well, how aggressive do you want to be about this goal? And I find that in life, a lot of times, it's easier to just pick extremes because then you don't have to have a debate about it. Like, you either smoke or you don't smoke, right? It's very difficult to be like, I only smoke one cigarette a day, right? So it's much easier to be at the extreme. So when I started working on Qwik, my philosophy was very simple, which is like, I want to be in a situation where the only time I download a piece of code is if I execute it, so that I will essentially always be in a situation that if I look up code coverage of my codebase, it should be pretty close to 100% at all times.
01:33:05 - Scott Steinlage
Right.
01:33:05 - Miško Hevery
It seems like a crazy extreme thing, but then you just walk backwards from that and you say, okay, so how do I get there? What do I need to do in order to get there? And so you kind of come to the conclusion, well, you need to be able to start at the listener, right? Because the listener, when you click on a button, the first thing that executes is the listener handler. So how do you get the listener handler? Solve that problem. How does the listener get a state? Solve that problem. And then just keep solving it until you either have a moment where this is impossible, or you sleep on it and somehow figure out how to get over that problem and keep going. So Qwik is just the result of that particular point of view. And I'm not saying that your application should only download the code when it has to execute it, but what I am saying is by starting at that point of view, it allows you to build all of these solutions, and then later you can always back off on it.
01:34:06 - Raees
That's very interesting. I guess that if you'd started at solving a different problem, you might have arrived at a very different situation. Instead of having that goal of only downloading the code that's going to be executed, if you tried to optimize the way the state works or some other piece of the problem, then you would basically be reinventing some piece of the existing system rather than reimagining how the system could be built from the ground up.
01:34:53 - Miško Hevery
Yeah, I think that's a good way of putting it. When I kind of started this, I was very cognizant of the fact that there are lots of different frameworks out there, and what I didn't want to do was just build yet another framework that just has a different DX. DX is important, but it's not something I basically wanted to do by itself. And so my very key requirement at the very, very beginning was, if I'm going to do this, it has to solve a problem that others cannot solve, right? It has to be something that is just a fundamentally different thing that can provide value that cannot be solved in other ways. And so this is basically what was the motivation for it. And when I started working on this project, I actually didn't want to solve all of it. I was just like, oh, can I just reuse an existing renderer, like React or Lit or some other rendering system? And I looked into it and I started building prototypes. But very quickly I just kind of realized that it just doesn't fit.
01:36:02 - Miško Hevery
This idea of being able to lazy-load code anywhere and all the time is so pervasive, mainly because it returns a promise to you, right, that you need to have a system and a rendering pipeline, etc., that at any point needs to be able to be handed a promise and it needs to be okay with it and not kind of blow up. And many existing systems are not really good at dealing with promises. It's just not native to them, right? When you look at the rendering APIs of existing systems, they are all fully synchronous. Like, when I call render, it's a synchronous update.
01:36:42 - Raees
I see.
01:36:43 - Miško Hevery
And yeah, there are tricks, like React will throw an exception to tell you, like, oh, the promise is not resolved, try again later, right? But you end up in this state where half the stuff is already rendered and the other stuff is still missing because it hasn't shown up. So, for example, the Qwik rendering pipeline has to understand this and say, look, I am collecting all the changes I'm going to do to the DOM, but until every single bit of it is resolved, I am not rendering it. And so it's a different kind of paradigm and a different rendering model. And so these are the things that I kind of realized, that as much as I would like to reuse existing systems because I don't want to build everything from scratch, it wasn't really possible to get to the world which was highly lazy-loadable like I wanted to get to without also solving these other bits. Also, as I said at the very beginning, we didn't want to build the meta framework either. But it turns out if you don't build the meta framework, then you cannot really show off the capabilities of the framework itself.
01:37:48 - Raees
Yeah. So we are very glad. I am sure all the people who are looking at Qwik are very glad that you made that decision. And it seems like, as I said, we have meetings and chats about this internally, and it looks like the perfect, you know, if you think about the perfect architecture for building websites, it seems like Qwik is doing that. So thank you for that. But I'm just wondering, what is coming down the pipeline next? What are some of the things that I am not imagining at the moment that could be solved or could be done differently and would provide a lot of value to the web ecosystem?
01:38:37 - Miško Hevery
Yeah, good question. First of all, thank you for the kind words. I appreciate it. I like to oftentimes say that we are trying to do every single performance trick that we can think of. If you can think of yet another performance trick that Qwik isn't already doing, let me know, because we'll probably integrate that one too. So everything from lazy loading to prefetching to lazy execution, resumability, everything we can think of, it's all in there. You're asking what's coming past 1.0? So there are certain things that didn't make it to 1.0, and I'm kind of sad, but there's only so much we can do. One is out-of-order streaming. It is still something that we want to do, and I think we can do some amazing trickery with that. That's going to come after 1.0. And we are working with our friends in Cloudflare, and they're building some amazing demos with micro front ends. Unfortunately, micro front ends have not made it into the main documentation yet. So we definitely want to do stuff around micro front ends because we think Qwik is a really good architecture for micro front ends, but it requires a lot more documentation, a lot more explaining, a lot more changes.
01:39:49 - Miško Hevery
And so we're not there yet, and so that's also not part of v1. So I think those are going to be the two big pieces that are going to happen after version one.
01:39:59 - Raees
That's very interesting. So actually this might be one of the things that we're considering, because we're kind of controlling the request from the browser essentially. Because if you build websites on top of Edgio Sites, there is some client-side code that's shipped to the browser, and that includes the service worker by Edgio to kind of prefetch some things. And then we're also controlling the CDN software and the backend as well because our SSR serverless systems are rendering the website. So one of the things that we're considering at the CDN level is edge side includes, something like ESI. So I'm just wondering, if you're thinking about micro front ends, could you specify, oh, this is the ESI tag for the header and this is the ESI tag for the shopping cart or something, and then a service worker can render that and add that into the existing response?
01:41:17 - Miško Hevery
Yeah, actually, that's exactly what we're thinking about. We actually have a nice demo already. So there is a URL, you can go try it out. Is it working? Oh, looks like it. Oh no, it works. If you go to the Qwik dream demo on Pages.dev, it's exactly what you're talking about. The idea is that we want to be able to render a page and server-side include different parts. But the different parts we're including are actually standalone applications. If you think about it, including stuff on a server is relatively easy, but there's more to it than just that. If you just include a chunk of HTML and then the client-side framework wakes up and starts doing hydration, it will override the stuff that you've included. So it's not just about including the HTML, it's also about doing it in such a way that when hydration happens, the hydration doesn't destroy the work that you have done. And it turns out Qwik is really good at this. The architecture of Qwik is really good at this. And so that demo actually shows off specifically this, that we actually have the menu running on a separate edge worker from the shopping cart, from the hero image, from the product, from the comments.
01:42:45 - Miško Hevery
And then all of these things get server-side bundled together. The advantage is that different parts can be cached at different levels and then all become interactive on the client. You can click a button from the main page and the shopping cart updates, even though the shopping cart is a separate server-side include from the button that adds the buy button.
01:43:09 - Raees
Yeah, this is excellent. This is even better than what I was thinking. This is a realization of an idea I had. Excellent.
01:43:20 - Miško Hevery
Yeah, so I think there's a button over there on that site called "show seams" that actually shows you all of the service include URLs and where they're coming from, etc. And yeah, it is kind of the next step, I think, in evolution. If you look at a super-complicated site like Amazon, right, it might be impossible to server-side render it. But if you break it up into pieces, you realize, well, there's only so many hero images that I can show, you know, it's not infinite, and I can pre-render them. And then all I need to know is which one to include over here. And the server-side include is inexpensive. And then if all of this actually works with streaming, then you can get into a situation where you send the menu and the shopping cart, and let's say the shopping cart needs to talk to the database to figure out what's in your shopping cart, and it says, you know what, I'm going to take some time. So don't wait on me, just keep rendering. And so you render the other parts, and then the shopping cart finally figures out what the answer is and then sends back an update.
01:44:20 - Miško Hevery
Saying like, okay, I know the answer is now 3, so go and update it to 3. And so initially you would render a page that would have maybe a question mark for a shopping cart. And then once the database returns, it goes and updates with the actual thing. So that's what we call out-of-order streaming. And it's something that's coming, and not only would it come here, but it would work in a way where it could be through server-side include, right? So if I server-side include a shopping cart, the inclusion needs to understand the fact that, oh, by the way, that shopping cart is not fully done. There's going to be an update coming down later. But don't wait up on me. Go start rendering the hero in the meantime, which is a separate edge worker. And so when this edge worker finally figures out what the update is, then come back and update it, right? Another example of that would be, let's say you want to show somebody a product and you want to show how many items are still available in stock, right?
01:45:16 - Miško Hevery
That might be a relatively expensive query. And so you just want to show the item and for the stock availability just say "computing," or something like that, or a spinner. And then, you know, a second or two later, that spinner would update with the actual number.
01:45:31 - Raees
That's, that's amazing.
01:45:35 - Miško Hevery
Cool.
01:45:35 - Anthony Campolo
So we're gonna start wrapping up soon, but I think we have one more person who has a question. Val.
01:45:42 - Val Nickman
Hi, FSG folks. This is Val from Waterloo, Canada. I love your show, especially the opening music. That's fantastic.
01:45:49 - Anthony Campolo
Thank you. It's me, actually.
01:45:52 - Val Nickman
Yeah, Miško, this is Val Nickman. How are you, my friend?
01:45:57 - Miško Hevery
Hey, how's it going?
01:45:58 - Val Nickman
Not bad, not bad. Yesterday I was going through the documentation and everything, trying to wrap my head around what Qwik is quickly. And so I managed to raise a PR in the process as well. One thing that I noticed is that a lot of people are getting really excited and they want to come and talk about the things they learn about Qwik on YouTube. And sometimes I realize that they have not been able to wrap their head around what Qwik is. And when the documentation is falling behind the development for too long, then those YouTubes, they show up, they will mislead a lot of people. Now my question is, will you be allocating some time, let's say half a day for everybody to get together and take
01:46:48 - Miško Hevery
care of the namings.
01:46:49 - Val Nickman
Because I noticed that so many names are flipping back and forth, back and forth. As an example, useVisibleTask$, which is the final name for it. And so that's one question. The last question is: browser is understood, client is understood. Next.js decided to call everything server-side unless you specify it specifically. But "server" on an edge function that is being advertised as serverless just doesn't make sense. It might confuse the young folks. So is there any way that we could remove "server" and just use, if not "browser"...? Those are the questions that I have. Thank you.
01:47:34 - Miško Hevery
Yeah, so you kind of are hitting the nail on the head as to why exactly we're not in version 1.0 yet. There's still a lot of polish that has to happen. And it turns out a lot of it is actually done by the community. The community is helping us. There are lots of awesome people like Shai Resnick who are organizing others to help with the documentation, help with the starters, improve the starters, the CLI, and things of that sort. So all of that stuff is just extra work that has to happen. And yes, you're right. We originally had the task called, I think, useClientEffect. The problem we discovered is that people came to Qwik with the pre-existing notion of what useEffect is in React, and so they started putting all kinds of stuff inside of useClientEffect that really wasn't fitting, like I kind of talked about with listeners and so on. And so the rename was actually motivated by the fact that we wanted to distance ourselves from the word "effect" because so many people have a preconceived notion of what it is, and it turns out that's not exactly what it is in Qwik.
01:48:49 - Miško Hevery
And so if you just come along and bring your notions and habits, then you're going to end up rebuilding the application in a way that is not performant. All right. And so that's kind of the motivation behind it. So yeah, it's a hard problem, but I think we're getting there slowly. And of course I will encourage you to kind of help with it. If you want to help with the documentation or anything like that, by all means jump in and help us.
01:49:17 - Val Nickman
Absolutely. I got my PR merged in yesterday and I'm just warming up. So yeah, expect more PRs from me. Thank you.
01:49:25 - Miško Hevery
Excellent. Excellent. Awesome.
01:49:30 - Anthony Campolo
Well, I think this is gonna
01:49:32 - Miško Hevery
wrap it up for us.
01:49:34 - Anthony Campolo
Thank you so much, Miško. This has been such a great conversation, and thank you everyone who came up to ask questions and speak. Yeah, I think you have your Twitter right here, people can follow you, and they can check out Builder.io and Qwik. Are there other links you want people to be directed to?
01:49:54 - Miško Hevery
Builder.io, Qwik, and Partytown, I think, are the main places to go. And of course, from Qwik and Builder.io, you can check out our link to our Discord, and there's lots of friendly folks to help you out.
01:50:08 - Scott Steinlage
Yeah.
01:50:09 - Raees
And actually at the end, I would like to thank Miško myself as well, and thank you for coming here, and especially for the work that you're doing and the contribution that you're making to the JavaScript ecosystem and the web ecosystem in general. So thank you for that, and good luck.
01:50:33 - Miško Hevery
Thank you for the kind words. I appreciate it.
01:50:35 - Scott Steinlage
Yes, yes. Everybody, let's give Miško a huge round of applause. Applause. All right. Oh, the applause had to stop. So unfortunate. Thank you so much. Thank you so much, everybody. It's been so, so good here today. Miško, thank you for all this wonderful time that you've given here in your busy day and schedule. So greatly appreciate it. Everybody also coming in the audience there and listening in, and if you came up to speak, thank you so much for that too. And just remember, we will be here every Wednesday at 12 p.m. Pacific Standard Time, as always. And be sure to give us a follow on JavaScript Jam there and go subscribe to javascriptjam.com and the newsletter there so you won't be left out missing out on any of the awesome things coming up. So with that being said, really excited for the future here. We're going to be doing some events. In fact, one that I will announce, we are going to be doing some collaboration with Remix Conference, and we've got more to come on that in the near future, and there are a couple more events as well that we'll be talking about soon. But yeah, I'm excited about the Remix Conference coming up here in the near future, and we're going to be having some speakers from there come on here as well and join us to just have some great conversation.
01:52:07 - Scott Steinlage
So keep an eye out for all that. Join the newsletter for more information. All right, thank you all so much. Really appreciate it, and we'll see you in the next one. Thank you. Peace.