skip to content

Qwik + Astro perf on perf on perf

with Steve Sewell

Qwik introduced resumability in JavaScript apps. Astro introduced a “just in time” approach to building complex frontends. Together, are they unstoppable? Steve Sewell will teach us.

Topics

Transcript

Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, friends. Welcome back to another episode of Learn with Jason. And today on the show, we're bringing back Steve. How are you doing?

STEVE: I'm doing great. How are you, Jason?

JASON: I'm doing so good. I'm so happy you're here. I'm excited for a lot of reasons. I've loved watching your content, you have good short format comment on getting better at code. You're building cool stuff over at Builder and doing interesting stuff with Qwik. And before I get this all wrong, why don't you give us some details on what you are, what you do?

STEVE: Yeah, co-founder of a company, Builder.io, and we do Figma and with the code and pump out the APIs to your website. Take it to the home page, publish, boom, and get off the backlogs. Marketing wants a change, marketing can do the change. That's the idea. We make cool open source projects. Obsessed with how to build and deliver amazing web experiences, easy to build, et cetera. And it can be integrations like Figma, building with Qwik, building with Astro, party town, mitosis. It's hard as a startup to do all the things, but we do our best.

JASON: Yes, absolutely. And it seems like you're doing a pretty good job. Everything that comes out feels quality. Especially there's been a lot of hype around the Qwik stuff. And I think for good reason. Like the Qwik stuff introduced something that I have never seen before, the concept of resumability. So, if other folks are like me and this was a brand new term, do you want to give us a quick overview what have resumability is?

STEVE: Yes, totally. For really brief background, the way that I came about to pairing with Misko and saying, oh my goodness, Qwik is incredible and we're investing significantly in. We made this builder platform, this way to make a visual editor, pump it out to code, whatever framework you have. Whatever we see is people see a drag and drop GUI editor, people compare it to legacy things like Microsoft Front Page, modern things, web server or Wix, but that's going generate poor-performed code. Buggy or ugly, it's gonna hurt my site performance. I'm a developer, I need to manage that by hand. We are proud, drag and drop, make something. But then crunch it down to be highly-optimal code. But what people were doing, going to our website, content generated from the platform and, oh, you know, this is a 40 in Google PageSpeed Insights. And why is your site not faster? Why is our site not faster? Why is nobody fast? It's a decent scale, not your personal blog or something. This is silly. It was a React site, using Next.js or similar, well, we could ask for any plugin. We plugged Vue, we plugged in SolidJS, Angular, Svelte, all the things, and the same content written to the Canonical code of the frameworks. The best was with SolidJS. It was 45. It was still not that much higher. Where is the hundred or 90?

JASON: Right.

STEVE: We couldn't figure it out. We have this cool technology it take a JSON representation of this site, home page, and modify it any weird way. It's kind of a pipeline between the conceptual kind of UI and the output code. Let me try messing or hacking question at how we generate output across these frameworks to see what would be fast. Eventually, I was trying everything. And the most I could squeeze out of it was like a 46. I was losing my mind. And eventually, I was like, let me get more drastic. Delete all images, is it images? Render the site with no images, see the performance score. Not really faster. Tried rendering with no CSS, not much faster. No JavaScript, let's see. Shot to 99. I couldn't move it two points. When I just deleted JavaScript, it was perfectly fast. After a lot of time, I was like, this makes sense. You think that a web page is HTML, you're displaying -- it's a home page or static page.

JASON: Right.

STEVE: Who cares? Mostly links. What you're doing is rendering the HTML, it's a facade with the majority of frameworks out today, barring Astro, and React components, but what was out there at that time, you're downloading all the JavaScript for that page, hydrating it all, executing, re-rendering the page, even though you're not replacing DOM nodes. And then your site could be interactive. One amazing insight was the fact that our frameworks were dependent on inserting rows quickly, making granular transition quickly. And the weight of the framework itself. The weight of the framework doesn't matter at all. It's the weight of how your code loads into your web page. If you're duplicating all of the code that pre-rendered the page and downloading again to hydrate client side, especially when it's not interactive.

JASON: Right. And to put a very fine point on this, one of the big challenges with hydration, you are putting all of the data, every word in the site comes in the pre-rendered HTML that is static. And also if you look down at the bottom of the rendered markup, there's a script tag that has got this giant JSON object that duplicates all that have data. You're doubling the size of all of the content on your page just by virtue of doing this hydration. Which seems trivial until it's not. Then it's really not trivial. This was the thing -- there was that big thing about a government site where they leaked everybody's Social Security numbers because they didn't understand how hydration worked. And in their static builder, they had loaded everybody's data. And then they only rendered the data they needed on the page, but all of the data went in that JSON blob. Somebody viewed source and started copy-pasting out people's identities. It's one of those things that it's sneaky. But man does it add a ton of weight to a page that has to then be parsed and rehydrated and all of those things. So, anyways, I interrupted you. But I feel like that's an easy one to forget if you have never actually viewed the source of one of these hydrated pages.

STEVE: That's spot on. There's three layers. Basic HTML, Astra, PHP, Qwik site, that's all you load. But with hydration, JSON, and then JavaScript, that HTML in JavaScript again. It's crazy. Loading the same thing three times over. And the JavaScript one is particularly expensive because it's executing a lot on startup. Might want to click on the link, maybe it's a little JavaScript, it can't run until hydration completes. It was crazy. What we did is we're like, okay. Maybe some other sites have a solution that works. So, we took like the top 50 eCommerce sites. They get complex over time, especially large ones. There's a lot of code. Developers every day, here's a ticket, add this code. The codebase grows, and the amount of code on the client, even if not rendering, tends to grow. Your package dependencies. It gets hard to manage. We took the top eCommerce sites. Also eCommerce, the industry knows very well that the slower your site is, the more money you lose. It's literally just dollars. One second slower is like a billion dollars at a certain scale. It's highly measurable. They know the sites have to be fast, they're losing money if they're not. I made a spreadsheet, plugged the top 50 into the Google Page Insights. And the average score was 13, very, very low. We made a CDN proxy, strip out all JavaScript, images and CSS. And we saw the new scores. And on average -- I forget the exact numbers, but in the ballpark, strip out CSS, a point or two, CSS, a few, and strip out JavaScript, it goes up 85. Everybody is executing way too much client side. And the way the frameworks traditionally worked, it fed into that. I started playing around, can we do something crazy and start creating a custom output target. Generate HTML and little bits of inline JavaScript for the minimal activity. Skip everything else. The redundant data and JavaScript downloaded execution. But I was having trouble scaling it. I never made a framework before. I was making a compilation, then made for our platform. Then I met Misko, I'm working on this thing. At Google, there's an internal framework, Wiz, powers Google, framework, et cetera. He uses a technique to add HTML. When you click this, this should execute by paths to where the JavaScript paths live. And it's clever, the bare minimum JavaScript needed is prefetched, but not executed. They have a compilation system that what runs on the client is as lazy and granular and minimal as possible. He said the DX was brutal, it was on legacy Google systems, Java backend and it was weird and all this stuff. But the runtime execution was incredible. Insane performance, complexity. Hey, I'm making this Qwik thing, don't download or execute JavaScript to any site and make it feel like a modern framework. Make it feel like you're writing a React app. And I was like, hey, I have data to show you. He was like, wow. Hooked up to the builder site, and tested on a few others. We're investing. That was kind of the genesis.

JASON: Yeah. And so, the general idea here is like we -- so, if I attempt to nutshell this. So, the challenge is that the way that we've been writing JavaScript has been basically I would say wasteful. We render is on the server, we ship the static markup, render it into JSON, ship that as a script tag. And then send down the JavaScript which then has to boot -- like be loaded -- boot on the client side and execute everything, update every DOM node. Regardless of whether or not it needs to do anything. Because we have to have that vDOM rebuilt, or some representation of the DOM in order to let the JavaScript framework continue to do the thing it does. Two approaches to this. Qwik as you just described is basic life compiling in line and using attributes and a very small runtime to allow things to basically -- you don't duplicate data. You're just putting everything into the framework with a way for that light runtime to immediately start using things. It's as you say, resumable as opposed to hydrated.

STEVE: Yes.

JASON: The other approach that we've seen is the Astro approach. So, Astro is taking this sort of just in time approach where the vast majority of things on a website don't actually need to be JavaScript at all. You just want to use JavaScript to author them. And what that means is that, you know, I write my React components or my Solid components or my Svelte components, and the Astro framework will come file that down to HTML. But because there's no interactivity on these things, it doesn't bother shipping a JSON object or a framework, it just ships what it needs. An Astro site ships JavaScript, there's your 100% score. But when you need interactivity, you can add an attribute that flags that and it will bring in the thing that you need just in time. Now, this does reintroduce hydration because once you reintroduce the framework, you have to use the framework. When you're using React components and you flag it to run just in time, it's not that much React, but that React has to ship its JSON object, rehydrate, all that work has to be done. It's just less work. Overall, Astro is getting a big performance. But what if we could do both? And I didn't think this was possible. I kind-it in my head, these were fundamentally incompatible concepts. I thought you had to choose one or the other. But can you ship Astro just in time with resumability as the strategy for that interactivity?

STEVE: Yes. 100%.

JASON: Amazing. So, this is very, very exciting. So, I have questions about this. And I think I'm gonna try to stick to just a couple questions because I want to spend a lot of time building. But I am very curious like was this hard? Like did this require -- because it bends my brain trying to think about how you would do there. How did you implement this in practice?

STEVE: Great question. First thing, huge credit to Jack Shelton who built this out. Huge work, I want to call him out prominently. I want to call this out. At a high level, we thought similar too, hey, these are supposed to be zero JavaScript by default. Very efficient way to distribute HTML to a client and load JavaScript minimally afterward, right? We thought at first, oh, these are different things. And you would use one or the other. We then came to realize, actually, at the end of the day, you know, Qwik is just sending HTML over the wire with attributes that make the subsequent activity for performant, fine-grained to load. And at the end of the day, Astro was a way to write HTML. One amazing thing about Astro, there is virtually no magic. If you don't write -- you're very aware, if you're writing client-side JavaScript, it's gonna run client side or not. There's no ambiguity. Is RSC going to run this way? By default, none, add the React component with the inline tag, it runs and the DX is really nice across. Because at the end of the day it's a way to send HTML, it opens up these interesting use cases like micro frontends and the Qwik containers are these encapsulated things. At a conceptual level, it's straightforward. If you're sending HTML, it's Qwik HTML alongside and aligned with everything else. The reality is because Qwik was originally made as kind of Qwik Core and the Qwik City, that is a layer on top that's a totally separate layer and you can make additional, call it meta frameworks, on top of this. It was supposed to be -- but when you're building and making things work and working with Qwik City. There were lots of things that we did not think on making it compatible, easy to plug into other places. That's the hard work Jack did. Reverse engineer all of this. It's probably only a specific couple things to make it compatible. But digging in with the assistance of the team, but high level, super simple. And Astro and Qwik. And it has a nice surprise attribute, the DX loading Qwik inside of Astro works like you would expect. Import Qwik component, render it in the Astro jsXe style. But you don't use any of the hydration attributes. Don't use load client visible, Qwik, that's all automated and HTML by default. Handles the granular you would almost call it microhydration from there.

JASON: Microhydration. I love it. One of the things I love about JavaScript, and I say love with a massive amount of tongue-in-cheekness. Stacking a niches. It's my favorite thing.

STEVE: Don't get me started on that, we thought we needed an acronym for the Qwik something, something. Just don't. Don't make an acronym. Invent a word if you have to, "resumable," but don't make an acronym.

JASON: resumability makes sense. I like the idea -- and this is something we have talked about a lot is the idea that you want things to be interruptible. You don't want them to be destroyed and then rebuilt entirely. You want them to be, you know, you want your logic to pause and then continue when it's time, right? This is a big goal. And I just don't know that we'd ever really find a way to crack that in the server client boundary. Kind of until here. Like this feels to me like -- maybe -- and maybe I'm wrong. Maybe somebody can correct me. But I don't think I've ever seen something that does this before. This feels like a net new accomplishment in computer science is this idea that like with Qwik, you get to do some work on the server and then just send the pause state of work to the client and then resume that work as if it was never interrupted on the client side. This has some really interesting things like y'all have been able to, for example, serialize functions across the server-client boundary. That still kind of melt -- and I know that that's out -- now that that's out there, I think it's introduced into I think Remix has it, and they're figuring it out in React. But, like, how? This stuff is so freakin' cool. The idea that you can send a promise from the server to the client and it doesn't explode just very, very interesting things are happening in JavaScript right now. And I'm really excited to see how -- as Sinaniya is saying, push those boundaries. Really moving the goal post in terms of what the most excellent approach is here. And with that being said, let's see, anything high level we want to cover before we start playing with code here?

STEVE: Yes, one more.

JASON: Let's do it.

STEVE: One more metaphor to share how this works. I didn't go into the details of where the concept of resumability comes from.

JASON: Sure.

STEVE: But you're spot on. The way Misko describes it, the way it's built in his metaphor, call it replayable. You call it -- your application computes on the server, and you snapshot the HTML and distribute to the client, a bunch of other metadata. Gonna be a lot. And then replay that. Send all the JavaScripts on the server to re-create on the client. The client sort of wakes up with amnesia, no idea what's going on and has to re-execute everything and hopefully land in the same state it was before. And the frameworks make sure that's the case, sometimes it's not. Hydration is a pain, we release as modal, it's a pain point.

JASON: Have you seen the movie memento? He has to look at the notes and has important facts tattooed on his body so he can figure out what he's supposed to be doing.

STEVE: Totally.

JASON: That. If you have seen memento, that's replayability.

STEVE: Wake up every day and figure out your whole life. That's rehydration. And resumability, Misko describes it, load a VM on one machine and pause it and distribute to another machine and wake it up. You don't reboots the operating system. That's an innovation, especially being able to distribute that, is just a fragment of HTML at a time. It's cool that's why it works so well with Astro. And why it opens up all kinds of new possibilities. We have people experimenting with use snapshot sum state at the server, sum state at the edge. And there's a demo, open up a to do app, fill in the to dos, and the client, and paste in another browser and start where you left off. The full state is resumed. It's wild. People might be watching, who cares? Why do you need that? Actually it solves long-running challenges. And this is the last thing to conceptually share then we can dive in. One thing this enables, a lot of crazy stuff. You're right, a lot of interesting under-the-hood work. Not just serializing functions, which they are adding, top level functions. But serializing closures. Having a function callback, it captures scope, referencing variables outside of its own scope. Capture that, distribute it over the wire in a superefficient way. Some people have said, wow, you're just overengineering the heck out of a seemingly simple problem. I can see why it looks that way. But here's a way to look at the end result. One way to talk about it. This way of running current applications. Maybe a long time ago when you had to download a video in your web browser, download the whole video, and then you hit play and watch it. Quite an innovation to watching videos online or in any sort of distributed mechanism is streaming. Buffer just a little bit ahead and then you can watch flawlessly without having pre-downloaded the whole thing. That's what this enables, we call this JavaScript streaming. The idea that you're on one page and we can buffer, we can pre-download little bits of JavaScript, and it's pre-executed when needed. None of it pre-executes. And it's as lazy as we can make it, no negative consequence to performance, which is good. But what's wild about it, unlike a video that is linear, one start and one end. Navigating a website is extremely multi-dimensional. You can go many different ways. That's what the tech enables. You have out of the box, smart prefetching, anticipated user paths and only on an as-needed base. You can be offline, crank it up, all is downloaded, easypeasy. And what we call Qwik insights. What it is, it's inspired by Misko, Guess.js, are you familiar with that?

JASON: Yeah.

STEVE: It looks at Google Analytics for your site and looks at what the user paths are. And based on that, it will do start prefetching. Most people go from your home page to your product page, prefetch that immediately, it's ready, lightning fast. Much smarter than what we do today. If this link is visible on the page, the menu has a hundred links. What do people click on? With Qwik, you can plug in a similar mechanism and on a granular basis, and most people hit this page, it's pre-streamed. I'll stop rambling about cool stuff and we can dive in and learn together.

JASON: I saw a question that I think is good. Astro does page transitions and things. Does Qwik work with view transitions and things like that? It seems like the answer is yes.

STEVE: Yeah, view transitions, the fundamental level, the browser feature, absolutely. A good way to think about it, one way to put it regarding Qwik and Astro, by default if you're building with Astro, HTML-only. Like all things, reach for the JavaScript only as-needed. In line JavaScripts, if you have very trivial functionality, amazing. Whenever you get to that point, I've got some complexity, rendering a to do list with iteration, needs to update, feel fluid on the client, not making too many round trips. That's where you can reach for React or the analogs. Or in this case, if you want to have topnotch performance, maintaining full complexity of interactivity, a React-like DX, but everything is client side rendered and updated to what you need to feel nice, reach for Qwik instead and use it the same way you would. Bytes called -- React the good parts. Used signals instead of states. I don't like state. Or use JS. A modern hook style. Feel familiar and modern in that sense.

JASON: For anybody who wants a one on one how Qwik works, we have had Misko on several times. Actually, why don't I take us over into this view here. And I will actually just pull up a couple links here. So, let's look at the site. It you go to Learn with Jason, hit command K and search for Qwik, you are gonna find concern here is something on Qwik City, the framework for building with Qwik. Intro to Qwik here, update on Qwik 1.0. And after -- as soon as Steve and I go offline, this one will be available to watch on demand. Lots of Qwik content here on the Learn with Jason site. You can make sure that you go and check that out. And then we are talking to Steve. So, this is Steve's Twitter profile. You can go and do a follow there. We've got the Qwik home page. If you want to go and get those details. Here is Astro. Which we're gonna be doing the combination. And then over here, I've got this page on how to integrate Astro and Qwik on the Qwik docs. What else? What am I -- all right. At this point, I have -- I think links to things. But I'm not sure how to get started outside of just saying, Steve, what do I do next?

STEVE: Yes. Yeah. Let's find the right doc for you. So, in this case, I think this is the right one. So, scroll down on this page a little bit. We will need an Astro project and then, yeah, we'll follow the installation which is really just two steps.

JASON: Got it.

STEVE: First is create from the Astro docs.

JASON: And npm Astro, latest, if I can get my keyboard to push the right keys.

STEVE: I love Houston.

JASON: Houston is such a good idea. All right. And so, we are going to call this one... Qwik-Astro-perf. And should I -- do you want me to keep any files or go empty?

STEVE: It's up to you, either works.

JASON: Let's go empty, keep it simple. Write TypeScript, new, newer repository, yeah.

STEVE: I love that you use Twitter instead of X. I have been hard core using Twitter instead of X. Everybody gave grief -- I went back, not saying X. I appreciate that.

JASON: I will call it X when they make it good again.

STEVE: When it's good again. I will join that pact. 100%.

JASON: Like, I know I'm being grumpy about this. But also like, that was -- it was my favorite place and now it's sad.

STEVE: Yes.

JASON: Okay. So, here we go. We're in this -- I'm not gonna do that right now. Let's close that up. And all right, I've got my site. So, this is a bog standard Astro site. All we have in here, let me make this a little bit bigger so we can see what's going on. I'm gonna close this down. This is basically all we've got. We've got our Astro config, empty, package JSON, the bare basics to make Astro work. And we have this one Astro file which has no Astro features in it outside of sharing what version of Astro you're using where you publish the site. From here, I want to add Qwik.

STEVE: Yeah.

JASON: Keep this open. And looks like we got some deals here. I saw Elian from the Astro team was saying that there's even an Astro command for this.

STEVE: Oh, is there?

JASON: This is it right here. Npm Astro.

STEVE: Yes.

JASON: Here we go. I'm gonna grab it. And this is my -- this is my favorite thing about Astro. I think this is so clever. So, I've gone to add this. And it says: Do you want to install all the dependencies? So, not just the Qwik Dev thing, but like, hey, we need builder Qwik, we need the right version of TypeScript. Okay. Great. Yeah, let me install. Do you want to update your config? Here is the code we're gonna add. God, this is just a good experience. Now if we go out and look here and open up my config. We're done. It's in there.

STEVE: Yep.

JASON: I love you, Astro.

STEVE: There is one last step, and I actually wonder, we should ask Jack this. I wonder why we don't do it automatically. I have a guess why we don't do it automatically. Scroll down, update the TypeScript config. If you're using TypeScript, I think most people do and should, it matches the JSX import source of quick needs.

JASON: Where is my -- here it is. It was there. I was trying to type TypeScript. All right. Let's add the compiler options. And gonna stick that right there. Good, good.

STEVE: That should be it. Now when you scroll further down on the doc, it will give us a component we can copy and paste in. There we go. Adding the component further down, sorry. Ignore that.

JASON: Oh, here we go.

STEVE: Now, we can grab that code. It's not pretty. Just a button with text inside.

JASON: Got.

STEVE: And then we can create a new file. You can add a file, source components, count it, CSX, whatever. And then paste it in, we can import it.

JASON: Okay. counter.CSX and copy this component here.

STEVE: Yes.

JASON: Let's take a quick second. Make this bigger, hide this, close this down. And let's just look what a basic Qwik component looks like. So, things that are really familiar to me. It's the capital C counter. so, it looks like a component the way we're used to. We're returning JSX, return the markup that I want to use. A lot of the rest of this looks fairly familiar. But a little bit different from what I've seen. If I want to put a value in, put it in curlies just like in React. I've got some functions here. This use signal has got like a hook vibe. But it also has the solid signal vibe. I can see the dot value is very signally. Any specific notes here? Like there's a couple things I've never seen before, like the dollar sign attached to a couple things. Is that to make it very clear that you're using a Qwik feature? Or is there another reason?

STEVE: Great question. Yeah, so, the dollar is really, really critical here. You're right. The hooks and signals works most similar to Preact.

JASON: Okay.

STEVE: Solid is really unique, you don't ever rerun component functions ever as you're probably familiar. You don't use things, you create things. Pushing the point, it's done, it's there. Which is a really cool feature of it. In our case, we actually found Preact's approach to be the most elegant for Qwik in that you have maybe a closer balance to what you expect from React with the benefits of Signals. That was one of the closest inspirations here. And you have stores which are like recursive. If you have a products list and the whole thing needs to be observed. If it updates, anybody who renders from needs to get a re-render or granular patch, that happens automatically. Vue is a close comparison. Taking the best of what we've seen and the fitting for the framework. But the dollar sign, that's the most important thing here. We talked about, we can serialize all these crazy things, serialize a closure, a signal, a promise, a function, whatever. So, the dollar sign is something you'll see throughout Qwik. You will see it, wrap components in a component dollar. And also for the event handler or onClick, that ends with a dollar as well what that does is it signals to our compiler. So, it's a special sort of token, anything that ends with a dollar sign is something that our compiler and other tools are aware of as a serialization boundary. What that means, anything that crosses a dollar sign, a good example would be a counter variable. Is outside the dollar sign when defined. And inside the dollar of the dollar sign whether referenced. That is a serialization boundary. Something you cannot do here -- I'm trying to think of a weird example. We can serialize so many things, it's actually hard to come up with an example. I don't know if I can off the top of my head. At least something that makes sense. What's a Node.js-specific API? Actually, that's a good example. Here's an example. Let's say at the top of the file, you did import FS and FS. Importing JS specific functions. And during the on click, and the status analysis and ESLint phase, you can't do that. Oh, my goodness -- you know what is crazy? This map thing, balloons up here, you have to disable it per application. I haven't disabled it for Chrome yet.

JASON: It is atrocious. It's funny because once you find it. Hold on, let me go back. You can start turning them on just by like, hey -- let's do a...

STEVE: How do I do this?

JASON: It's up in the little green camera thing. And then you can drop down the cameras and just start doing effects. And it's --

STEVE: Oh, I see. There it is. Oh my goodness.

JASON: Absolutely ridiculous, but hey, why not?

STEVE: Was in a board meeting on Zoom -- one of the best benefits post-pandemic is I can join board meetings wearing sweat pants. Nobody knows. It's remote, it's amazing. But I was in a board meeting one time. Had a very serious discussion, very difficult. And out of nowhere, balloons came up on a camera. Everybody was trying not to laugh. It was the worst possible timing. I don't know what they did. But anyway, so the -- we will statically analyze -- this is important for many things, performance and security safety, all the stuff. You can't take, for example, Node.js APIs and shoot them out to the clients. We will not allow that. That would be absurd. Don't do that. Even if it could be done, don't do it. The dollar sign makes it clear. Anything that crosses a dollar sign could go from server to client. And guarantees, we have the server dollar function and stuff like that. But in this case, that tells you, the human, the compiler at sort of parse and check time, lint time, as well as the compiler at distribution time, if there's a dollar, things have to serialize to get over it. As soon as won't work, we will tell you. And in the majority of cases you don't think about it.

JASON: Yeah. Got it. Okay. So, we've got a basic counter. I have -- let me see. Let's look over here.

STEVE: Yeah, use it. Yeah.

JASON: I've got my index here. And then I believe I can do the thing that I always do.

STEVE: Yep.

JASON: Which is import this right from my components counter. And it should just autocomplete for me. It does. There we go. And then down here... I'm gonna put in my counter. And I'm gonna intentionally do it wrong to start. So, here's my counter. I've put it in.

STEVE: Yes, jesuit.

JASON: Then I'm gonna run the site, npm run Dev. And that starts me up on four, three, two, one. Let's go over here and open up 4321. Here is our Astro site. This is the Astro part. And here is our Qwik component. And what the hell?

STEVE: I was wonder for you were gonna catch that.

JASON: Whoa, hold up. Hold up. Okay. This is magic. Check out what just happened. In Astro, to make something dynamic, you are supposed to have to include a client directive. Because otherwise you're doing a bunch of unnecessary hydration. But we're using resumability, folks. Apparently it doesn't matter and it just works. That is freakin' dope. Talk to me about this. Does this --

STEVE: Yeah.

JASON: Like did I accidently load a bunch of JavaScript that I didn't need to load with this approach?

STEVE: Great question. That's the beautiful thing. And in fact, that's funny. That surprised me too. Wait a second, we did something I don't think wrong. No, we didn't actually, we did it right. I'll describe in more detail. The way to think about it, in my opinion, Astro is the best opinion to create HTML-first applications to distribute to clients. I love, love, love, it's the awesome modern PHP we never had. Inline script tags compiled -- all the little things. What it does is also gives the ability to have resumable HTML, magical HTML. I refrain from magic, but it's a little magical in this case. If how click on the browser Dev tools and click on the button, we can show interesting stuff. Original work, things are prettier. Optimized and things are less pretty, but see the big thing. The big thing to see is yes, the on click attributes. In junk mode, other stuff to add that's stripped out in production. On click, when we distribute this HTML, it has a path too -- that's a path to a JavaScript file. It doesn't say dot JS at the end. It used to, that's sort of convention. But don't actually need that in reality. That's the path to JS. It could be called you know slash, hash, dot JS. The thing we do, if you add a Qwik component, add small JavaScript for a boot load. Regardless of the amount of components. This is the Dev load version, smaller in production. We sometimes -- this is a bit pedantic and not entirely accurate if you want to go deep on the perfect use of the term. But we call this generally speaking an oh of one framework. No complicated how your site is, no matter how big it grows, that's all the JavaScript you will ever load. All the JavaScript does is two things. The most important thing, it listens for if you click an element that has an onClick in it, it will find the path and import and execute that one specific file granularly. And second, prefetch. It will scan for the things and prefetch those things in a smart way. In reality, what's happening is the boot loader runs and looks for those onClick and on whatever attributes and finds the path to JavaScript and prefetches those. And actually uses a service worker for that to do it in a smarter, more optimal way. And then when you click on that button, it's going to import that JavaScript file in normal ECMAScript fashion. And that will be in your browser's cash and load immediately and execute it. No JavaScript executes on load besides this tiny boot loader no matter how big the application is. As you react, the compiler does this for you, you just pretend you're writing React. We will take care of that. You're not writing inline JavaScript and wiring it up in all those nuances.

JASON: That is extremely cool. I'm looking down here to see -- here's a little more happening. But look at what's actually happening here. It's not very much.

STEVE: Yeah, I think some of these might be -- only as well --

JASON: Is this also what happened when I clicked? Let me reload. And I want to look to see what's happening here. Okay. So, we've got this, we've got our quick loader. It is pretty impressive that you can fit your entire framework, including Dev mode, on to one screen.

STEVE: Yeah.

JASON: So, then we've got some refs here. And then when I go to click one of these, we'll see...

STEVE: It won't update. We won't synchronize the update back. That's just for the sort of like hand-off so to speak.

JASON: I gotcha.

STEVE: There is a utility to write it back. That is useful in the cases where -- let's say you're doing something where the server generated HTML and the edge picked it up and modified and continued. The edge writes it back, that makes it distributable over a wire. How we used to do it, inline attributes everywhere. In the old way, the button its held on toes it own state. But the tiny JSON turned out to be more optimal for that.

JASON: Gotcha. Gotcha, gotcha. I think by comparison, like if we look at -- what's a -- what's an easy example for like a -- I'm trying to think of a next site that's not me just picking on the team directly. Let's just pick on the Vercel team directly. If you're looking at the bottom, you're gonna find the next data -- which will be... where is it? Boy, there's a lot in here. Am I going to be able to find this if I -- like next data.

STEVE: Where the app router, they may not use next data anymore. Lots of -- I think that's streaming, chunk-by-chunk.

JASON: I got it. That's not a good example. Whatever. It doesn't matter. So, the general idea is that you get -- you get a lot of extra stuff down in the bottom and that JSON object is big. It's a hefty -- a chonky boy.

STEVE: Exactly.

JASON: It's nice to know that I don't have to worry about that.

STEVE: Exactly. And one thing in the chat that's pretty good, if the JavaScript is prefetched by a worker, what happens when you have a big JavaScript chunk? Is there a limit to loading times? This is important to point out. Prefetching, working in the service worker in JavaScript is in terms of all user kind of experience metrics, all Lighthouse metrics, it's literally free. If we wanted to, in the background we could download infinite JavaScript. And it hogs resources and the service worker lets us be smart and prioritize. That's the beauty. Let's imagine a scenario, excuse me, where you've got a page, a web page. And one component on the page is actually extremely heavy. A lot of client-side JavaScript. There's no way to pre-render any of it, it's WebGL. It's all got to render to the client. In the typical React sort of way, we would have to download that, execute all of it before any of the site itself is interactive at all. You're paying an up front penalty, it affects the user experience, the Lighthouse metrics for the user experience, all that have. In the case that it's a Qwik site, what will happen is the HTML will go to the client and all that have work -- it's much less work to do and it all happens on another thread entirely. It's all free. This component, interacting and doing all kinds of stuff, this is down here getting ready to be interactive. In a React site, that's not the case. They're trying to do things to get closer to that state. But Qwik is in many ways, we had the fortune of not having an existing ecosystem to support. There's a down side, building with Qwik, it's a much newer ecosystem and we don't have as many things yet. But the good thing is we didn't have to support anything. What's the most extremely optimal way. Do we have to be extreme? When you look at Amazon or Google or Microsoft sites, these things start to really, really add up. And so, in extremely high bar, this idealistic compilation, execution resumable strategy maybe something in a tiny, tiny website is not a big deal on the first Hello World. It is a gets bigger and as things inevitably get beefy, more and more complex, a lot of code added. You probably have tickets every day asking for added code. And never get a ticket in the queue that's leading to removing code. We want to feel fast today and fast at huge scale and never have to worry about it. Be a joy to build with regardless.

JASON: Right. It's a good point. And I don't know. I like the sort of pragmatism there of just recognizing that like, sure, if we had infinite time and no outside directives, we would all write clean code all the time. But that's just not -- the reality is most become append only. How do you get an append-only to not become unmanageable. Or if it's unmanageable, only for the Devs and not for the users. That is a form of thinking that I think we fall into a trap as Devs, well, I'll have time, I'll make time. This one is going to be different. Make sure I carve out the maintenance hours with leadership. Like you can do it for a while. But it's not a -- it's not a sustainable battle. Like it's -- you got to be thinking about, all right, what happens when everybody gets lazy because they have other things to worry about. And how can we make sure that still gets results?

STEVE: Totally. And I can say, I remember I was working on my last job and I feel like everybody has at least a moment of thinking this way. I have moments, if I ran this company, we would have the cleanest code base, so maintainable, so fast because the bar was so high. Then you start your own startup and realize customers need stuff. They don't need it in a month, they literally need it right now. And like your opinion starts to change. And you realize, okay, there's a balance here. I think we're right.

JASON: One of my favorite things is when like you see somebody who is early in their clear and they go, you know, like, ah, you know, if I could just get rid of these idiots in charge and then five years down the road, I'm the idiot in charge and I realize...

STEVE: Exactly. 100%. There's a good -- oh, my god, there's this guy on TikTok. I don't know his name. One of the few tech TikTok creators I don't know. I should probably reach out to. He also does improv and has this character he does where he's like Jerry the intern. Jerry gets in the code base, I don't know what this garbage is, delete, delete, delete, push to prod. junk code, refactor. That is the codebase until the crushing reality of the world destroys you. And the people, the leadership, might not be entirely the bad guy. The bad guy is the world. Customers need things, business has to make revenue. It's just a thing. That's how the world is. And no business has the salt. In the builder journey, we worked with company, and a lot of logos think highly of. All of them think all their software is garbage, how do they do it? They're good. They're not good. Nobody is doing it right, everybody sucks and that's life in a nutshell.

JASON: So true. Okay. So, I want to make sure that we -- that we take advantage of the fact that I've got you here and I want to try a couple things that sound hard. And see how hard they actually are.

STEVE: Yeah.

JASON: So, here's my thoughts. One of the big things that Astro promises is islands architecture. Take multiple components, spread them around my site and only the pieces rehydrate. Something interesting already happened here where when I embedded a counter component from Qwik, I didn't have to add one of these client directives to get it to be interactive. So, it is already we're using resumability, not hydration. So, we're not paying that hydration toll. So, step two, then, something that's hard in Astro is what if I want my islands to talk to each other? So, what is the process if I want to my counter button also inform something over here. So, let me -- let me maybe just try out my Qwik -- my Qwik skills here. And I'm gonna say we're just gonna have like info.tsx. And what I want here is I'm gonna export const info. And that's gonna be a component.

STEVE: Yep.

JASON: And that component has a render function that's going to return for now. We'll say info goes here. And let's see if I think that might be enough to get me on the page. I'm going to come down here and say info. And then we will import info. From our -- oops. I swear I know how to type. Info. I think I -- did I screw something up? Here's our info. Goes here. So, what I -- what I want to happen is I want -- when I click this button -- maybe this just says, the button has been clicked. Whatever the count is, times.

STEVE: Totally.

JASON: Can I do that? How would I do that?

STEVE: Yeah, let me explain how you do it today. And there could be even more kind of deeper integration with Astro to add more forms in the future. Today, as long as you're okay with a parent component in Qwik, it's easy to share it across and communicate across. That's the important thing. That's why Qwik takes the approach of being a, I guess you would call it full-featured framework. Not purely meta or feature, but signals, hooks, all of that good stuff. For now, we can make a compare of components.

JASON: Okay.

STEVE: We can structure in a couple ways, but make a parent component. Trying to think. There's so many ways to do this, create a store that gets passed down, a context that gets referenced. Context could be a nice way to do it. Or actually the store as well. Start with the store. We'll take the concepts kind of one at a time. We'll define a store and do something fun with it.

JASON: We'll go with the old classic wrapper.

STEVE: Yeah, I think this will actually be a good example.

JASON: Okay. So, then do I need to do a fragment to do --

STEVE: Yeah, plain old JS.

JASON: So, put a counter. And we're gonna put in our info component. Okay. And then I'm gonna back out to my page, I guess it's index. And I'm gonna swap these out for we'll call it wrapper. And we're gonna put our wrapper here. Oh, I screwed it up. Components wrapper.

STEVE: Named differently?

JASON: Oh, that's right. Ah. So, now everything is kind of back to normal. But we've got our wrapper. And if I go back into my parent.TSX, I'm ready. What happens next?

STEVE: Yes. Why don't we do this? Why don't we do something fun, a cool property of Signals? And why don't we lift the count tracking of the counter up to the parent. Copy const counter, yeah. And go back and paste it. We'll deal with how we pass it down in a moment. Beautiful.

JASON: Okay. Then I need my use Signal... okay.

STEVE: Beautiful. And now yeah why don't we just pass count signal equals counter -- whatever you like.

JASON: Yeah. Let's do count equals counter.

STEVE: Cool. And let's go to counter. And let's -- in fact, yeah. Why don't we -- we could do something fun, actually. We could make the count button just say click me or something. And make the other component display the count. So, in this one, first thing we want to do is -- yeah. Exactly. So, why don't we define -- so we want to have a prop. Say, you can say like props, colon, and provide the types. Provide the types other way, yeah, counter, good. Or count. And then there's a signal type, exactly. In the what do you call it? The alligator brackets, number. Prop scatter, perfect. Count.

JASON: Does that just work?

STEVE: It does. Though Signal right now will assume an any time. If you just signal and pass the type argument of number, it will be number. But yeah, it should just work.

JASON: Sick.

STEVE: Yeah. And then we could go back to your other component.

JASON: Okay. It's not -- no errors at least. Like we took out the part where we're showing -- let's see... here's -- oh, wait, did I? I do have an error. Hold on. Let me reload. And maybe it was just because I -- oh, no. It doesn't like this. What does it not like?

STEVE: Count of value -- oh, I know what it is. Go back out other components. The parent we are passing this -- count, counter, hop back one more time. We could try logging props.count. Why is count not being passed through? plus... yeah, props.count. This might come on the server. If you clip click me, it should log. Or maybe not, actually. Yeah, this is actually a funny case. Let me explain one brief thing. This is an important thing to know. Just adding a console log there, because Qwik is resumable, that function body doesn't run on the client ever. So, that props will only ever run on server. This is the compiler magic that's running. So, what we should actually probably do is put the log inside of the onClick. The onClick dollar says we're only going to capture what's inside the click handler and only send that, exactly.

JASON: Okay. We got our proxy.

STEVE: Try doings props.count just in case it's a props --

JASON: Undefined.

STEVE: Props.count is undefined. And our parent, maybe log something in the parent. What did we do here? I'm sure it's the most simple thing in the whole entire world that's just escaping us. What we can do is we can add the finishing code to pass in into info as well. We could also switch to a context, whatever tiny typo we're hitting wouldn't affect us for context. But also try to flesh out this code further. Maybe learn something by hooking into info, uh-oh, we did one silly thing wrong. But going into info, follow the same pattern and log out the counts.

JASON: Okay. So, we want props. And that is going to have we'll call it the count. And that is a signal number.

STEVE: Yep.

JASON: Okay. And on this one, we want count.value -- oops. Stop that. We want props.count.value.

STEVE: Okay. Cool. See if any magic happens.

JASON: See? It immediately fails. So, something is going wrong here.

STEVE: Yeah. What's showing up or I know server. This is what I hope for, a new error. Okay, okay.

JASON: Unhandled rejection, converting circular structure to JSON. We're trying to serialize something that's not serializable, it looks like.

STEVE: Yeah.

JASON: Render to static markup, cannot read property of undefined. That's interesting.

STEVE: That's similar. It's running into this at this point as well. Jump back to your wrapper quickly maybe. See if there's a typo on how we're defining signal. Let's do this, switch over to context. This will explain it.

JASON: That makes sense.

STEVE: A new error here.

JASON: Okay.

STEVE: Okay. Same error.

JASON: Did we get any error?

STEVE: I don't know.

JASON: Let me just start this one more time. Make sure we're getting...

STEVE: Yeah, good call.

JASON: Are you doing anything? Are you frozen?

STEVE: Okay.

JASON: Not doing anything.

STEVE: Oh, we don't know why.

JASON: Now it's trying something. Did my stuff freeze?

STEVE: I don't know. Okay. It's a new tab.

JASON: But now it's just working. I think I locked it up somehow. Because that looks like it wasn't reloading.

STEVE: Oh, yeah. It's logging the -- oh. Oh. Oh, my goodness, yes. So, that's definitely what happened. For some reason, something got frozen here. And so, it was just never passing the props.count through. It wasn't getting this update. So, good news is --

JASON: So, I locked something up.

STEVE: Not crazy.

JASON: Everything is fine. We have working components.

STEVE: Yeah.

JASON: And whatever we did had nothing to do with the software. We just -- probably logged something wrong. I think I might have gotten the console caught in a loop. This is full frozen. I can't even close this tab.

STEVE: Yeah. Something. Heisenbug. When you're livestreaming, it will guarantee to fail in a way that you can never reproduce in your entire life.

JASON: Okay. Here's the other thing I was interested in.

STEVE: Yeah.

JASON: I'm gonna add just some extra crap in here that is not interactive because I want to look at what happens. Do we have a lorem? Can I just do like a lorem?

STEVE: What? Do you have an extension for that?

JASON: I think that's cool. Yeah, the extra. Yeah, okay.

STEVE: That might have been -- do you have Copilot on?

JASON: No, no, no. This is -- it's Emmett.

STEVE: That's awesome. It just comes with VSCode, I think?

JASON: I think it's on by default. I might have installed it early on. There's a few that I add every time.

STEVE: There's one funny thing you can do here. If you wanted to comment out the couple components and Signal, what you will see is no JavaScript is distributed again. So, kind of I think what you're looking for. Get rid of all the interactive stuff and you should not see the quick loader. You should not see really anything -- or maybe we still load the quick loader in Dev mode, but in production mode, those things aren't sent at all.

JASON: Let's build, let's see.

STEVE: Sure.

JASON: So, npm run build. No errors, everything is fine. Then I'm gonna npm run serve. Wait. Is that -- that's not a thing, is it? So, it's NPX serve, and then is it dist? Yeah. Okay. So, I have localhost 3000 now. If I open this up, all right. So, this is our production site.

STEVE: Yep. Do we have quick loader? Now quick loader -- that ticket is not solved yet. It's either done or coming soon. That's the expectation the customer should have. I would say it is still in beta. By v1, it would be there. That's with Qwik City and everything too.

JASON: Got it. We don't see much of anything here. It's all good. And if we look at the network size, let me turn off the cache. Let me -- let's -- you know what? Let's play even more. Let's go slow 3G.

STEVE: Oh, yeah.

JASON: And... nine and a half kilobytes of resources.

STEVE: Yeah, there should be no JavaScript downloaded. So, none of the JavaScript for the components, literally none that have. So, looks like Qwik loader is still there. Jack said you might need to run a preview build opposed to -- there might be another way to do it, but the expectation you should have by at least 1.0, run -- the thing that is working as expected.

JASON: Npm run preview? I don't know what --

STEVE: I forget the difference. This is a Vite thing, pretty sure. I've run into this with multiple Vite projects. I've never known the difference. I just know in the case of like Astro or Qwik City, I just use deployment adapters. So, if I deploy to Netlify or whatever, it just works. It just does the right things.

JASON: Cool, okay. I don't know what preview is. Turning it off and turning it back on would solve problems. Yeah. The preview is the build, I mostly understand what that means. So, we've got --

STEVE: The build command, I think in Vite projects in general, it's a common thing. Build, okay.

JASON: This is good. We're good, I'm happy. I'm in. Okay, yeah. Paulie is saying there's -- it's in the package JSON. Which obviously it just worked when I ran it.

STEVE: Yes.

JASON: Do these deployment adapters work going directly to AWS? I believe there should be Astro adapters for just about everything that you would want. If we look at the deployment... where is it?

STEVE: Yeah. And that's actually a really nice thing. One of the really nice things about the combination of Qwik and Astro. If we adapt Qwik and Astro, every feature of Astro, every feature works. Every deployment adapter, probably doesn't have as much as Astro. Whatever feature you have on here, you basically give -- if you want all the things, all the perf and all the features, this is a pretty awesome combo.

JASON: Where is the actual deployment thing? SSR adapters, maybe? Official adapters. Community maintained-adapters. All right. Here's the thing I was looking for.

STEVE: Yes.

JASON: Node, Vercel, cloud, SST, AWS --

STEVE: SST is AWS too, or SST supports AWS.

JASON: Yes, deploy your site to AWS. There's another AWS, more AWS. So, it looks like there are lots of options out here for what you can do. Astro WordPress, that's fascinating.

STEVE: Oh! What the heck?

JASON: Lots and lots of options. Let me drop the link here for anybody who wants it. Lots of good stuff there. So, all right let's dig back into -- is this my frozen one? No, this one is fine. So, let's take this, make this a little bit bigger so I can get to it. All right. We're in the preview still?

STEVE: Yes, maybe.

JASON: Okay. Let me get back into Dev mode. All right. And then I can uncomment, uncomment --

STEVE: Yes. And we'll get a little bit of JavaScript prefetched now. And it should be -- this is the cool part. In fact, let's look at the network tab, this should be fun. Dev mode is not as optimized as production mode, but see the things.

JASON: We're gonna turn off the log, disable the cache, and then run this. So, these, I think, are the Astro bits. So --

STEVE: For that preview widget, yes.

JASON: Yeah. Let me just filter out for like Astro.

STEVE: Whoa, you can type dash and a negative filter? What?

JASON: I think I learned this one from like Tim -- why am I blanking on his name? Perf Lord Tim.

STEVE: Yes, I know who you're talking about. I forgot his last name too. But yes.

JASON: Hold on, we can find this fast. Tim! Kadlec.

STEVE: Yes.

JASON: That's a Tim special. Also, this episode is dope if you're into performance, get in there.

STEVE: Yes.

JASON: Here's a question, what's the difference between Qwik City and Astro?

STEVE: Yeah. Great question. And I'll point out -- click on that JavaScript file too. We'll open in a second -- sorry, the bottom one, chonk, yada, yada, yada. Let's see if this is what I expect. We'll get back to that. Big difference between Qwik City and Astro. Think of it as you have Svelte Kit, which is sort of like the meta framework built bit Svelte team for kind of Svelte top to bottom everywhere. And then you have Astro where you can load Svelte components, use Astro as sort of the root renderer, AKA, the meta framework. In this case, Qwik City is analogous to Svelte kit, and Astro is felt -- or Astro with Qwik. It's another great starting point for the container of your application, the root HTML, the meta framework, whatever you want to call it. The thing that delivers the stuff. Or rather, you could call it this way, the structure of how you write your code, dot Astro, Houston, all your files as TSX, similar to React. Load in a first way, sort of anticipated. And you can pick your poison. I think for everybody a different combination is right. If you love Astro, you have a heavy DX for interactivity. Without the perf drawbacks. If you're die hard, left, right, everything Qwik, Qwik tattooed on your shoulder. Qwik City is maybe the way to go.

JASON: All right. I figured out what was going on.

STEVE: Cool.

JASON: And it's the best possible use case. I hope that jackhammer next door is not coming through my mic. Sorry, everybody.

STEVE: It's not. At least for me, it's not.

JASON: Check this out. Here, right? Watch the network tab when I click. Did you see that? That's cool

STEVE: Oh, yeah. And this is the file I wanted to show. So, go cool thing here is. I'm glad you pointed occupy. One is that in development mode, we will only fetch in interaction, and in prefetch, this is the thing on the show, you know what I was talking about. Go to the counter component we can look at these two things side by side. In counter.tsx. There we go. You know how I said the onClick handler, only sends the click handle, this is what we're seeing here. This is actually -- this is kind of a big secret, by the way. We talked about how we can serialize -- we were the first to serialize functions, serialize promises, serialize stuff across web worker and server client boundaries. It was new in Qwik land. And to be honest in the beginning, we didn't know if this stuff would be possible. And Manu on the team would go away for a week and come back and be like, you can! Here's how! And then you see this stuff propagate. Prove the idea and then it shows up in other frameworks, Remix, Solid. Ryan is a great engineer and reverse engineer. It can be done in Solid, and it will, if it's possible. He will make it happen. Quite an amazing cadence. But one thing that's completely unique to us, many of them are, serializing signals. But what this is, this is what serializing function closures look like. In this case, we have a function that covers certain lexical scope. The props object. What we're doing is actually generate this function at compile time that can pull out what whole use lexical scope was one of the biggest sort of unlocks to create a lot of the serialization power. The ability to pass at runtime as needed and compile all the other stuff away. So, we're still just distributing this little tiny couple lines to still execute with still all the thing use expect from a basic closure, a basic reference function, how it manipulates stuff outside. I don't know if that was so abstract it didn't even make sense. But that's the idea.

JASON: I mean, I do think that this is, you know, when you start looking into the guts of how any framework works, if you're not a hard core like JavaScript framework engineer, a lot of this stuff is gonna sound completely opaque. And that's okay.

STEVE: Yeah, what the heck is that?

JASON: The reason we use frameworks is so that we don't have to learn this stuff. If you just listened to that explanation and I have no idea what I'm talking about and it started triggering your panic that you want to learn more. If you want to be a framework engineer, learn it. If you don't want to be a framework engineer, isn't it great that Steve and Manu and Misko are building stuff like this? Frameworks exist because these are hard problems. This sort of concept of can I take a promise? If you try to console log a promise, you get a JavaScript is just like, no.

STEVE: Yeah, no. Yeah.

JASON: But if you send a promise across the server client boundary in most frameworks you would get nothing. And because of the work of -- it sounds like Manu -- you can just do it now in Qwik. And subsequently in Remix and in Solid and so on and so forth. Pretty dang cool.

STEVE: And if it's not obvious, we should take it back, what's the benefit? Why does this cool stuff matter? It's simple. Imagine this component, I'll tell you, hold on. Let me find a stat for you that most people never want to share. I will do it because I enjoy pain. Let me tell you something. We have a React component in our codebase, in the builder codebase, that will -- that loads a lot. It's very commonly used. If you use our platform, you will be using this component a lot. Jason, could you guess how many lines of code our largest React component is?

JASON: 75 line -- no, 750 lines. No, two lines.

STEVE: No, much, much larger. Definitely larger than two. I'll give you the number -- it's 13,449 lines of code. One React component. This stuff happens sometimes. It is -- I'm sorry -- it is being broken apart bit-by-bit. Every time we work on this component, we break thing office. But stuff happens in real world application developments. And so, in this case, let's imagine for a moment -- and like honestly, I -- one thing I hate -- I hate, hate, hate -- is when the authors of frameworks tell you, oh, well, you're doing it wrong. You need to make smaller components. That's great. All your doc examples are beautiful. And my code is not. That's just how it's going to be. Because we don't have time to restructure the code every time we have to append something to it. And so, the reality is, if the guidance is right, you code differently. In many cases, it's not going to happen. At least in these ways.

JASON: I do think -- yeah, I also think that something that always kind of drives me up a wall is the general approach that when somebody writes something that thing is very technically impressive and then somebody brings them a very practical reason why they had to do something different or why the thing they're doing, they're like, this isn't gonna work in my use case or whatever. And the response tends to be like you're not understanding this correctly. You need to refactor, you need to rewrite. Like this implicit expectation that like the world should shape around the brilliant idea.

STEVE: Yeah, exactly, yes.

JASON: This is why so many good ideas die in open source is because people think that the good idea will just cause everybody to drop everything and rebuild everything. And like, it's not -- we still got codebases. Our entire banking system runs on what? Cobalt?

STEVE: Cobalt! Yeah!

JASON: Because there's zero chance that anybody is gonna rewrite the 50 million lines of banking code. Because React server components have a technically superior idea. There's a much bigger reason that causes those times of codebases to get rewritten. It's not like, it is more pleasant to work with.

STEVE: Totally. And if you have ever been in involved with one of those projects, this is unmaintainable garbage, rewrite it. Over never experienced so much pain as a developer. Because those projects start great. You make 80% of the progress in a few months. And then you spend four years doing the last 20% and it never gets off the ground and it's horrible. It's horrible for everybody. It starts great and it goes downhill and you live in the pit of despair for years.

JASON: I feel like this is a -- it's a -- like another way of experience that, like, well, if we could just get rid of those idiots in charge. Well, if we could just get rid of the legacy code and get the green field, and it looks just like the old codebase. Turns out people write code for a reason.

STEVE: Exactly. The end result.

JASON: Us not wanting to deal with them doesn't mean it doesn't exist. You have to handle them, oh, I see why they did that thing the way they did it.

STEVE: Totally.

JASON: Expecting everybody did it wrong because they don't have your brain is a sure fire ticket to pain and to realizing you're not as smart as you thought you were.

STEVE: 100%. You have this mentality of well the prior code was written without respect to the codebase, and should have factored that in when delivering the feature. We actually do this in our company. A lot of our engineers talk to the customers directly and figure out the solutions. When you're face to face with a customer, if you try this, you'll probably try it once ever. If you are not gonna do that, that won't look nice in the codebase, they have no -- that does not resonate whatsoever with them. What they care about is what they're trying to use your product for. And you realize through this experience repeatedly that they are correct. Your codebase is not correct. And, you know, we try to find a balance. And in this case, like this example, this 13,000 line of code React component, if that was here in Qwik, that massive component and all we did was click on that one button, that tiny code that's there is still what executes on the client. I don't care if you wrote 13,000, that's what you see and what's downloaded. That's the beauty. In Elm, large files are a virtue. I'll be honest, there are many cases whether you ignore the performance drawbacks that most frameworks have with large files and accept -- take one extreme, SolidJS. SolidJS I've never thought about it this way, but if I think deeply, besides rehydration, there's no runtime penalty to a massive component. Everything is granular signal. You're never rerunning and re-hy-diffing. In React, at 13 ,000 license, the team would say, don't do that. It's nice when your framework says that's fine. Refactor when you need to, not when you have to.

JASON: And really anything we're doing is just us like -- we're writing abstractions over the fact that this is all gonna get unrolled into one giant file anyways when it's executed on the browser.

STEVE: Totally.

JASON: At a certain point, we're just making our lives harder, taking a little thing and moves it out. It doesn't look right. It's okay to put a function inside a function if that's the only place it gets used. It's okay. The aesthetics are not the point. Because we always said, well, code is the course of truth. Sure, code is the source of truth, but the truth is whether or not people who use the software find if valuable.

STEVE: exactly, yes.

JASON: That's it. You can write the most beautiful code in the world. If the source of truth is everybody hates your app, you're out of a job, I'm sorry. Gorgeous code doesn't pay the bills. A what pays the bill is writing code that people are using. As I'm off on a rant, we're coming close to time. Anything you want to cover on should we look at next steps for people who want to go further on their own?

STEVE: Good question. I think we covered the basics. Let's talk next steps. Even for those what found these initial steps, there's a lot more to the framework. Stores, context stores are freaking awesome. So many other things. The route loaders and the server and worker dollar. Needs its own episode, the ability to send things to the server. Do one last quick thing.

JASON: Yeah, let's do it.

STEVE: Let's go to your counter component. I'm trying to think of where we want to do this. What I would love to do is call a function on the server, or server code, from the client and show how stupidly easy this is. Maybe we could just add another but then and just do an alert of like the current date or something. And the date will actually come from the server. So, if you want to put wherever you want, if you want to add a fragment, add another button, or something else add in the wrapper. Whatever you think is easiest.

JASON: Yeah, this is easier. We'll go for time.

STEVE: Yeah.

JASON: We have got this one here. And then we're gonna have another button. Have an onClick.

STEVE: Yes.

JASON: Actually not do that yet. Just go here. Get the server date.

STEVE: Yes.

JASON: Okay. Now we've got a button to click to do it.

STEVE: Yes.

JASON: I assume I want to be in here for this.

STEVE: And now -- yes. Login would be a good idea. Good. Add onClick and remember onClick ends with a dollar in Qwik land. TypeScript is your friend. There you go. Let's say const time equals await server dollar.

JASON: Okay.

STEVE: There we go.

JASON: Let me make this async.

STEVE: Yes. And server dollar, you can import -- yeah, do you have an autoimporter doodad?

JASON: That's not what we wanted at all.

STEVE: Do we need to import from Qwik City? I don't know if it works --

JASON: It's not part of it, doesn't look like.

STEVE: Try npm installing Qwik City and importing server dollar. Yes.

JASON: Is it builder --

STEVE: Yes, add server.-- Jack can you say in the comments? Will it work in the Astro integration? If not, we can add that. If he knows it doesn't work, we don't have to take the time.

JASON: Saying use task.

STEVE: He is right, but server dollar is way cooler. Let's show what server dollar looks like. If it's not in Astro, we can be optimistic it will come in 1.0 or soon. Add a callback function to server dollar. Okay. There we go. And if it surprise works, that's super-awesome. But we'll see. Cool. We can return like date.now or something, you know? It would be really cool to return a server-specific API. Use a Node.js import or something.

JASON: What if we use -- yeah. This is fine. Let's start here. And then we're gonna return... time.

STEVE: Yeah, do that. Console log it, alert it, whatever.

JASON: Console log... okay. Saving.

STEVE: Okay. Jack is saying it won't work. There's still a chance that it does. Yes, I'm happy. Let's look at the code. Ignore the fact that this doesn't work in the Astro integration. It works in Qwik City. Jack is saying let's bring it over to the Astro integration. But what this is, if you're familiar with React server components or how any framework handles this boundary. Server land is over here in this file, client land in this file, and Qwik is about granularity. If you write something and you want -- if you have seen -- this is taking this concept of trying to make it one more step generic and work with others. If you want to call code on the server, do it anywhere, and this serialization technology identifies the dollar and every dollar can transfer over the wire, it can work forwards and backwards. Client back server. In this case, if you looked at the code that the compilation gave you it's not easy to do here, what you would see, whether you run that server dollar, it's making an HTTP call to the server. The code is only running on the server, ripped out by the compiler, executes server side only. And any time, this relates to the point we were talking about, this idea that you need to re-architect the code, you need a server side or client something, React server components, need a client, refactoring components. We know that's something people don't have time to do. And back and forth, that's the dream. Building out server first, but have client handlers, and I want to call my client again, I don't need to make this HTTP. Others do it at the module level, instead of the closure levels.

JASON: Right.

STEVE: This is unique to Qwik. I'll pause there. But yeah, that's an exciting thing. And also works with dollars. Worker dollar execute on a dollar, if this imported JS, it would only be in the server or the worker.

JASON: That's a thing to consider. Something like moment is huge. Not having to download that on the client side, that's a big win. It just lets you make more informed choices about what your code is doing. And the way the tradeoffs of like do I want to do this work on the server? Do I want to do this work on the client? And not think is this a use server or client file? Do I have to write an API endpoint and so on and so forth? I know we're almost out of time. Where else should people go if they want to learn more?

STEVE: Yeah, I would say check out -- go to Qwik.dev and search for the Astro integration. It's on our docs. I think because it's not maintained bit Astro team, it won't show up in the docs. You can go in here, search the docs for Astro. Google Qwik Astro. There you go. That's the getting started. It will walk you through, install the package, add TS config and just writing quick inside of Astro. Add magic HTML too your HTML-first framework. It's cool. I would love to see what people build. I think what we'll see off of this and I'm excited about is more I would call like rich Astro sites that fully maintain that performance. There's Qwik sites out there -- we didn't talk about visible tasks, making animations crazy fast. All things to learn separately. And bring all that to Astro, really cool stuff.

JASON: Yeah, I'm going to drop a link to the Qwik docs if you want to dig in. And take advantage of the community. A lot of people building cool stuff. I know your team is hanging out on Discord, right?

STEVE: That's correct. And a whole bunch of community members. Some our Qwik heroes, community members who are awesome, killer, contribute, answer questions. It's an amazing ecosystem.

JASON: Excellent. Yeah I know we're basically out of time here. I'm going to take this opportunity to just do another quick thank you to our sponsors, Netlify, Vets Who Code, make this episode possible. Look like I've got a bug. It's been live captioned, Amanda here from White Coat Captioning all day. And Steve, thank you for being here. One more link to your Twitter profile. And then I think I'm gonna call this one a -- I had a blast, did you have fun?

STEVE: Super fun. Appreciate it. This was awesome.

JASON: Chat, I hope you had fun. And look at the schedule, we have a lot of fun, including a special episode next week, live in studio. make sure your mark your calendars and show up for that one. I think that's. Thank you so much for hanging out.

STEVE: Love it, thanks, everybody!