Speaker 1: Hello, everybody, Welcome to another exciting ever episode of javascripts Jabber.
Speaker 1: I am Steve Edwards, the host with the face for
Speaker 1: radio as you can see in the voice for being
Speaker 1: a mine, but I'm still your host with me Today
Speaker 1: on the panel, we have mister Dan Shapiro coming live
Speaker 1: from tell Abev, Israel. How you doing, Dan, But well.
Speaker 2: You know it's hot here as surprise, surprise.
Speaker 1: Yeah, we're going back and forth here. It was pretty
Speaker 1: warm last couple weeks and now it's a little cool
Speaker 1: and cloudy and it's gonna be pretty mellow, so pretty nice.
Speaker 1: As we're getting to the end of August, I'm going
Speaker 1: to let Dan introduce our special returning guests, So go for.
Speaker 3: It, Dan.
Speaker 2: Yeah. So I'm really excited about today's guests. We have
Speaker 2: two of them, which means it's double the pleasure, and
Speaker 2: they are both a living testament to the fact that
Speaker 2: you don't need to work at Google or at Meta
Speaker 2: or at some other fang in order to make a
Speaker 2: huge impact on web development. So we have Ryan Carneato
Speaker 2: and we have Tanner Lindsley. Hi, guys, want to introduce
Speaker 2: yourselves in case somebody somehow doesn't know who you.
Speaker 1: Are Oh sorry, I hit the plauser. Okay, I got
Speaker 1: to get that crowd to control themselves. Lots of fun.
Speaker 4: Yeah, I'm Brian Carneado, probably most known for creating solid
Speaker 4: Jazz and my work on Signals CEO of Signals and Tanner.
Speaker 3: I'm the tan Stack guy.
Speaker 2: And for those who don't happen to know, Tanstack is
Speaker 2: also where react query came from.
Speaker 3: Now tanstack query right, React Query I even I still
Speaker 3: call it that, which is fine.
Speaker 2: And also lots of other great tools. You've recently introduced
Speaker 2: a couple.
Speaker 3: Yeah, we we have just a couple. We're working on
Speaker 3: a new framework inspired by solid Start called tan sax Start.
Speaker 3: We have a router. We have a new library called pacer,
Speaker 3: which is about like debound throttling, ate leming stuff. We
Speaker 3: have the controversial name tan stack dB, which is a
Speaker 3: reactive client store. I mean it's a database, but it's
Speaker 3: only for like the client on the front end. It's
Speaker 3: pretty sweet, guys, except that it isn't right. Yeah, it's
Speaker 3: it's an awesome library. That's all you need to know. Uh.
Speaker 3: And we've got like table and form as well virtual
Speaker 3: h We've got a couple. We're even working on something
Speaker 3: called tan Sak dev tools right now, which is oh
Speaker 3: yeah about that.
Speaker 2: We will have to bring either you or somebody else
Speaker 2: on the team on to talk about that when you're
Speaker 2: different than you guys already h and I have to
Speaker 2: also mention create tense ten stack start or whatever Jack
Speaker 2: these days.
Speaker 3: Whatever we're going gonna call it, and it might even
Speaker 3: just be called create tan Stacking like that.
Speaker 2: For those of you don't know that is. We actually
Speaker 2: had Jack Harrington on the show to talk about it.
Speaker 2: It's an awesome replacement for create react at least.
Speaker 3: Yeah, we have some fun plans for it.
Speaker 1: So it's Tanstack Ranger. I'm looking at a last.
Speaker 3: Ranger is kind of a throwback to my old open
Speaker 3: source days. It's it's I needed a library to do
Speaker 3: multi range inputs, so like sliders with multiple handles. I
Speaker 3: made a headless version of it. I called it Ranger,
Speaker 3: which is kind of fun.
Speaker 1: See I'm thinking like Park Ranger and uh, you know
Speaker 1: Jellystone Park and I remember that.
Speaker 3: Yeah, it's probably it's it's the most niche library that
Speaker 3: we have, which it's cool. I still use it every
Speaker 3: now and then.
Speaker 2: And one more thing about you, Tanner, correct me if
Speaker 2: I'm wrong, but you're now you've transitioned to work full
Speaker 2: time on your open source staf.
Speaker 3: Right, yeah, about a year and a half ago.
Speaker 2: That is awesome. So basically you're the guy not making
Speaker 2: a living, so the rest of us can.
Speaker 3: I mean as of nine months ago, I'm making a
Speaker 3: good living now.
Speaker 1: So yeah, so what is your business model for that?
Speaker 3: Then? Well, it's it's different than most others, I think,
Speaker 3: so I abhor VC around oss. I've done venture capital
Speaker 3: for my last company, and I've also bootstrapped plenty of things.
Speaker 3: I didn't want to do that for tanse Dec. So
Speaker 3: Tensex basically run like a media company right now, as
Speaker 3: like a business side of things, so marketing, advertising, partnership,
Speaker 3: brand deals and the like. And that's how tanse Dec
Speaker 3: is making money and paying both me and also now
Speaker 3: contributing a lot towards contributors as well, and that's just
Speaker 3: going to grow over time hopefully.
Speaker 2: Does that mean running ads within your website, within your
Speaker 2: products or something else?
Speaker 3: Yeah, So tan stack dot com is the revenue generator
Speaker 3: and the libraries are just guests on the tan stack
Speaker 3: dot com show every day.
Speaker 2: That's interesting. Yeah, I'm really happy that it's working for you.
Speaker 3: Yeah, it's working so far, so we'll we'll see. I
Speaker 3: don't know if it's scalable or not, but it works
Speaker 3: for me, and I think that's that's good enough for now.
Speaker 2: And how about you, Ryan, how are things with you?
Speaker 1: Pretty good?
Speaker 4: I've been at Century now for almost a year, so okay, Yeah,
Speaker 4: like this week coming up marks a year Century So
Speaker 4: they've been great, been able to obviously support my U,
Speaker 4: R and D. I've been doing a lot this year
Speaker 4: because I've been working a lot of new areas kind
Speaker 4: of for upcoming releases of Solid and and they've been
Speaker 4: supporting lots of other ways. I've been getting closer with
Speaker 4: the syntax FM guys.
Speaker 1: I was gonna ask if you worked with them.
Speaker 4: Yeah, So we've been talking about how to up my
Speaker 4: game on video content and different kinds of media stuff
Speaker 4: like better promotion.
Speaker 2: So I'm guessing they told you you need to make
Speaker 2: longer videos.
Speaker 1: Yeah, that's funny, No, they were.
Speaker 4: Everyone's been really stoked on those shorter videos that I've
Speaker 4: been doing recently. They said they were like a little crunched,
Speaker 4: could do some more production value, but generally speaking, I
Speaker 4: usually stream for like five hours ish you know, maybe
Speaker 4: every other Friday or so. And I started in the
Speaker 4: last couple of months doing like ten minute videos, and
Speaker 4: for me, doing ten minute videos very hard.
Speaker 1: It's condensed.
Speaker 4: It's like because I picked really deep topics, but I
Speaker 4: just needed a place to point people too. When people
Speaker 4: are like, you know, signals, blah blah blah blah blah,
Speaker 4: you know, like complains. You know, I'm a React developer.
Speaker 4: I don't get why they important. It's just like, okay, well,
Speaker 4: can I make an FAQ basically as a video. And
Speaker 4: that's sort of what I've been trying to do. Find
Speaker 4: content that's sure enough that people will not like bulk
Speaker 4: looking at the whole length of the video, but then
Speaker 4: still get a lot of unique content in there. It's
Speaker 4: difficult because my expertise is I said, very very deep.
Speaker 4: You don't really find content like I do in most
Speaker 4: video content. Like you guys sometimes get really deep on
Speaker 4: your podcast, which is why I love this podcast. But
Speaker 4: a lot of video content isn't the same sort of thing.
Speaker 4: You know, it's either like how do you do this?
Speaker 4: Or it's like the most beginner intro level of stuff.
Speaker 4: So being able to ask the whys, I think is
Speaker 4: really really important and like looking at the design stuff.
Speaker 4: So I'm going to try and bridge that gap, you know,
Speaker 4: maybe pick smaller topics that I can actually talk about,
Speaker 4: you know, in seven to ten minutes.
Speaker 2: So you kind of remind me of that. I think
Speaker 2: it's Mark Twain who said I didn't have the time
Speaker 2: to write your long letters short letters, so I wrote
Speaker 2: you a long one. So yeah, it's exactly much much
Speaker 2: more challenging to create short and concise and to the
Speaker 2: point content.
Speaker 4: Yeah, especially if you spend all your time like like
Speaker 4: really like like just kind of exploring ideas and stuff,
Speaker 4: you know, and taking stuff which way to actually come
Speaker 4: up to a consolidated messages way more work. I can
Speaker 4: stream for five hours, but then I'm like mostly done.
Speaker 4: The video is going to take me at least two
Speaker 4: or three days.
Speaker 2: You know, that's for sure. Well, let's put it this way.
Speaker 2: I think that once you get the hang of it,
Speaker 2: you'll be able to do it much more effectively. Maybe
Speaker 2: you should also consult about it with THEO.
Speaker 3: Yeah.
Speaker 4: Yeah, he's been waiting for me to like level up that.
Speaker 4: He was like, yeah, I just keep on doing what
Speaker 4: you're doing, but when it's time come see me you know,
Speaker 4: like better gear, better stuff, you know.
Speaker 1: So yeah, yeah, I did one video for for you
Speaker 1: Mastery a couple of years ago, And the amount of
Speaker 1: work it takes to get to just to put together
Speaker 1: simple videos is crazy. Whether it's recording, I would assume
Speaker 1: that once you get your setup in place, you know,
Speaker 1: your your software and your different artwork components and your
Speaker 1: speakers and all that stuff, and you know what you're doing,
Speaker 1: it's probably a lot quicker. But that's that's got to
Speaker 1: be a learning curve just in getting set up to
Speaker 1: do video production like that.
Speaker 4: Yeah, and I like editing stuff in I'm a big
Speaker 4: fan of fireship videos and even my articles are like that.
Speaker 4: I've always done a lot of meme pictures and like
Speaker 4: like images to back up what I'm saying, Yes, can
Speaker 4: I keep it going? Even my conference talks are like
Speaker 4: that too. So I find the video editing actuallyising a
Speaker 4: long time because I need to find just the perfect
Speaker 4: clip or the perfect like image to kind of overlay
Speaker 4: the different parts. So like it's like it's almost on
Speaker 4: like a twenty second cadence, so like it's you know,
Speaker 4: twenty minute video.
Speaker 1: You know, that's a lot of clips.
Speaker 3: Well, just let AI do it for you.
Speaker 1: Well, you know, I have the same struggle with always
Speaker 1: trying to find a perfect dad joke to publish on
Speaker 1: a daily basis and to throw in here and there
Speaker 1: so I can somewhat they all perfect.
Speaker 2: Stage, they're all perfect.
Speaker 1: Oh boy, I got to tell you some stories about
Speaker 1: how they're not always, but that's a topic for another time.
Speaker 2: Yeah, I think we need to finally get to the
Speaker 2: to the crux to the main issue.
Speaker 1: We had a topic for today, any topic that we're
Speaker 1: here to discuss, gotcha.
Speaker 2: So again, I'll give a brief background. A while back,
Speaker 2: I had this idea of le let's go even further back.
Speaker 2: I started noticing a certain pattern that was occurring in
Speaker 2: a lot of frameworks, especially as they were becoming meta frameworks,
Speaker 2: and that's kind of and I termed it to come
Speaker 2: back of RPC, and we'll talk about what RPC is
Speaker 2: and why it's making this comeback now. But when I
Speaker 2: noticed that, it occurred to me that this could be
Speaker 2: an interesting topic for a conference talk, which I created
Speaker 2: and already gave once at JS Heroes in Romania. But
Speaker 2: I reached out to a lot of my friends, people
Speaker 2: like Ryan, like Tanner, like Rich Harris and others, and
Speaker 2: started in Jack Harrington, whom we mentioned, and started talking
Speaker 2: with them about this whole thing, and I realized that
Speaker 2: a lot of them had very different viewpoints about what
Speaker 2: our PC is, how it should or should not be used,
Speaker 2: why it's interesting or maybe not. And what this ended
Speaker 2: up is this conversation here. I basically asked both Ryan
Speaker 2: and Tanner if they'd like to come on the show
Speaker 2: and talk about this, so, you know, take it away, guys.
Speaker 4: Yeah, I start because I feel like this starts with
Speaker 4: stuff that I was doing. But to be fair, this
Speaker 4: is stuff that Tenor definitely relates to right off the bat,
Speaker 4: because the first thing you hit when you're writing a
Speaker 4: meta framework, like the most obvious thing is actually meta
Speaker 4: frameworks are centered around routing, right and the router And
Speaker 4: I know this has nothing to do with RPC right
Speaker 4: off the bat, but like.
Speaker 2: Maybe we should define our PC before we dive into it.
Speaker 4: Yeah, okay, sure, A remote procedure call basically this idea
Speaker 4: that you can in different environments call a function from
Speaker 4: the other environment.
Speaker 1: Because I thought it was really popular comedy for a moment,
Speaker 1: glad read.
Speaker 2: I like to use a slightly different definition the way
Speaker 2: that I like to define it is basically as a
Speaker 2: method for invoking a service or obtaining data from another process,
Speaker 2: even on another computer across the network, using a function
Speaker 2: call paradigm. Are you okay with this definition? Yes, So
Speaker 2: it's basically it looks like a function call. It feels
Speaker 2: like a function call. You. It's as easy to use
Speaker 2: as a natural to use as a function call, but
Speaker 2: instead of just actually being a function call, it translates
Speaker 2: to an operation across the net.
Speaker 1: Yeah.
Speaker 4: The funniest thing is, like my first introduction to rpcs
Speaker 4: didn't feel as easy or natural to use as function calls.
Speaker 1: I was using a.
Speaker 4: Like soap in Microsoft stuff back in the early two thousands,
Speaker 4: And if anyone's us that it's like all XML based
Speaker 4: and they call they get categorized under RPC. But that
Speaker 4: like in my head when someone says RPC to me, traditionally,
Speaker 4: that's what I thought of. I thought of these like
Speaker 4: XML end points from like Microsoft Server from like two
Speaker 4: thousand and two.
Speaker 1: Memories.
Speaker 2: Yeah, I'm a bit of a history buff. I'm a
Speaker 2: bit of a history buff. So it's interesting because it
Speaker 2: was that period in time where RPC was effectively dying
Speaker 2: so our PC was really RPC. The term was coined
Speaker 2: in the eighties. It became really popular in the nineties
Speaker 2: with the native platforms for it like Corba or Dcom
Speaker 2: from Microsoft, and then the Web happened, which kind of
Speaker 2: killed it. Soap was an attempt to somehow continue to
Speaker 2: do RPC despite the Web, and we can talk about
Speaker 2: why the web killed RPC for a while at least,
Speaker 2: and now it's making a comeback in a much more
Speaker 2: natural way, which is in a lot of ways very
Speaker 2: reminiscent of how it was in the nineties, but compatible
Speaker 2: with the modern technologies that we use nowadays.
Speaker 4: Right, Yeah, yeah, I mean that sounds about right, Like
Speaker 4: no one was touching RPC after that early mid two
Speaker 4: thousands period until maybe like twenty twenty.
Speaker 1: Is they're like in the web technology, But.
Speaker 4: I mean yes, obviously, when we start designing these surver
Speaker 4: rendered meta frameworks where we actually have the server and
Speaker 4: the client being developed in the same place, you start
Speaker 4: going like, well, if I control both sides, why not
Speaker 4: like make that pipe easier.
Speaker 1: But I mean that was the motivation.
Speaker 4: The thing for me personally when I started looking at
Speaker 4: this stuff was I wasn't I was aware of this
Speaker 4: the soap stuff you know and that, But I was
Speaker 4: just trying to like I was looking at other meta frameworks,
Speaker 4: was this is the beginning of all start Like twenty
Speaker 4: twenty one is actually before I even really sold at
Speaker 4: one point zero, And I was like looking at other
Speaker 4: meta frameworks a bit, and I was looking like next
Speaker 4: JS and and mostly and like you know sapper from
Speaker 4: and like next and they all had these like API
Speaker 4: end points, like like where you'd like do this file
Speaker 4: based routing system with apien points. And the thing that
Speaker 4: was weird for me is I used to be a
Speaker 4: real guy for a bit, so like you would define
Speaker 4: like like in the file system, you'd define I guess
Speaker 4: not a file system was an auto madeive.
Speaker 1: Filesism, but whatever.
Speaker 4: You you skelton out these like models essentially and API
Speaker 4: n points and they would describe the whole collection of
Speaker 4: the whole model of things, and the filesystem approached a
Speaker 4: lot of these APIs had taken was kind of it
Speaker 4: felt weird to me because you'd have like a different
Speaker 4: file for like the general like groups versus like group
Speaker 4: I D like you didn't put all the crowd commands
Speaker 4: together like it would like separate based on the URL path,
Speaker 4: not based on the conceptual model, if that makes any sense,
Speaker 4: Like instead of being talking about groups as a single thing,
Speaker 4: you would have like groups and groups slash.
Speaker 1: I d like it's a funny thing.
Speaker 4: But I was looking at these API shapes and I
Speaker 4: was like, this is such a hassle to like every
Speaker 4: time I do this to build out these files.
Speaker 1: I saw Remix. I think this was for me.
Speaker 4: They did their big reveal in spring twenty twenty one,
Speaker 4: and I know this, and when I saw their loaders
Speaker 4: and actions and the way that they doubled it up
Speaker 4: on the API side, I'm like, this is kind of nice.
Speaker 4: It's like turned into a single approach, because what was
Speaker 4: kind of awkward was that people would build their app
Speaker 4: in one folder and then they'd build their API and
Speaker 4: another folder, and it was getting kind of clunky. You
Speaker 4: do everything twice, kind of connecting it up. And they
Speaker 4: were like, no, you can just kind of stick it
Speaker 4: all in the same place, follow the same kind of pattern.
Speaker 4: The challenge I had Remix is because I've been working
Speaker 4: on routing for a while and nested routing and with
Speaker 4: you know, parallel data fetching and all these things. Is
Speaker 4: the remix loader basically said that this part of the
Speaker 4: UL loads this data, and that wasn't granular enough for me.
Speaker 4: I was working a solid gazz which is based on singles.
Speaker 4: So as you can imagine, there's multiple different data sources.
Speaker 4: You want them to update independently, right, you want to
Speaker 4: be to refresh them independently. You only want to update
Speaker 4: certain parts of the page. Treating the whole page like
Speaker 4: it was like a single data flow was not particularly
Speaker 4: nice for me. So I was like, okay, can I
Speaker 4: take my kind of like route loaders, which are they're
Speaker 4: not really loaders, they're isomorphic. They run on both sides,
Speaker 4: these kind of nested rout kind of areas where you
Speaker 4: can fetch data and instead of you know, hitting API
Speaker 4: calls like we used to, instead of using one single loader,
Speaker 4: can we make it more ergonomic to define individual pieces
Speaker 4: of data you can fetch. And I was looking when
Speaker 4: I was doing the client side, and I'm like, I
Speaker 4: love this. You know I can put you know, you know,
Speaker 4: solid query. This is like a ten I rack in
Speaker 4: the conversation for a second, but like I can put
Speaker 4: like my different data fetching things inside this loading and
Speaker 4: I can manage them separately. If I'm on this page,
Speaker 4: can I can grab users and their posts and have
Speaker 4: multiple things and call them and invalidate them separately. And
Speaker 4: I'm like, this is a great pattern. It works on
Speaker 4: the server, works on the client. The only problem is
Speaker 4: you have to call these extra API in points. So
Speaker 4: I started working on a solution, which was, what if
Speaker 4: I could use the file system in a nicer way,
Speaker 4: like better than the API in points, where instead of
Speaker 4: being quite as bulky and like having these URLs, I
Speaker 4: could use like a proxy or something like where you
Speaker 4: could maybe make some types for an object, and based
Speaker 4: on what path you go through the object, it would
Speaker 4: construct the URL on the client and then know what
Speaker 4: endpoint to hit on the server. And I kind of
Speaker 4: put this together and I call them actions after remixes actions.
Speaker 4: And the difference is they weren't really exactly actions, or
Speaker 4: they were both actions and loaders. You could basically hit
Speaker 4: these URLs both on data fetching and on mutation, and
Speaker 4: you could call them They're just like autogeneratid APIs. And
Speaker 4: I remember I put that out around April. I made
Speaker 4: some demos around April twenty twenty one, but then Solid
Speaker 4: one point zero needed to get released, and I put
Speaker 4: it aside, and I basically was like showing people and
Speaker 4: talk like how cool this was going to be, but
Speaker 4: you know, people just like, oh, yeah, yeah, whatever, Ryan,
Speaker 4: and and then and then it was almost a year later.
Speaker 2: It could be fair half of us don't know, don't
Speaker 2: often don't understand what you're talking about, so.
Speaker 1: That that's that's perfectly fair. But some people did.
Speaker 4: And I was talking to someone in December or like
Speaker 4: around Christmas time, and they're like, oh, isn't that what
Speaker 4: blitz JS is. I'm like, Blitz, isn't that next JSS thing?
Speaker 4: And I look at it, and sure enough, that is
Speaker 4: actually what blitz was. I basically independently also came up
Speaker 4: something similar to what Blitz was.
Speaker 2: Which is blitz what is it?
Speaker 3: It was?
Speaker 4: It was it was kind of like a meta framework
Speaker 4: on top of Next. I thought it was like Redwood,
Speaker 4: like it was one of those more opinionated meta frameworks
Speaker 4: on top of Next. But eventually they just became like
Speaker 4: a Next plug in and kind of downscaled it because
Speaker 4: but originally it was like a separate product, like you
Speaker 4: when installed Next, you install Blitz, and it was it
Speaker 4: was a React meta frame essentially. But it's cool feature
Speaker 4: was that it had these basically kind of generated API
Speaker 4: functions in the same kind of way that I was describing,
Speaker 4: where you could just kind of put these basically API
Speaker 4: call things in a file folder structure and then call
Speaker 4: them directly without like the fetch and the ceremony around
Speaker 4: like that. You could just call them basically it's functions
Speaker 4: via like a proxy like I was talking about, because
Speaker 4: the cool thing that the proxy approaches you can have
Speaker 4: the proxy return whatever you want, so it just wraps
Speaker 4: the details of the fetch away from you. So it
Speaker 4: is kind of the beginning of this RPC thing because
Speaker 4: you still have the API point where you have a
Speaker 4: file system running telling you like basically where these functions are.
Speaker 4: But then you could use the path on the proxy
Speaker 4: like get users dot get or like whatever to actually
Speaker 4: construct the URL and obscure the fetching. And I know
Speaker 4: this is kind of crazy history, but you know, like
Speaker 4: beyond where we ended up, but it was important for
Speaker 4: me to get there because when I went back to
Speaker 4: solid Start and after playing with this again, by this
Speaker 4: time I had met Nikhil Sarah, who was kind of
Speaker 4: responsible for a lot of stuff in solid ecosystem. He
Speaker 4: did a lot of the heavy lifting on the original
Speaker 4: salt Start release, and he also created Vinci, which we
Speaker 4: used to actually base salts Start and tasks Start initially.
Speaker 4: And he was like, man, veat is amazing. We don't
Speaker 4: need to use all this proxy stuff. We can just
Speaker 4: use a compiler and split these things out, like even
Speaker 4: in the middle of the files, like it doesn't matter.
Speaker 4: He started doing crazy stuff where he was analyzing like
Speaker 4: things further down the tree and hoisting them automatically and
Speaker 4: doing like all this stuff. And I'm like, this is crazy.
Speaker 4: I can't even wrap my head around what's happening. But
Speaker 4: he's like, look, as long as we have a symbol,
Speaker 4: like some way of it's saying like this is a
Speaker 4: is a function call, we don't need to use the
Speaker 4: file system. We can just go like this is a
Speaker 4: server function or whatever, and we passed the function to it,
Speaker 4: and now that function will always be called on the server.
Speaker 2: This is where you guys invented bling. I think you
Speaker 2: called it back then, right.
Speaker 1: Yes, almost.
Speaker 4: Bling would come very soon soon when we brought Tanner in.
Speaker 4: On Tanner, what this I actually presented our original version
Speaker 4: like this at vcomp the first b COMP back in
Speaker 4: September twenty twenty two, and that's when people were like, oh,
Speaker 4: this is actually kind of cool, you know, because it
Speaker 4: had types like when you start having functions and you
Speaker 4: can write them like functions where you can just import
Speaker 4: them the types match up.
Speaker 2: Yeah, And I'll get to that because it brings an
Speaker 2: interesting point from my perspective about why RPC is so
Speaker 2: attractive and what changed, because we talked about how the
Speaker 2: web kind of killed RPC, so it's interesting to talk
Speaker 2: about how RPC was able to make this kind of comeback.
Speaker 2: But before we go there, Tanner, I really want to
Speaker 2: bring you into the conversation finally.
Speaker 4: So I mean, it is basically almost at that point
Speaker 4: because Tanner is really into types. So after I demoed
Speaker 4: this stuff and the type stuff, what came out in
Speaker 4: the world that we realized that, like, what's cool, You
Speaker 4: can literally write the function as is. You don't you
Speaker 4: know a lot of type things that graft you or whatever.
Speaker 4: You'd have to write these schemas were this the types
Speaker 4: inherent off the functions simply from importing them automatical transferred.
Speaker 4: You didn't have to do anything you wouldn't be doing
Speaker 4: usually for typing. So once once we uh basically realized that,
Speaker 4: uh you know, uh, I started kind of publishing it
Speaker 4: out there and talking to other people. I was like, man,
Speaker 4: I still couldn't get over how magical it felt. And
Speaker 4: then I looked over it Quick and I was like,
Speaker 4: maybe we just need a better symbol. So I was like,
Speaker 4: let's add a dollar sign on it. And I actually
Speaker 4: told the Quick guys like they didn't know I did this,
Speaker 4: and I was like, I was tarting to manual In
Speaker 4: at a conference in that fall, and I was like, man,
Speaker 4: I think Quick could add this. I honestly stole your
Speaker 4: guys's dollar sign just because it's like a good indicator.
Speaker 1: And I'm like, we can just like you. It's just
Speaker 1: the reverse of what Quick does.
Speaker 4: Quick it was really good at pulling out these little
Speaker 4: pieces on the client. This is like pulling out these
Speaker 4: little pieces for the server. It's just like inverse Quick
Speaker 4: and they added it to their meta framework within a
Speaker 4: month after that conversation, like they were just like, yeah,
Speaker 4: we already have everything here, and they did it almost immediately.
Speaker 4: And as said, that's when tanner Gun involved around that point. Oh,
Speaker 4: actually it might have been even a little bit later,
Speaker 4: is around when next Uh and React they were like
Speaker 4: saw this stuff too, and they're like, oh, and they
Speaker 4: came up with like use server, but it was specific
Speaker 4: for their for their rpcs, for their server function communication.
Speaker 2: Their Initially they actually had it in the fine names
Speaker 2: if you recall the dot server dot ts and dot
Speaker 2: client dot t s.
Speaker 3: That was that was the catalyst for me right there.
Speaker 4: Yeah, I mean there there was there was like a
Speaker 4: subtle different like put it because technically server functions start
Speaker 4: on the server and there's like a naming convention where
Speaker 4: they're like, okay, these are server, these are client, and
Speaker 4: these are shared. But then like it's a different scenario
Speaker 4: because the server stuff can be done all in a
Speaker 4: single pass, like in a single go. They when they
Speaker 4: originally came up with that, that was to denote server functions,
Speaker 4: but not sorry, server components, not necessarily server functions, right or.
Speaker 2: Like they didn't have an aultation. Use client came as
Speaker 2: an alternative to dot server and dot client my fine names.
Speaker 2: They didn't have anything for you server, which came around.
Speaker 4: Later, right exactly, So they started proposing this stuff and
Speaker 4: I mean, yeah, Tenner can jump in at this point,
Speaker 4: but I think he saw what they were doing and
Speaker 4: it was just like, what the hell is this?
Speaker 3: I didn't I mean, I thought it was neat. I
Speaker 3: was more interested in, like what they were doing under
Speaker 3: the hood with like the compilation, what was actually happening
Speaker 3: to the build and transforming that the AST and whatnot.
Speaker 3: But I did not really like the approach to like
Speaker 3: use client use server at least for like RPC. I
Speaker 3: looked at it and I was excited about like, oh,
Speaker 3: I can just throw this token in there and all
Speaker 3: of a sudden creat an RPC, and like that part's cool.
Speaker 3: But then all these questions started bubbling up about like, Okay,
Speaker 3: clearly they don't believe that like configuring and RPC is
Speaker 3: as simple as a one string Like that's ridiculous.
Speaker 2: So I want to touch that briefly again to give
Speaker 2: a little bit of context to our listeners. So we
Speaker 2: talked about the fact that RPC is about invoking a
Speaker 2: function somewhere else as if it's a local fun a
Speaker 2: local function, and specifically in the context of full stack frameworks,
Speaker 2: it's basically invoking a server side function from client side
Speaker 2: code using the function called paradigm. So it looks and
Speaker 2: feels like a function. Now, in order to be able
Speaker 2: to do that, you kind of need to have, from
Speaker 2: my perspective, three things. First of all, you need to
Speaker 2: have type safety. Otherwise what's the point and going back
Speaker 2: to your or to your point, Ryan ab when disappeared,
Speaker 2: Obviously it only came into being after Typescript really went mainstream,
Speaker 2: because before Typescript, the whole typing thing was irrelevant. And
Speaker 2: the other thing that you need is to be able
Speaker 2: to simulate blocking you call to the remote function. You
Speaker 2: want to have it to feel like a local function,
Speaker 2: which means you don't get the execution back until that
Speaker 2: remote function finishes and provides a value. And we only
Speaker 2: got that after we got a sinkle weight.
Speaker 4: Basically, yeah, yeah, I mean, I'm native support of promise is,
Speaker 4: but more specific to this conversation, when framework started having
Speaker 4: tools to do what they think, which secularly you know.
Speaker 2: And which brings me back to the final point is ideally,
Speaker 2: not necessarily, but ideally you also want what you mentioned
Speaker 2: about vat, the ability to effectively instrument the code basically
Speaker 2: write something that looks like a function call, identify that
Speaker 2: this code is going to be running on the client,
Speaker 2: this code is going to be running on the server
Speaker 2: and generate all the magic code that makes this thing work. Basically,
Speaker 2: it's it's a stub and on the client and on
Speaker 2: the server that handles the whole networking layer underneath that
Speaker 2: function call.
Speaker 3: Now I'm mentioning that you don't.
Speaker 2: Necessarily have to have it because types trpc does without it,
Speaker 2: which makes it less magical and and also less fun. Potentially,
Speaker 2: going back to I want to give Tanner, I basically
Speaker 2: stole the mic from Tanner. So Tanner, you said that
Speaker 2: you looked at that the fact that they introduced this
Speaker 2: kind of magic string and all of a sudden it
Speaker 2: kind of worked, and you had thoughts about.
Speaker 3: That, Yeah, because like details matter eventually, details matter a lot.
Speaker 3: Like I think what you see is like you you
Speaker 3: write use server and a function, and that's that's really magical,
Speaker 3: and it's it's magical both in a sense of like
Speaker 3: it's doing a lot under the hood for you, but
Speaker 3: it's also a magical experience for most like basic operations
Speaker 3: or basic use cases. It's so simple, it's deceptively simple
Speaker 3: that it's like, oh, that's all it takes, right, and
Speaker 3: you just you put U server in there, But there's
Speaker 3: so many details that bubble up that you cannot get
Speaker 3: away from the fact that this is happening over the network.
Speaker 3: There are implementation details there that matter sometimes and there
Speaker 3: for example, yeah, caching protocol methods, header's authentication. There's there's
Speaker 3: like edge case flexibility that needs to be inherently in
Speaker 3: the system to allow you to do things that you
Speaker 3: maybe don't do ninety percent of the time, but you
Speaker 3: will need to do. One of the basic ones was
Speaker 3: you server defaults to a post sorry not be defaults.
Speaker 3: It is a post request in like next jays and
Speaker 3: React reacts to kind of spec right.
Speaker 2: You also don't have any control, like you said, either
Speaker 2: over the end point all the protocol.
Speaker 3: No or headers or anything like that. You're you can
Speaker 3: kind of get it some of the implementation, but only
Speaker 3: at like a global place. But if you wanted to
Speaker 3: customize any of that other stuff, you can't really do that,
Speaker 3: and you have to break out of the system entirely.
Speaker 3: And I didn't like that because immediately I was like, well,
Speaker 3: I want to use this with reac query, and that's
Speaker 3: great for cashing, But wouldn't it be great if if
Speaker 3: the browser could actually just cash this get request that
Speaker 3: I'm making, it's totally capable of doing that. And then
Speaker 3: there's questions of well, how is that URL formulated in
Speaker 3: a way that's going to be stable for the browser
Speaker 3: to cash, And there's lots of questions that came up
Speaker 3: for me around that, and I just knew at one
Speaker 3: point we're going to need to like ninety percent of
Speaker 3: the time same experience as just use server. Just create
Speaker 3: a function, give it some kind of a symbol, a
Speaker 3: dollar sign or something that would make it easy for
Speaker 3: a bulk of the use cases, and then have at
Speaker 3: least the ability or the option to expand and and
Speaker 3: make that configuration advanced. I just don't understand when people
Speaker 3: create APIs that cannot be ripped away easily or like
Speaker 3: dug into easily. I don't understand it. And these directives
Speaker 3: of use server or use cash or whatever are like
Speaker 3: the biggest offenders of that principle for me.
Speaker 4: So it's it's funny because as you get guys may
Speaker 4: not know actually I started with server functions, solid uses
Speaker 4: use server today because compatibility with react or like conceptually
Speaker 4: there yes, wrapper functions are.
Speaker 3: By the way, like intense sex start you can write
Speaker 3: use server ye and you'll get the same experience.
Speaker 4: But it's yeah, like rapper functions are as tenders that
Speaker 4: are almost necessary for configuration. And that's like positively at
Speaker 4: least is that because this configuration comes from the client,
Speaker 4: wrapping is definitely something you can do, Like you can
Speaker 4: compose these kind of pieces on top of server functions
Speaker 4: because the server parts on the server, the use server,
Speaker 4: the server offs and represents the split between the like
Speaker 4: this goes on server, this goes in the client.
Speaker 3: So it's basically.
Speaker 2: One of the things that kind of enabled I'll give
Speaker 2: you in a second just mentioning that one of the
Speaker 2: things that enabled this whole thing is like you mentioned
Speaker 2: when we talked about VAT, is that smart bundler that's
Speaker 2: that's analyzing the code in any event, sees it and
Speaker 2: then knows to generate different code for the server and
Speaker 2: different code for the client from the same source code. Right,
Speaker 2: That's the sweet magic.
Speaker 4: We should talk about beat here for a little bit more,
Speaker 4: because the thing is at this point Tenner and I
Speaker 4: are talking the keel and we're like every framework could
Speaker 4: use this.
Speaker 1: Why just use this.
Speaker 4: Only in solid Why have you know, you know, quick
Speaker 4: make their own version. Why have next make their own version?
Speaker 4: And Antenner was like, okay, let's let's like just make
Speaker 4: a generic plugin for this, right, So that's where Blain
Speaker 4: came about. When it was like Kennedy, he picked it
Speaker 4: up and he was like, let's let's make this generic.
Speaker 1: The thing that is.
Speaker 4: Bling didn't quite survive in the same form because what
Speaker 4: we realized was Blain was basically like a was it
Speaker 4: a Babel plug in. It was basically a transform. It
Speaker 4: basically transformed a code without bundler awareness, which does work
Speaker 4: a lot in this in the simple cases, but it
Speaker 4: doesn't work in the more complicate cases, mainly that if
Speaker 4: how do you register these endpoints?
Speaker 3: Right?
Speaker 4: Real apps have code splitting, so you might not load
Speaker 4: all the code in the client, or you might not
Speaker 4: load all the code on the server. And what ended
Speaker 4: up happening with the just doing a compiler approach was
Speaker 4: that we would sometimes navigate to a page on the
Speaker 4: client that hadn't been navigated to on the server, which
Speaker 4: means the endpoint wouldn't be registered yet.
Speaker 3: It didn't exist yet, so it didn't even occur to me.
Speaker 4: So like basically, this generic approach, it wasn't enough just
Speaker 4: to stop a babble and a compiler. We needed something
Speaker 4: that would actually go through the whole module graph and
Speaker 4: oist out these things, and it had to be bundler level.
Speaker 4: So this is that's that's actually why Blaine died. In
Speaker 4: a sense, Tannor has remade.
Speaker 3: It was repurposed, right. Actually, what's funny is like a
Speaker 3: lot of the code from Bling made it into VINI.
Speaker 1: Yes, yeah, yeah, I mean at the VAT.
Speaker 3: Level, right, And then what's funny is then eventually we
Speaker 3: ripped it back out.
Speaker 4: Right, and the other part of Vinci ended up going
Speaker 4: directly to VAT when VEAT adopted the environment's API, because
Speaker 4: we're building these things and the VAT team had, I
Speaker 4: guess their own problem with deployment, like the solved with
Speaker 4: the deployment environments, like you have cloud Flare, which is
Speaker 4: different than Netlify and Bursell, and you could build for
Speaker 4: like different outputs like workers versus pages and all these
Speaker 4: things people wanted to have, like you know and client preserved.
Speaker 4: They want to have these different environments. Vinci actually did
Speaker 4: that because VAT didn't. It was hard to manage these
Speaker 4: kind of things, and.
Speaker 1: That's why we created it. And in the end.
Speaker 4: As I said, VINCI now has kind of been dismantled,
Speaker 4: but the environment API now exists in Beat very similar
Speaker 4: seeing usage to how we used to do it in VINCI,
Speaker 4: and we still have the server functions plug in in
Speaker 4: the form of what what's under Tanstak that's now used
Speaker 4: both by Soul, certain tank Tack start Tanner.
Speaker 2: You're very polite. You raise your hand.
Speaker 3: Oh, I was. I was gonna say. One of your
Speaker 3: questions went unanswered, and I wanted to answer it before
Speaker 3: we went too deep into compiler land. And it was
Speaker 3: about type safety, and that is a massive part of
Speaker 3: another massive reason of why it all went this direction
Speaker 3: for me, and it's it's also because type safety. A
Speaker 3: lot of people think, well, it's just defining, you know,
Speaker 3: the types that this function can take on. But in
Speaker 3: reality you're not just writing typescript types and expecting those
Speaker 3: to get extracted away into validation. Because that's another that's
Speaker 3: another part where like just sending, just treating it like
Speaker 3: a function still is not totally safe. I mean, I
Speaker 3: like it that we that we want to get to
Speaker 3: this functional zintax of just calling the function and having
Speaker 3: it be awaited, and it's it's really nice, but under
Speaker 3: the hood, it's these details you need to be aware
Speaker 3: of them, and one of them is that you're going
Speaker 3: across the network. So type safety without validation is a
Speaker 3: complete lie. You can validate anytime you go across a
Speaker 3: serialization boundary, even into the URL or local storage, anywhere
Speaker 3: you have to validate or it's just a lie.
Speaker 2: So yeah, it's really I'll let you continue in a second.
Speaker 2: I'm just clarifying again the terminology. It's that distinction between
Speaker 2: dev time type safety, maybe even build time type safety
Speaker 2: and run time type safety.
Speaker 3: Static type checking versus actually run time validation.
Speaker 2: And exactly in Typescript very intentionally does not do any
Speaker 2: run type type checking. So the fact that you're building
Speaker 2: on that you're leveraging Typescript types is really cool. You
Speaker 2: get completion, you get squiggly lines during development, but at
Speaker 2: runtime over the network, anything might be sent, especially if
Speaker 2: it's like a public point.
Speaker 3: Right and you know, you might feel like you're just
Speaker 3: writing a function and it might feel secure, But no
Speaker 3: one in their right mind would create a rest endpoint
Speaker 3: straight into their back end and not validate the inputs
Speaker 3: that they're getting from people. And so the same way here,
Speaker 3: like you you want to be validating the inputs going
Speaker 3: across these functions in a special way that isn't just oh,
Speaker 3: it's a typescript type. So I'm just going to trust
Speaker 3: that I'm the only one calling it and that my
Speaker 3: system is the only one that has access to this
Speaker 3: public RPC endpoint. Like all this stuff is easily reverse
Speaker 3: engineered and abused.
Speaker 2: It's even worse because when you're doing posts like straight
Speaker 2: on RESTful APIs, you know that you know that you're
Speaker 2: going to have to check the types. You're going to
Speaker 2: have to effectively cast the types.
Speaker 3: Yeah, because when you're losing the types perfectly going into
Speaker 3: this exactly on transform mechanism and pulling them back out
Speaker 3: on the server side, you know you you have to
Speaker 3: do the same thing coming back out. Otherwise it's like, well,
Speaker 3: this is just a blob of whatever, you know.
Speaker 2: I think, yeah, and with and and I forget if
Speaker 2: it was Rich Harris or Lirental who literally showed me
Speaker 2: an example I think where they used typescript and instead
Speaker 2: of a certain value pass vr PC being like saying
Speaker 2: just a string, they said it needs to be like
Speaker 2: the quote unquote quote child or quote teacher and nothing
Speaker 2: at run time validates that some other string is not
Speaker 2: passed in so you so typescript literally lies to you
Speaker 2: in this case if you're not careful.
Speaker 3: Which typescript needs to come after that, which is it
Speaker 3: needs to be a byproduct. And that's exactly why we
Speaker 3: we did two things. One we adopted Standard Schema. I mean,
Speaker 3: we helped kind of push standard Schema into reality. It
Speaker 3: was created by all the brilliant people that build these
Speaker 3: validation libraries like yeah, like like ZOD and type, archetype
Speaker 3: and stuff like that. But but we needed validation, so
Speaker 3: we did validation first. And what's interesting is with with
Speaker 3: our APIs to create our PCs, we do not allow you.
Speaker 3: I mean, you can do anything you want, but I mean,
Speaker 3: the the happy path of our API is that you
Speaker 3: do not get types in your server functions in your
Speaker 3: rpcs unless you provide validation that gives you those types.
Speaker 3: If you try, like, we don't have a generic API
Speaker 3: to just cast the the types coming back with just
Speaker 3: typescript because we we think it's unsafe. So that is
Speaker 3: the happy path. You have to use a ZOD schema
Speaker 3: or an archetypes or whatever to to get that validation
Speaker 3: and turn it into types.
Speaker 1: It's funny how full circle this is going.
Speaker 4: And this happens to me a lot, I have to admit,
Speaker 4: because of the lookliness. Like the reason that RPC died
Speaker 4: in the first place was because it was clunky to
Speaker 4: in my opinion, there's many reasons, but part of it
Speaker 4: was that it was clunky to define stuff. And like
Speaker 4: it's a challenge like graft Tuel going away because you
Speaker 4: know you're defining these like.
Speaker 1: To define the types.
Speaker 4: So people get these Jason APIs and then and the
Speaker 4: people did the Jason on APIs and they like, you know,
Speaker 4: manage themselves, but it wasn't schema basis through the code
Speaker 4: at run time.
Speaker 1: And then like but there's a lots of holes there.
Speaker 4: So now people have reinforced on types, which obviously again
Speaker 4: gets us back to RPC. But like, it's funny the
Speaker 4: framework author's side, like let's say like deeper on the
Speaker 4: UI frame side, Like say, guys like myself or people
Speaker 4: working on React, we're looking at this and we're like, okay, McKenna,
Speaker 4: this works nice. It's ergonomic as thing. People can build
Speaker 4: stuff on top of it if they need to. But
Speaker 4: I have the pieces I need to do what I
Speaker 4: need to mechanically, and it's and it's smooth, but then
Speaker 4: we we get to a point where we add back
Speaker 4: our own friction because of like best practices.
Speaker 1: So that's what it was. Kind of kind of like the.
Speaker 2: Nice things on the web, that's truism.
Speaker 4: So yeah, it's kind of it's kind of interesting because
Speaker 4: because like, yeah, I mean, I love, you know, the
Speaker 4: standard schema, A big fan of Valabot and all that
Speaker 4: kind of stuff, But it's but it was, it's like
Speaker 4: one of those things where like the people building UI
Speaker 4: frameworks usually maybe the meta frameworks can, but the UI
Speaker 4: frameworks can't. Can't generally won't push those kind of things
Speaker 4: on you because they're like they're not they're not in
Speaker 4: our range of to be enforced because people will have
Speaker 4: different opinions, things will change over.
Speaker 3: Time, too much opinion coming from right exactly.
Speaker 1: So it's like we.
Speaker 3: Being a meta framework, then you get to enforce a
Speaker 3: little bit more those opinions.
Speaker 4: Yeah, it's just tricky because meta frameworks have a shorter
Speaker 4: shouldn't theory have a shorter shelf life?
Speaker 1: Because of that, Like.
Speaker 4: This was always the struggle I had on was work
Speaker 4: on all start because I like didn't want to make
Speaker 4: meta framework. I just wanted to make a like a
Speaker 4: create React app that work on the servers. This kind
Speaker 4: of kind of tension is interesting for the science space.
Speaker 4: There was something I wanted to say. You said, there's
Speaker 4: three things you need for rpcs to come back.
Speaker 2: Yeah, I mentioned, I'll said again, maybe it'll jog your memory. Basically,
Speaker 2: it was a type for the underlying system to be
Speaker 2: typed or type safe that at least a development time.
Speaker 2: Otherwise there's no point. So you probably wouldn't do RPC
Speaker 2: if you've just got JavaScript, a weight so that you
Speaker 2: can quote unquote block until that remote function finishes, and
Speaker 2: optionally the compiler slash bundler so that you can automatically
Speaker 2: general rate the stub code to do to translate that
Speaker 2: function called into you know, do the serializations, send the
Speaker 2: message across the wire, do the de serialization on the
Speaker 2: other side and back again?
Speaker 4: Right yeah, yeah, And you just mentioned it twice because
Speaker 4: I said at the beginning I wasn't trying to build RPC.
Speaker 4: I think the final piece that access cemented it for
Speaker 4: me was the serialization part. Because we don't communicate in
Speaker 4: Jason anymore with these you don't.
Speaker 1: No, no, no, I think.
Speaker 2: You do, don't you the call over the wire is
Speaker 2: it Jason or is it something else for server functions?
Speaker 3: Yeah, yes, by default, yes it's Jason. Yeah.
Speaker 4: See didn't And this is one of the attractive to
Speaker 4: be though. Yeah, this is one of the attractive things
Speaker 4: for us time because you can trouble sides. So this
Speaker 4: is like react love this, we love this, framework has
Speaker 4: love this. This is this is where you can go
Speaker 4: back and to what framework wanted is. At the exact
Speaker 4: same time I was working on this, we were updating
Speaker 4: our approach to doing streaming SSR and stuff, and we
Speaker 4: were making it faster and more efficient. Like every framework
Speaker 4: has their own serializer. Some are publicly available like solid seabo,
Speaker 4: Marco's warp nine devalue from spelp, and we were.
Speaker 2: Going to need to give a little bit more context
Speaker 2: I think. Okay, so to some of our listeners about
Speaker 2: why it is that you need this sort of civilization
Speaker 2: for SSR.
Speaker 3: I think that'll be really useful.
Speaker 1: Yeah, okay, sorry.
Speaker 4: Basically you're sending HTML, which you're like, okay, that's great,
Speaker 4: but the problem is now you have something ASIC so
Speaker 4: you can send the HTML in chunks. Let's say, so
Speaker 4: you're sending you know yes or it's streaming is basically
Speaker 4: the problem. You want to be able to not only
Speaker 4: send the HTML markup, but you want to be able
Speaker 4: to send the data across and if you wait for
Speaker 4: it all to finish, then just send the Jason and
Speaker 4: the HTML. Then you show the whole page at the end.
Speaker 4: But if you can, if you can send different types
Speaker 4: of serialization values, it's possible to send pieces of the
Speaker 4: app in parts and then for the client to go, oh,
Speaker 4: you serialize a promise, for example, and the client go okay,
Speaker 4: I know this data is coming. That's the most fundamental
Speaker 4: way of doing it, where we basically describe a promise
Speaker 4: over the wire. So when you know it starts hydrating
Speaker 4: part of the page and the whole page hasn't loaded
Speaker 4: in from the server, we can go okay, treat it
Speaker 4: like a client side promise, and we know that what
Speaker 4: will end up happening is actually on the same website page.
Speaker 4: We'll actually stream that Jason later, but then we'll when
Speaker 4: it comes in, we'll fulfill the promise on the client.
Speaker 2: So again, just to clarify the need, if I understand correctly,
Speaker 2: correct me if I'm wrong. It's it's your HTML intrinsic
Speaker 2: is intrinsically streaming. So the HTML protocol, unlike JavaScript, essentially
Speaker 2: you can stream it and it will just execute. The
Speaker 2: problem I think is the order of things is the
Speaker 2: fact that you that HTML streams top to bottom, whereas
Speaker 2: you want to be able to stream things and inject
Speaker 2: them in the middle of things that have already arrived. Right,
Speaker 2: and Tanner has raised his hand again, so interrupt.
Speaker 3: I just want to punctuate that and say that it's
Speaker 3: it's about order. It's about componentization of these calls to
Speaker 3: to say I have something that needs this amount of data,
Speaker 3: you know, and you can have multiples of those in
Speaker 3: whatever order you want, And inside of those responses you
Speaker 3: can have immediate, immediately returned partial parts of those responses
Speaker 3: and have some of them be delayed. So it's almost
Speaker 3: like you get the same experience inside of HTML where
Speaker 3: you can give the important stuff really quickly and delay
Speaker 3: the other stuff. You get that same capability within each
Speaker 3: request response life cycle.
Speaker 2: You can see it in this just just to say that.
Speaker 2: The joke that I like to say is that the
Speaker 2: big difference between old websites and modern websites is that
Speaker 2: we've replaced the single large spinner with a lot of
Speaker 2: small spinners.
Speaker 4: Yeah, we've been trying to solve that.
Speaker 3: I mean.
Speaker 4: The challenge is you can see in the shape that
Speaker 4: ht amount it self, it's x amount or you know,
Speaker 4: it's a markup language. So these things are naturally nested.
Speaker 4: You see it in your components. You have components and
Speaker 4: components and components and components. So like doing it top
Speaker 4: the bottom doesn't even work because the outer component hasn't closed,
Speaker 4: you know what I mean, like these envelopes. So what
Speaker 4: ends up happening is the trick to the h mell.
Speaker 4: Actually isn't that difficult mechanically because you can put it
Speaker 4: on the end in something invisible like a template, and
Speaker 4: have JavaScript move it back into place as it loads.
Speaker 4: The hard part is that is the data. If you
Speaker 4: actually want to wake up parts of that page before
Speaker 4: it all loads, you need to tell you need like
Speaker 4: a placeholder for the data. Essentially, you need to be like, look,
Speaker 4: this data will be coming or you know.
Speaker 3: And that's a promise and that's a problem or a substream.
Speaker 4: Right, So we started serializing well, I mean, and then
Speaker 4: there's different types of data right, like data objects, you know,
Speaker 4: and different things. So like even stuff like TRPC has
Speaker 4: like advanced like super JSON or like advanced data types
Speaker 4: you know. And but for us promises, we're the key
Speaker 4: for and we realized that we could bring that serialization
Speaker 4: not just in our original SSR, but use it in
Speaker 4: our server functions, so we could serialize anything, you know, HTML, elements, promises, whatever.
Speaker 4: And this meant that because both sides, RPC let both
Speaker 4: sides understand and this is in a sense like how
Speaker 4: server components work and React because they can go we
Speaker 4: have our special jsx on format and we can communicate
Speaker 4: both sides, and now we can communicate react components of
Speaker 4: the wire. As I said, our needs are a little
Speaker 4: bit simpler with like promises and streams, but it works
Speaker 4: out kind of similar. We it lets us build on
Speaker 4: really powerful capabilities on this because you can say, return
Speaker 4: some data with a promise encoded in it, and then
Speaker 4: like have the data come back in chunks.
Speaker 3: You can make an.
Speaker 4: ACYNC iterable and basically return the stream so the server
Speaker 4: can just keep on yielding data into your server function.
Speaker 4: And you write it literally as like an ACE generator function.
Speaker 4: So you write it as a like an acing function,
Speaker 4: and it'll our generator word yields and will literally be
Speaker 4: yielding from server to client. So there's a lot of
Speaker 4: really cool mechanics here.
Speaker 2: Do you support that in? I know that Quick supports that.
Speaker 2: I know that, or RBC supports that. Do you guys
Speaker 2: also support that that the ability to stream a response
Speaker 2: from ann RBC?
Speaker 4: Yeah, Salades, Yeah, it's in. It's in, Sarah Belle. I
Speaker 4: don't know if someone Start handles it the best in
Speaker 4: all cases, but the core technology support to it.
Speaker 3: So I guess side uh side quest here is we
Speaker 3: we and we started out building our own serializer I
Speaker 3: did for tansex Start that was had. It was a
Speaker 3: little bit lighter than something like sarahvel Or or the
Speaker 3: big giant serializer that that can do like re ex
Speaker 3: server components and stuff. And there's also super Jason there.
Speaker 3: There's even one that the remix team built right for
Speaker 3: react about.
Speaker 2: Somebody on the chat called it a tool boards.
Speaker 3: Cha Jason, Right, Yeah, there's there's a couple of these,
Speaker 3: and and I wrote a simple one that would kind
Speaker 3: of get to m v P for tansex Start Alpha.
Speaker 3: And even even the simple one could serialized promises and
Speaker 3: serialized streams. But then we we realized that we want
Speaker 3: to do more complex stuff. We've decided to adopt Sarahvell.
Speaker 3: I think I told you that, Ryan, right, okay for you.
Speaker 3: We so we have one that works for tansax start,
Speaker 3: but we're adopting Sarall because is beyond just being able
Speaker 3: to stream this stuff. Sarahville has some very unique So.
Speaker 2: What is Serville I think I missed explanation.
Speaker 4: It's it's the serializer used by SOLODJS use both in
Speaker 4: our server rendering and in our server functions. I was
Speaker 4: built by Alexis Monselek core team members sologs and yeah.
Speaker 2: It's basically serializes stuff over the wire and then de
Speaker 2: serialize it. But it's not exactly Jason. It's something else,
Speaker 2: like like React doesn't use Jason either. In case people
Speaker 2: don't know.
Speaker 3: For their.
Speaker 2: Responses from server from server components, you.
Speaker 3: See a lot of them that have like it's it's
Speaker 3: like a superset of Jason that they then encode and
Speaker 3: decode special characters, special things.
Speaker 2: Look for at the very least, you won't command lines
Speaker 2: separate the Jason in order to be able to send
Speaker 2: multiple messages and not be kind of stuck on on
Speaker 2: not closing the bracket or something.
Speaker 3: Is I think Saravel is very unique and really cool
Speaker 3: because Saravel does not Servell uses javascripts essentially to stream
Speaker 3: like to serialize all of this. Saravel uses JavaScript and
Speaker 3: streams it and executes it over the wire, and it
Speaker 3: is it's incredible to watch it work. Because even beyond that,
Speaker 3: I mean super JC yeah, a little bit. Yes, I
Speaker 3: wouldn't want to call it that.
Speaker 1: But yeah, I mean there is a bit of that.
Speaker 4: And in some cases where the security isn't concerned, he's
Speaker 4: he's been looking at alternate serialization formats so that you
Speaker 4: don't have the evil aspect of it. But yeah, it is,
Speaker 4: it is, there is there's.
Speaker 3: Great power comes great responsibility.
Speaker 4: But I mean the power is incredible because this is
Speaker 4: this is what enables future facing patterns. We've never had
Speaker 4: things like single page apps be able to easily do
Speaker 4: basically picture. You know, people familiar with React query where
Speaker 4: you can like do a mutation and invalidate like a
Speaker 4: couple of queries. What if you can do the mutation
Speaker 4: so send it to the server and have the server
Speaker 4: figure out what the invalidate and then while it's still there.
Speaker 4: Start fetching the data, that data on the server and
Speaker 4: send it back, you know, like return right away from
Speaker 4: your mutation, but then have it streaming back the data
Speaker 4: for like the next page you're going to visit right.
Speaker 4: If you have the knowledge of say like a router,
Speaker 4: and you have this capability of serialization, you can do
Speaker 4: like single flight mutations and stuff.
Speaker 1: Crap is gonna restart because of not.
Speaker 3: Just single mutations, but stream Yeah, for a minute or so,
Speaker 3: I'll be back. It looks like, but you'll yeah, it's
Speaker 3: not that it's single flight mutations doesn't been around forever,
Speaker 3: but I mean that's how the web worked anyway. But
Speaker 3: single flight mutations that are streamed, I think that's the
Speaker 3: most important part of it. It's like as you get
Speaker 3: the response, as you get the requests on the server,
Speaker 3: and you start processing things that need to change, you
Speaker 3: don't again, don't need to wait to know all of
Speaker 3: the changes that are going to happen to send them
Speaker 3: back to the client. You can start processing them and
Speaker 3: shipping them as you find them to the client. That
Speaker 3: that is incredible, so that you know you're in Validation
Speaker 3: from the server can essentially be streamed in as soon
Speaker 3: as you know about it to the client in the
Speaker 3: same request.
Speaker 2: The funny thing, though, is that that kind of goes
Speaker 2: beyond RPC. That's more in the territory of SSR, isn't it.
Speaker 3: No, Because we're still just talking about individual requests an
Speaker 3: RPC for instance, to say, you know, I want to
Speaker 3: go the base query maybe and then or say I
Speaker 3: want to update a user. I want to update a
Speaker 3: user capability. Right, I'm adding a capability to a user,
Speaker 3: and you you go to add that capability on the
Speaker 3: server side, You'll you'll receive that mutation, You'll you'll create
Speaker 3: that mutation, and then you're probably going to have a
Speaker 3: bunch of other things that need to be invalidated for
Speaker 3: the user or refresh or streams to the user that
Speaker 3: are going to be new. With that new capability, they'll
Speaker 3: gain access to new items, new things, new collection types
Speaker 3: inside of their application, and some of those items might
Speaker 3: take longer for you to fetch on the server and
Speaker 3: give to them than others, So out of the gate,
Speaker 3: you'll want to ship them a new user object that'll
Speaker 3: be really fast, So you ship that down in the
Speaker 3: same response, you push that down, and then you're still
Speaker 3: working on maybe maybe their team data or their work
Speaker 3: based data, and then as you get those, you ship
Speaker 3: those down as well, and so you can start in
Speaker 3: the same request of just a mutation, the response can contain,
Speaker 3: you know, immediate and streamed data. It's really interesting.
Speaker 2: First of all, you're turning on a lot of light
Speaker 2: bulbs for me, so thank you for that, and you're
Speaker 2: raising and it's interesting because what I'm thinking. I'm old
Speaker 2: enough to remember the original RPC implementations back in the
Speaker 2: nineties and one of the main problems with them was
Speaker 2: the fact that they were built as being synchronous type operations,
Speaker 2: and because the assumption was that it is kind of
Speaker 2: like a function and function calls usually are cheap, so
Speaker 2: you can make one function call for the fast stuff
Speaker 2: and another function called for the for the slow stuff,
Speaker 2: or get the call back or stuff like that, and
Speaker 2: they did I didn't really accommodate for that scenario that
Speaker 2: you're describing, where I'm requesting multiple data items and they
Speaker 2: are available at different at different times, and that I
Speaker 2: can create this kind of a sophisticated staggered response that
Speaker 2: data arrives as soon as it's available, and I don't
Speaker 2: need to make multiple calls in order to get all
Speaker 2: this data. Yeah, I'm giving them mic back to you.
Speaker 3: I think that it even goes He takes that even further.
Speaker 3: Is yes, it works for data that you request you
Speaker 3: may know about, but it also works for data that
Speaker 3: maybe you don't want to know about but needs to
Speaker 3: be sent. Is it leaves room now for this hidden
Speaker 3: layer of meta data, of meta actions or meta code
Speaker 3: that could happen with a request response. So, for example,
Speaker 3: the developer experience that I would want as a developer
Speaker 3: when I say update this user capability, I just want
Speaker 3: to update that user capability. I don't want to I
Speaker 3: don't want to have to be responsible for receiving and
Speaker 3: acting on all of this extra data coming back to
Speaker 3: me though. I just want to trust that it's going
Speaker 3: to work. And so naturally, what do a lot of
Speaker 3: people would say is that say, well, I'm going to
Speaker 3: update this user with a new capability, and then they
Speaker 3: get it back, and what do they expect. They expect
Speaker 3: the response to be a user and the new version
Speaker 3: of the user that has the updated capability. What they're
Speaker 3: not going to expect is to have a bunch of
Speaker 3: other random, you know, data invalidation payloads that they now
Speaker 3: have to handle. So what's nice about something like Sarah
Speaker 3: Bell is that it's it's not just you know, this
Speaker 3: super set of Jason or whatever, but it's the ability
Speaker 3: for even frameworks or middlewares or things in the middle
Speaker 3: of that operation more code can just be sent down
Speaker 3: to the client to execute that the response doesn't even
Speaker 3: need to handle or know about. So it leaves a
Speaker 3: lot of room for optimizations and frameworks to get into
Speaker 3: this request response life cycle, but still keep the developer
Speaker 3: developer experience really lean, not.
Speaker 2: Meaning it means, but a little bit scary because if
Speaker 2: I'm understanding correctly what you're saying is, let's say I
Speaker 2: want to get the new user an updated user object
Speaker 2: from the server. So I do an RPC call, I
Speaker 2: get back the new user, and I do with it
Speaker 2: whatever I do with it. But it turns out that
Speaker 2: it also realized that some group that the user belongs
Speaker 2: to updated, so it sends that down as well. I
Speaker 2: don't handle it because I don't expect it, so I
Speaker 2: didn't even write the code to handle it, but it
Speaker 2: also sent the code that will handle it for me.
Speaker 2: If I understand correctly, what you're kind.
Speaker 3: Of it depends. It depends. A lot of this gets
Speaker 3: into how you use such a tool, right, Yes, you
Speaker 3: could stream down the code that handles it as well,
Speaker 3: but more than likely that kind of code would live
Speaker 3: on the client. It would live on the client side.
Speaker 3: To say, we are orchestrating this metadata layer right as
Speaker 3: the client. We know that we're going to want this
Speaker 3: extra metadata to invalidate.
Speaker 2: So it's a callback that I attached that one, or
Speaker 2: middleware that I attach that gets invoked with the extra
Speaker 2: data that happened to arrive on because of some other
Speaker 2: call that caused it to be sent.
Speaker 3: And we're talking about middleware that can span the client
Speaker 3: and the server just like a server function. Right, it's
Speaker 3: middleware that can compose together inside of this system that's
Speaker 3: extracting into client and server and creating. It's RPC middleware
Speaker 3: essentially what.
Speaker 2: It is, correct, I'm trying to think of an actual
Speaker 2: valid scenario and you tell me if it kind of matches.
Speaker 2: So I know that a lot of times as secure
Speaker 2: systems have this concept of a refresh token. So if
Speaker 2: your access token in validates, you have a refresh stoken
Speaker 2: that generates a new access token for you, and that
Speaker 2: happens behind the scenes. You don't need to be aware
Speaker 2: of this whole thing or this whole mechanism going on.
Speaker 2: So is it something kind of like that.
Speaker 3: I don't know if I would use this for that.
Speaker 2: I mean you could, No, I'm just thinking about the
Speaker 2: scenario where you're making a function call for a but
Speaker 2: that triggers also other stuff to take place in the
Speaker 2: system that you may not necessarily be aware of.
Speaker 3: Yeah. I think what we're mostly talking about here is optimizations, right,
Speaker 3: kind of like the example that Ryan brought up is
Speaker 3: like you send off pre crashing. Yeah, you send off
Speaker 3: a request with a mutation and the intent is known
Speaker 3: that you're going to be at this destination next. Instead
Speaker 3: of waiting for all of this to to settle, the
Speaker 3: dust to settle before you go request the assets for
Speaker 3: your next destination, you can do all of this in
Speaker 3: one request. You can send all of the assets that
Speaker 3: are going to be requested anyway.
Speaker 1: Yeah, it's it's kind of interesting.
Speaker 2: Kind of resource sense in a sense.
Speaker 3: Yeah.
Speaker 1: What I found kind of interesting about this resource.
Speaker 3: Pushing resource pushing.
Speaker 4: Yeah, when I when I was working on the solution,
Speaker 4: was the kind of that realization is that people are
Speaker 4: already writing their code mostly isomorphically, which means that like
Speaker 4: they're already creating these patterns. So like running the say
Speaker 4: the routeloaders again on the server and a mutation and
Speaker 4: then expecting the code to be basically the same on
Speaker 4: the client because it is the same code it's source
Speaker 4: code basically gives you this ability. So like what was
Speaker 4: kind of cool is yeah, the kind of optimization look
Speaker 4: you can go in because if you're in a nested route,
Speaker 4: if you're familiar with nest to routing, maybe the top
Speaker 4: section doesn't change, only the like the two sections underneath
Speaker 4: swap on this navigation, so you're like you're staying on
Speaker 4: the same main page and then you go to the
Speaker 4: next page. Well, if that data from the top main
Speaker 4: page isn't being updated, then you don't have to fetch
Speaker 4: it again on the server loaders. Like basically we were
Speaker 4: able to use the same sort of knowledge of what
Speaker 4: route changes and what data is already available based on
Speaker 4: what things it would fetch when it navigates to those pages,
Speaker 4: to the point that we basically go, Okay, this is
Speaker 4: already there and the client don't need the updated and
Speaker 4: it hasn't explicitly invalidated. This is already there, this is new,
Speaker 4: this isn't just on this page, this has been updated.
Speaker 4: And then fetch those things and put them on that request.
Speaker 4: But the client are the server responds right away. So
Speaker 4: the server goes, okay, we're going to redract to this
Speaker 4: next page, and the client goes, okay, I'm going to
Speaker 4: go to this next page. So the client goes to
Speaker 4: that next page. But because those promise stubs are there,
Speaker 4: when it goes to load the data, it goes, oh, no,
Speaker 4: promise stub right here, it's already in the cash. I'm
Speaker 4: going to use this promise instead of fetching it again
Speaker 4: for the stuff that's new. So it's it's kind of
Speaker 4: it's weird how you can kind of like do this
Speaker 4: kind of predictively, but in the end, what you end
Speaker 4: up with, which is my favorite part about this, is
Speaker 4: you're actually leveraging your knowledge of the client side cash
Speaker 4: on the server here, so you actually don't need cashing
Speaker 4: on the server in this mechanism. Like you could still
Speaker 4: optimize it with like a rettis or something, but we
Speaker 4: never went through that whole Next DS use cash dilemma
Speaker 4: or cash stup because when you do server functions, you
Speaker 4: re render the whole page. It's kind of like remix.
Speaker 4: It's like that loader bit. You know the whole route sections.
Speaker 4: So when you hit a you have five data points, well,
Speaker 4: guess what, you are fetching all five data points.
Speaker 1: There's no way for you to separate those apart.
Speaker 4: Which means that if you don't want to refetch all
Speaker 4: five data points every single time, you are going to
Speaker 4: cash them on the server. This approach you'll let you
Speaker 4: basically use the knowledge of the route and the knowledge
Speaker 4: of the invalidation from the mutation to actually only fetch
Speaker 4: what's needed, so server cashes aren't necessary. It feels like
Speaker 4: a single page app word. You know, the cache is
Speaker 4: on the client, but it's actually doing this all in
Speaker 4: a single.
Speaker 2: So again, let me see if I'm getting this, because
Speaker 2: to an extent, it's kind of incidental to the fact
Speaker 2: that it's RPC. It's basically the fact that you're controlling
Speaker 2: both sides and the protocol that lets you do a
Speaker 2: lot of magic. The fact that it's RPC, like I said,
Speaker 2: it's almost incidental. It might have been some other mechanism.
Speaker 3: But what you're.
Speaker 2: Saying is this, I'm triggering an operation to receive data.
Speaker 2: I know that this operation will likely trigger redirection or
Speaker 2: transition to another page. I can prefetch or push more accurately.
Speaker 2: I can like you said tenor I use the wrong analogy,
Speaker 2: because it's not client instigated, its server instigated. The server
Speaker 2: side knows that I'm likely going to be needing that
Speaker 2: additional data. I can send it down, hold it somewhere
Speaker 2: in the client side so that when I actually needed
Speaker 2: it's already there.
Speaker 3: Basically, and that becomes even more powerful as you stream,
Speaker 3: because we could do this before with single flight mutation.
Speaker 3: As you send it, and if you spend enough time
Speaker 3: on the server, you can gather up all of the
Speaker 3: data and finally send it all back and then allow
Speaker 3: the user to navigate. But streaming allows you to respond immediately,
Speaker 3: but tick off those requests server side and then stream
Speaker 3: them down to the user and utilize utilize that connection
Speaker 3: that's already open.
Speaker 4: It's because the frameworks support a signatively. Things like suspense
Speaker 4: basically will trigger and treat your cached promise or your
Speaker 4: pre pushed promise, and a new promise would fetch identically.
Speaker 4: So in these kind of scenarios, you actually get further ahead.
Speaker 4: You can start rendering the next page before that data
Speaker 4: has arrived.
Speaker 2: And the fact that we're componentized kind of necessitates this
Speaker 2: whole thing because otherwise one of the big problems with
Speaker 2: components is that in capsulation, if you're following through on
Speaker 2: it often leads to waterfalls. So the fact and react
Speaker 2: query it back of the day at the time was
Speaker 2: so great in this regard because you fetched from one
Speaker 2: component and then it got reused the data in other
Speaker 2: components without you needing to like break in capsulation be
Speaker 2: very iplicit about it. It was totally implicit. So now
Speaker 2: you're kind of taking it to the next level in
Speaker 2: a sense this and this.
Speaker 3: Opens up new can of worms. I don't know how
Speaker 3: deeply you want to get into that, but components have
Speaker 3: you on again component level data fetching it. I'm still
Speaker 3: I think it's still really the way to go. And
Speaker 3: then thinking about thinking about the the optimizations that need
Speaker 3: to be made at the routing level and the SEO
Speaker 3: level and the page levels to get rid of waterfalls,
Speaker 3: and that you know these are optimizations and making those
Speaker 3: optimizations as easy as we can is really important, and
Speaker 3: we can do that through API design with our routing.
Speaker 3: We could do it through compilers like relay, but they
Speaker 3: are optimizations. I think at that point, I like this,
Speaker 3: I like everything that we've talked about is really.
Speaker 2: I interrupt you again because I have to say that
Speaker 2: one of the biggest downfalls of RP see back in
Speaker 2: the old days, and one that I was so concerned
Speaker 2: with that I actually at the end of my presentation
Speaker 2: or RPC, I talk about the potential downsides of RPC,
Speaker 2: and it's one of the items listed there is the
Speaker 2: fact that RPC kind of encourages waterfalls because you make
Speaker 2: a function call to get some data, and then you
Speaker 2: make another function call to get some more data, and
Speaker 2: another function called to get some more data, so you
Speaker 2: end up with chatty protocols and waterfalls because the implicit
Speaker 2: assumption is that it works like functions and functions are cheap.
Speaker 2: And what you're saying is that you're overcoming it by
Speaker 2: being smart realizing you know, you can still write it
Speaker 2: like it is if it's a waterfall, but you've triggered
Speaker 2: the requests, the generation of the code that's going to
Speaker 2: be requested in the third request, in the first request,
Speaker 2: and already be even scented down, so by the time
Speaker 2: I get to that third RPC call, it's returning immediately
Speaker 2: because all the data is already there.
Speaker 3: Yeah, we're getting into what I would call orchestration of
Speaker 3: our PC, like RPC orchestration because and I think that
Speaker 3: you know, single flight mutations is one kind of flavor
Speaker 3: of utilizing rpcs and orchestrating like data flow through rpcs.
Speaker 3: There's other ones like routing is a big RPC orchestrator really,
Speaker 3: anything that's providing life cycle based on user input, so
Speaker 3: even forms or the framework itself.
Speaker 4: It's it's tricky because the biggest cause of waterfalls, in
Speaker 4: my opinion, in terms of co location is often those
Speaker 4: two causes. There's the code splitting. We want to code
Speaker 4: split at the route level generally, like you know, you
Speaker 4: can do lazy components wherever, but because of the code splitting,
Speaker 4: it's hard to fetch the day before you have the
Speaker 4: code to pitch the data essentially, So that's what pushes
Speaker 4: us to hoisting. And it's necessary because you don't want
Speaker 4: to load all the JABSKO for your whole app.
Speaker 1: But if you didn't, if.
Speaker 4: You didn't actually do that, then the other second thing
Speaker 4: you hit on the client. Is that co location of
Speaker 4: UI and components can lead to waterfalls depending on how
Speaker 4: the renderer handles the ACYNC in the in the rendering.
Speaker 4: So like, for example, let's say every time you hit
Speaker 4: a promise, you throw and it then re renders the
Speaker 4: whole thing. Well, if there's a promise after that, well
Speaker 4: then you're causing a waterfall, right.
Speaker 2: And I'm saying that because RPC potentially brings in the
Speaker 2: third cause, which is just the fact that people can
Speaker 2: look at the code think that if it looks like
Speaker 2: a function, then it is a function, and just write
Speaker 2: the code in a way that's very inefficient and generates
Speaker 2: a waterfall regardless of the framework.
Speaker 4: Right right, which is which is well, I mean there's
Speaker 4: two different types of waterfalls, necessary waterfalls and unnecessari stary waterfalls.
Speaker 4: Necessary waterfalls can still be made unnecessary if you say,
Speaker 4: move everything into a single function call and you know,
Speaker 4: put them together whatever.
Speaker 1: But there's a dependency.
Speaker 4: But there's a dependency, right, Like there's like you need
Speaker 4: to get the users to get or get the user
Speaker 4: to get the posts for some reason. But if you
Speaker 4: could fetch them both off the user ID, like the
Speaker 4: poster is user ID and the user information off use ID,
Speaker 4: then that's an unnecessary waterfall. The problem is we cause
Speaker 4: unnecessary waterfalls all the time in our UI rendering. If
Speaker 4: if because we go okay, well the posts go under
Speaker 4: the user section, and then you you basically by by
Speaker 4: using ACYNC in your component, you're basically like putting in
Speaker 4: a weight in the middle and blocking. Blocking rendering sucks
Speaker 4: a weights suck for rendering UI. You don't want ACYNC
Speaker 4: components really it React gets away with it on the
Speaker 4: server because it's on the server, and server waterfalls are
Speaker 4: not as bad.
Speaker 1: But I'd argue against that.
Speaker 4: I'm generally speaking it's this co location of data and
Speaker 4: UI that causes this blocking. The reason I'm stressing on
Speaker 4: this is because it's solvable with signals, Like basically, if
Speaker 4: you're doing fine green rendering, there's no reason to await
Speaker 4: or block except for where the data is finally being
Speaker 4: used at the end of the data chain, which means
Speaker 4: that you could parallelize this data fetching for unnecessary waterfalls
Speaker 4: not only for like sibling components, but also nested components.
Speaker 4: Because the component aspect doesn't matter, you're not blocking to
Speaker 4: re render the the you know this component, you're literally
Speaker 4: just going, oh, I actually need this in this text,
Speaker 4: in this div I'm going to block there and everything beside.
Speaker 1: It's a sibling. You basically turn all you flatten the
Speaker 1: whole tree.
Speaker 2: And this is something you know, just to be clear,
Speaker 2: just you do all this magic for us automatically, right,
Speaker 2: It's not something.
Speaker 4: I mean, this is run to time what I'm talking about.
Speaker 4: The funniest thing is it's not actually magic. It's just
Speaker 4: the way signals work. This is something that I kind
Speaker 4: of discovered a while ago when I was doing fine
Speaker 4: green rendering. That pine green rendering is actually it flattens
Speaker 4: the tree. That basically what does there's no components anymore.
Speaker 4: You just have a bunch of independent things. So if
Speaker 4: you fly on the.
Speaker 2: Tree, because signals don't care about component boundaries essentially.
Speaker 4: So if you fly in the tree and talk about
Speaker 4: async that way, then it's the same thing. Nothing has
Speaker 4: to block unless it actually has a data dependency on itself.
Speaker 4: So necessary waterfalls still walk, but things that are not
Speaker 4: necessary waterfalls don't need to block. So I think this
Speaker 4: is another wind that you're going to see in the
Speaker 4: signal of libraries. So people haven't really been leveraging this yet,
Speaker 4: but it's coming soon and we know what it looks like.
Speaker 1: Right, So I'm going to jump in here because we're
Speaker 1: running a little long here on time, and I have
Speaker 1: a suspicion with anything that Dan gets into. We could
Speaker 1: talk to for two or three hours when he gets
Speaker 1: into a topic. So before we wrap up and head
Speaker 1: to picks, is there any last word on our PCs?
Speaker 1: In summary?
Speaker 2: And all I can say is my summary is that
Speaker 2: we absolutely positively need to get Ryan and Tanner on
Speaker 2: to continue this conversation because we are scratching the surface.
Speaker 2: It feels to me.
Speaker 3: Yeah, I mean, even just what Ryan brought up about,
Speaker 3: like all the ACYNC signal stuff, there's a lot that
Speaker 3: we could go into.
Speaker 2: Yeah, but then stuck is built on react. What does
Speaker 2: that have to do with the sink signals?
Speaker 3: Maybe you say something about that, let's say, let's say
Speaker 3: it for later, Let's save that for later. We are
Speaker 3: running along. There's a lot to talk about. But and
Speaker 3: you know, hold on, you brought up a good point
Speaker 3: though about the necessary waterfalls as well, Like necessary waterfalls
Speaker 3: are still there and they still need to be handled,
Speaker 3: And like I feel like I've been spending a lot
Speaker 3: of time on that as well as like, you can
Speaker 3: still make mistakes there that you can't solve with a
Speaker 3: bundler or you can't solve with with signals or anything
Speaker 3: like that. So but you can solve some of those
Speaker 3: problems with with good API design and prefetching and and
Speaker 3: you know, so, I think there's a lot more to
Speaker 3: unpack there. I don't really want to. Okay, there's a
Speaker 3: reason that tan Stack everything is built to be agnostic.
Speaker 3: I'm a very firm believer and React and obviously it's
Speaker 3: it's our most supportive framework, but it by no means perfect.
Speaker 3: It's it's not, it's but it's amazing, it's great. There
Speaker 3: there's pros and cons to every UI framework, but I
Speaker 3: I'm very much preparing for a future where there are bigger,
Speaker 3: better UI frameworks doing amazing things. And the things that
Speaker 3: Ryan just teased and talking about with like signals and
Speaker 3: acinc and flattening signals to to you know, around suspense
Speaker 3: and things like that, that stuff's really exciting. Uh I.
Speaker 3: And I'm just gonna gush a little bit right here
Speaker 3: before we end and say that the things that Ryan
Speaker 3: is working on with solid two point zero have made
Speaker 3: me the most excited about what's technically possible with the
Speaker 3: UI framework since I discovered React and discovered hooks and
Speaker 3: really got into it. So hopefully it's a good teaser
Speaker 3: for maybe what we can talk about next time.
Speaker 2: Thank you, look, I'm here for it each and every
Speaker 2: time you just say when I'll have you on the
Speaker 2: show again.
Speaker 1: Alrighty well, thanks to Ryan and Tanner for scratching the
Speaker 1: surface on our PCs and waiting our whistle for more
Speaker 1: discussion on the truly geeky stuff that we talk about.
Speaker 1: With that, we'll move to picks picture, the part of
Speaker 1: the show where we get to talk about anything we
Speaker 1: want to talk about, could be tech related, could be
Speaker 1: not tech related. We run the gamut. I will start
Speaker 1: off with what I consider the high point of any
Speaker 1: of our episodes, which is the dad jokes of the week.
Speaker 1: So the other day I was watching a show called
Speaker 1: ten Ways to Avoid a Shark attack, and I was
Speaker 1: surprised that stay out of the water wasn't on the list.
Speaker 2: There was actually a skit about that on YouTube where
Speaker 2: they do a parody of a horror movie when there's
Speaker 2: the shark in the pool, and everybody's like, oh my god,
Speaker 2: there's a shark in the pool.
Speaker 3: What can we do in this?
Speaker 2: The one guy keeps on saying.
Speaker 3: Just don't go into the pool, right right.
Speaker 1: So yeah, my drum joke here is not working. And
Speaker 1: I'm really bummed because that adds all the impact. So
Speaker 1: I'm gonna have to sue a riverside for that one.
Speaker 1: So my wife looked at my feet this morning and said, honey,
Speaker 1: your socks don't match. And I said, that's funny. I
Speaker 1: have another pair just like them in the drawer. But
Speaker 1: it boom. And then finally, in a surprising announcement, Head
Speaker 1: Shoulders have decided to discontinue their popular anti dandruff shampoo line.
Speaker 1: The decision left many people scratching their heads. I expected
Speaker 1: not that I need that, as you can tell by
Speaker 1: the video. So those are the dad jokes of the week. Dan,
Speaker 1: you got any picks for us?
Speaker 3: Yeah? So two funny things.
Speaker 2: First of all, Avishai Shalom, we've had on this show
Speaker 2: a while back, made an interesting observation on X and
Speaker 2: I literally quote him because he just wrote it very well.
Speaker 2: He was talking about the fact that will Ai destroy
Speaker 2: the Worldwide Web because the bit it's destroying the web's
Speaker 2: business model, and he says it's actually worse. NLM's marked
Speaker 2: the end of open networks because the cost of producing
Speaker 2: junk and malicious content is now near zero. We already
Speaker 2: see this in LinkedIn, Facebook, et cetera, but more alarming
Speaker 2: in GitHub and NPM. And it's a very interesting observation,
Speaker 2: I think, And so that would be my first pick,
Speaker 2: that observation. And the second one is this funny story
Speaker 2: that just came out about the fact that the UK
Speaker 2: government is trying to sue four Chan. Turns out that
Speaker 2: the the UK passed the law that requires age verification
Speaker 2: before you access potentially offensive content, and four Chan, being
Speaker 2: an American company, is not complying with the UK laws,
Speaker 2: so they're actually trying to force them to comply by
Speaker 2: they sent them a threatening email and they basically responded
Speaker 2: with First Amendment bitches. And it will be interesting to
Speaker 2: see where this goes. So yeah, that would be my
Speaker 2: second pick. And I think you can tell which side
Speaker 2: them on in this argument, or put it this way,
Speaker 2: The worst thing that has ever ever happened to the web,
Speaker 2: I think is GDPR.
Speaker 3: Yes, and.
Speaker 2: Yeah, we don't need any more of that.
Speaker 3: So yeah, those would be my two picks for today.
Speaker 1: All right, Tanner, you got any picks for us?
Speaker 3: Picks? Picks them of these pics? Do these picks needed?
Speaker 3: Is random the room? The randomer the better, randomer the better.
Speaker 1: Okay, why you think about it, We'll go to Ryan.
Speaker 1: See if Ryan anything.
Speaker 4: Ryan, I'm just gonna think here because I've been so busy.
Speaker 4: If you guys don't know, I have a little baby
Speaker 4: at home, so I have that to your pick. Yeah,
Speaker 4: I mean, I mean, honestly, I don't get to watch
Speaker 4: or check out nearly as much as I want to
Speaker 4: that and like kids shows. I recently watched what it
Speaker 4: was like K Pop Demon Hunters.
Speaker 1: I've heard real good things about that one.
Speaker 4: Yeah, you know, I mean if I mean, people are
Speaker 4: gonna disagree with me, but it gave me like it's
Speaker 4: got almost like Sailor Moon vibes, but like some big production,
Speaker 4: you know, thang it.
Speaker 1: It was fun, the kids liked it.
Speaker 2: Since you mentioned the show, and to give Tennor a
Speaker 2: little bit more time, I have to say that I
Speaker 2: was really disappointed with the second season of San I mean,
Speaker 2: they had an entire episode which was literally funeral. I
Speaker 2: mean what the half.
Speaker 1: I haven't watched that one, so I can't.
Speaker 4: Oh, I know, I know what else I want to
Speaker 4: say without giving away too much. I actually enjoyed the
Speaker 4: ending of season three of Squid game station to have
Speaker 4: split it, but oh really, but I like the second
Speaker 4: third season together. It ended in a I like the
Speaker 4: way it ended, So maybe I'm made me minority. But
Speaker 4: I actually if if if you're willing to watch the
Speaker 4: second season, that you should finish it with the third season.
Speaker 1: Well, yeah, is really into that one, and he was
Speaker 1: explaining the plot to me. I haven't watched the NAVA,
Speaker 1: but he's explaining to me, and I mean, it sounded
Speaker 1: the first season is just creeped me out. It was
Speaker 1: more of a Hunger Games type vibe and it just
Speaker 1: sort of creeped me out. But he was explaining what
Speaker 1: was going on in the second third seasons to me,
Speaker 1: and that's that's pretty intriguing the way they're doing it
Speaker 1: right now.
Speaker 2: Thank you word for it, as long as you don't
Speaker 2: tell me that you enjoyed the eighth season of Game
Speaker 2: of Thrones.
Speaker 1: No, no, that was that was not my favorite. All right, Tanner,
Speaker 1: we gave you some time.
Speaker 3: What do you got. I mean, I like Ryan I,
Speaker 3: so I don't consume a whole lot of of what's
Speaker 3: out there. I'm I'm more of a builder, but there
Speaker 3: there are a few things that I do I do enjoy.
Speaker 3: So I'm overly hyped for the new season of Stranger
Speaker 3: Things coming out, and so we've been rewatching all of
Speaker 3: the seasons before it. So that means that I've seen
Speaker 3: the fourth the first season four times, the second season
Speaker 3: three one, and so forth, and we're watching the fourth
Speaker 3: season four the second time now, and then we're going
Speaker 3: to anxiously await number five. Yeah.
Speaker 2: That's an interesting argument that I had with aj about
Speaker 2: fantasy book series that tend to come, you know, not
Speaker 2: yet finished, and then the next book comes three years
Speaker 2: after the previous book, and you don't remember anything. And
Speaker 2: I never have it in me to reread that those
Speaker 2: previous books. So you're basically you do have it in
Speaker 2: you to rewatch the entire series.
Speaker 3: They were they were so good, and you know, Stranger
Speaker 3: Things connoisseurs will tell you, well, this season was worse
Speaker 3: and this season was terrible, and but like going back
Speaker 3: and watching them, I mean, I'm it's been a long
Speaker 3: time since the first one came out, so like, I
Speaker 3: am very much more adult now than I was then
Speaker 3: watching them, and just the the acting from these kids
Speaker 3: is just incredible. It really is so good. And and
Speaker 3: the writing for for how quick they were taking out
Speaker 3: the first couple of seasons, like the writing in some places,
Speaker 3: I was like, okay, like that could have been better,
Speaker 3: But for the most part, we're just spoiled with great content,
Speaker 3: like what a fun story, a great story. And yeah,
Speaker 3: I was just telling my wife. Season four got a
Speaker 3: little dicey because it started feeling really evil, and I
Speaker 3: was like, well, I don't know if I want to
Speaker 3: take part in this anymore. And then all of a
Speaker 3: sudden it went super sci fi and I was like, okay,
Speaker 3: this is awesome. So yeah, we've been watching Stranger Things
Speaker 3: and that's about the only like one episode at night
Speaker 3: and then I'm asleep, so that's about the amount of
Speaker 3: time that I have to consume.
Speaker 2: How old are your kids, if I might ask, I.
Speaker 3: Have a a seven year old, a four year old,
Speaker 3: and a almost two year old, So well, I'm not
Speaker 3: they're not watching Stranger Things right now? For them? Is
Speaker 3: I just really I just introduced them to spy kids
Speaker 3: and they are like, this is the coolest series ever made,
Speaker 3: So you know, they're they're living in a different world
Speaker 3: right now. That's just as cool, but way more child friendly.
Speaker 2: No, I was asking for the perspective of your free
Speaker 2: time because, like Ryan said, then you have little children
Speaker 2: at home.
Speaker 3: Yeah, we both have little children, and I know that
Speaker 3: I know from talking to Fran that they consume, happily
Speaker 3: consume a lot of our time. So yeah, I it's
Speaker 3: basically at night for maybe an hour that you know,
Speaker 3: we get to indulge in something.
Speaker 2: So all I can say though is from watching from
Speaker 2: the other side as it were enjoyed while it lasts.
Speaker 3: Yes, oh yeah for sure.
Speaker 1: Yeah, mine are twenty five, about to get married twenty
Speaker 1: two and Congratulateen, and so yeah, we have a lot
Speaker 1: more a little more free time. But yeah, I missed
Speaker 1: some of those. I'm looking forward to grandkids and be
Speaker 1: able to have the kids into then say here you go,
Speaker 1: you know.
Speaker 2: Yeah, well my baby goes twenty three years old working
Speaker 2: in tech.
Speaker 3: Very cool.
Speaker 1: Yeah all right, So with that, we're going to wrap
Speaker 1: this up and hopefully we'll have these two backing in
Speaker 1: to continue our discussion in the meantime. Thanks for watching
Speaker 1: slash listening, and we'll talk at you next time.
Speaker 3: Bye.