Speaker 1: Hello, everybody, Welcome to another exciting episode of JavaScript Shabber.
Speaker 1: I am Steve Edwards, the host with the face for
Speaker 1: radio and the voice for being in mine. But you're
Speaker 1: stuck with me as your host today. With me on
Speaker 1: our panel, we have mister Dan Shapiro.
Speaker 2: How are you doing, Dan, I'm fine, Hello from Tel Aviv.
Speaker 3: Where it's probably really warm, right, well.
Speaker 2: Not super warm, but nice. You know, you can wear
Speaker 2: a T shirt outside if you like.
Speaker 1: Right, Yeah, I was just I'll diverge a little bit here.
Speaker 1: I was just in Thailand, been gone for a couple
Speaker 1: of weeks. Was visiting my daughter there. And in Thailand
Speaker 1: it's really really warm. It barely gets below seventy fahrenheit
Speaker 1: during the year, even at the lowest point in the year.
Speaker 1: And on the way there we got so I dressed
Speaker 1: for Thailand, right too close for Thailand. Well, on the
Speaker 1: way there, we got delayed in twenty four hours in Soul, Korea,
Speaker 1: And to say it was cold is the understatement of
Speaker 1: the year. We went from I told when we left
Speaker 1: Seoul and went to Chang Mai, we went from twenty
Speaker 1: two fahrenheit to twenty two celsius because it was.
Speaker 3: Like below zero cold.
Speaker 1: It was so cold we tried to go for a
Speaker 1: walk one day and lasted about three minutes and said, okay,
Speaker 1: we're going back inside. So but yeah, chang Mi was
Speaker 1: awesome because we had it was like in the eighties fahrenheit,
Speaker 1: you know, no humidity. This is the coolest time of
Speaker 1: the year, coolest in terms of temperature. Not because I
Speaker 1: was there, but but yeah, it was perfect, perfect weather.
Speaker 1: And then I came back from wearing shorts and no
Speaker 1: code all week to bundling up and having multiple lets
Speaker 1: on the bed.
Speaker 2: So tel Aviv is not in the eighties, but it's
Speaker 2: in the high sixties, low seventies.
Speaker 3: That's still pretty nice.
Speaker 2: During the day.
Speaker 3: Yeah, that's nice.
Speaker 2: Night night it gets a bit colder.
Speaker 1: And then also on our panel, we have mister aj
Speaker 1: how are you doing, aj Yo yo?
Speaker 4: Coming at you live from the show room, So.
Speaker 2: It's better than the alternative, Yes.
Speaker 3: Coming out you dead? Yes, I agree.
Speaker 1: So, and our very special guest today is mister Tanner's
Speaker 1: Wensley of tan Stack fame.
Speaker 3: How you doing Tanner?
Speaker 5: I do you agree?
Speaker 2: Yeah, I'm very excited.
Speaker 5: To be here.
Speaker 3: All right, it's good to have you back.
Speaker 1: We had have had Tanner here in the past on
Speaker 1: JavaScript Drabber on episode what was it Dan?
Speaker 3: I forgot the number.
Speaker 2: Oh I think it was episode five seventy eight.
Speaker 1: Five seventy eight talking about the tan Stack. And for
Speaker 1: those of you who might be wondering, this is a
Speaker 1: question I asked on the previous episode. It is not
Speaker 1: called Tanner tan Stack because he is tan, because if
Speaker 1: you look at him, he is obviously not very tan
Speaker 1: like me.
Speaker 3: It is tan because of Tanner.
Speaker 1: So for those of you unlike me who made that
Speaker 1: logical jump, good for you.
Speaker 3: But some of us aren't that smart anyway.
Speaker 1: So we are here ten day to talk about Actually,
Speaker 1: before we get into start, let's uh just give a
Speaker 1: brief description of what the tan stack is overview for
Speaker 1: those who might not have heard of it before.
Speaker 5: You guys are gonna give that, right, not me.
Speaker 3: Yeah, yeah sure. Let me pull up the about us.
Speaker 2: Page and you'll do it. Thank you, So do it
Speaker 2: if you want to.
Speaker 5: But I appreciate it. I got it. I'm just playing
Speaker 5: with you. No. I started tan stack as like an
Speaker 5: open source GitHub organization a couple of years ago to
Speaker 5: start collecting all of my libraries that I was building.
Speaker 5: It started with uh React table and then React query
Speaker 5: that we took both of those agnostics, so they became
Speaker 5: something that I didn't want to have to like brand
Speaker 5: you know, every framework times every library that I had.
Speaker 5: So I decided to call it TAN stack, and so
Speaker 5: I pulled all those libraries together and then we kept building.
Speaker 5: So now there's a there's a virtualization library called tan
Speaker 5: SAG Virtual. We have some libraries that are for like
Speaker 5: helping you build open source packages. We have our own
Speaker 5: store now or reactive store. Tan sac form is an
Speaker 5: agnostic headless form library, which is pretty sweet. It's almost
Speaker 5: one dot zero, which is pretty pretty cool. What is that?
Speaker 1: Is that like a form rendering library where you provide
Speaker 1: the underlying structure and it renders the form or what exactly.
Speaker 5: Yeah, so it's more around just like the state management,
Speaker 5: the validation and the form life cycles for forms, like
Speaker 5: for doing client side and full sack forms, but it's headless,
Speaker 5: so when it comes time to render those forms, you
Speaker 5: attached the form logic to whatever you want, whether it's
Speaker 5: like a component library or just a raw input something
Speaker 5: like that. Yeah, So it gives you full control over
Speaker 5: you over your UI, but gives you all of the
Speaker 5: nice logic and validation and management of the form state
Speaker 5: that you would expect.
Speaker 2: That's cool.
Speaker 5: Yeah, Corbyn correctly is the one who's kind of heading
Speaker 5: that up. We combined our libraries together. He was building
Speaker 5: I can't remember when he was it's been a while,
Speaker 5: it's been about two years, but he was building a
Speaker 5: form library that was supposed to kind of be the
Speaker 5: next version of Formic, but it was React only. And
Speaker 5: then I was building one that was really really type
Speaker 5: safe and agnostic. So we put them together and that
Speaker 5: became pan sac form.
Speaker 1: The according to the description, it helps you, quote stop
Speaker 1: crying over your forms. So obviously obviously you have experience
Speaker 1: in working with forms.
Speaker 5: I don't cry too much, but if there's something that
Speaker 5: would make me cry, it would be building forms.
Speaker 3: Yeah.
Speaker 2: By the way, are you familiar with the VEST form validator?
Speaker 5: So what validator? Sorry?
Speaker 2: Vest?
Speaker 5: No, I'm not.
Speaker 2: It's greaty. We actually had the creator own of hotel.
Speaker 2: He's uh, he works at Meta, but it's it's his
Speaker 2: own project. It's it's interesting in that it does form
Speaker 2: validation in a way that looks very much like unit testing.
Speaker 5: Interesting. Yeah, I would love to look at it. That
Speaker 5: sounds cool.
Speaker 2: So it's called best Okay.
Speaker 1: Needless to say, he's you hear this coming, very invested
Speaker 1: in it. Sorry, that was just hanging out there. I
Speaker 1: had to grab that one.
Speaker 5: Oh yeah, months of all so that so form is
Speaker 5: kind of another one we're working on. And then obviously
Speaker 5: the last so a year ago we did one dot
Speaker 5: zero for Tan sac Router, which I'd been working on
Speaker 5: for several years before that as well. And now we're
Speaker 5: here to talk about start, which is.
Speaker 2: So before before we go there, I noticed that you
Speaker 2: have a few more things on the ten stack site.
Speaker 2: You've got ten stack ranger.
Speaker 5: What is that ranger is? It's not used as much
Speaker 5: in my opinion. It's a fun little library from my past.
Speaker 5: But you can use it to create multi range sliders.
Speaker 5: So if you ever use the range element, you've got
Speaker 5: that single slider. Yeah, we needed some that had both
Speaker 5: handles that you'll kind of see for range slider selectors,
Speaker 5: and then we even had some that would create steps,
Speaker 5: so we'd have like three or four different handles on
Speaker 5: an individual range input and you'd be able to kind
Speaker 5: of create different steps using different handles. So it's a
Speaker 5: headless library to create those we wanted it to have
Speaker 5: a very custom UI. I don't use it as much
Speaker 5: anymore admittedly, but it's still a pretty cool library.
Speaker 2: And also ten stack configure.
Speaker 5: Yeah, the the config is what we use for publishing
Speaker 5: all of our libraries. So it it helps us both
Speaker 5: build all of the different versions like ESM and common JS,
Speaker 5: like legacy and modern versions, and it helps us publish
Speaker 5: those to tan SAC using or to NPM using kind
Speaker 5: of our It's it's based on Angular semantic version ing,
Speaker 5: but basically lets us do all of our pr automation
Speaker 5: for releasing new versions and whatnot.
Speaker 2: Cool. Okay, So now back to ten stack start.
Speaker 5: So start is I'm going to be honest, it's like
Speaker 5: ninety percent of start is just tan stack router. Because
Speaker 5: routers are frameworks, there's not really any way around that.
Speaker 5: But we decided, I decided to build the router first.
Speaker 5: That's just like a client side router that would have
Speaker 5: some SSR utilities on top of it. But then trying
Speaker 5: to put together your own SSR environment really sucks, which
Speaker 5: is why like meta frameworks as we call them exist.
Speaker 5: So tansec start is like the official implementation of getting
Speaker 5: server features into a tanseac router application that mostly includes
Speaker 5: so you get SSR, which is the very first thing
Speaker 5: which most people want. It gives you streaming on top
Speaker 5: of that as well, so all the new streaming you
Speaker 5: know APIs that React has for suspense and just being
Speaker 5: able to stream data down in responses in general. And
Speaker 5: then it gives you bundling for both, like for all
Speaker 5: the environment, so it bundles the client side the server
Speaker 5: SID and it also bundles for server functions, which is
Speaker 5: it's our version of being able to access you know,
Speaker 5: all of the server features that you would expect. But
Speaker 5: so that's where it gets a little interesting. I think
Speaker 5: we could discuss that a little bit more. But server
Speaker 5: functions are really.
Speaker 2: Cool before we get to server functions, which I would
Speaker 2: definitely want to discuss. RPCS is a favorite topic of
Speaker 2: mind and I actually had an episode on jobscript Jabber
Speaker 2: when I spoke about our PCs. I don't even I
Speaker 2: don't remember the number off the top of my head.
Speaker 3: What about it? I would check both places.
Speaker 2: Yeah, that's true. I think it's worth mentioning though, because
Speaker 2: I think we kind of skipped it that all of
Speaker 2: your libraries, utilities, frameworks, whatever, they're all built on top
Speaker 2: of React. Right, there's nothing like that. You don't you
Speaker 2: haven't implemented your own view framework or whatever it's supposed
Speaker 2: to be called.
Speaker 5: No, they're not built on top of React. We have
Speaker 5: React adapters for all of them. So every single one
Speaker 5: of these libraries is in fact called tanstak something because
Speaker 5: it's no longer just React. So, for instance, tan sac
Speaker 5: query has adapters for React and view and spelt and
Speaker 5: solid tan sac Virtual has adapters for all of those,
Speaker 5: and SODA's tan sac form and table. Tan sac router
Speaker 5: is the only one that is currently React only, and
Speaker 5: that's mostly just for our own sanity's sake right now,
Speaker 5: basically because we just wanted to get all the way
Speaker 5: finished from you know, zero to one dot zero on
Speaker 5: one framework. We're still preparing the code base and writing
Speaker 5: it to the agnostic but we're just not trying to,
Speaker 5: you know, do too much at once.
Speaker 2: You think it's really doable. I think I spoke with
Speaker 2: Ryan Carneiato while back where he told me that I
Speaker 2: think it might have been him. Maybe I'm confusing him
Speaker 2: with somebody else, but I think was probably him, and
Speaker 2: he probably said something along the lines that he came
Speaker 2: to the conclusion that writing a true multi framework router
Speaker 2: is bordering on impossible or something.
Speaker 5: I've recently changed his mind. So he had some concerns
Speaker 5: and so did I honestly, and we got together and
Speaker 5: we we've been talking for I mean years, we go
Speaker 5: back a long time, and we've been chatting a lot
Speaker 5: about this, and recently he he's like, oh, you know what,
Speaker 5: with our new Solid two point zero stuff they're working
Speaker 5: on in the new async data primitives, there's really no
Speaker 5: concerns anymore. It's just opinions on top of routing and
Speaker 5: life cycles for navigation. So really what we're going to
Speaker 5: do is actually I'll let you in on some fun news.
Speaker 5: So it's nothing. It's something official and it might might
Speaker 5: never become something official, but behind the scenes, So the
Speaker 5: Tanstack Start and the Solid start team we're working very
Speaker 5: very closely now on a lot of things. So mainly
Speaker 5: one is that tansec Start and Solid have both been
Speaker 5: based on Vinci up to this point, which is awesome.
Speaker 5: It helped us get to where we are today.
Speaker 2: But to.
Speaker 5: Better consume Nitro and to even further align our architectures,
Speaker 5: we are we are moving away from Vincy to just
Speaker 5: a unified layer for start essentially, and it's just going
Speaker 5: to have some server function plugins on Nitro coordinator and
Speaker 5: that's going to set this stage four tan stack router
Speaker 5: for solid, so solid router, and that's that's not nice
Speaker 5: that that is a semi active development. We have some
Speaker 5: people who are you know, we're separating some of the utilities.
Speaker 5: We're making sure that you know, we're not mixing up
Speaker 5: framework types and getting ready to build these adapters. But
Speaker 5: essentially there's nothing blocking us now if we want. If
Speaker 5: I wanted to divert all my attention to solid router
Speaker 5: and solid you know, getting that working and solid, I
Speaker 5: could do that today, but I'm not going to do
Speaker 5: that till we get the REACT when done.
Speaker 2: So question about that. You threw out a whole bunch
Speaker 2: of project names, some of which are familiar with, some
Speaker 2: of which less. So Vincy Nitro also as I recalled,
Speaker 2: Vinci is built on VAT. Yeah, so can you tell
Speaker 2: us a little bit about all these projects?
Speaker 5: I would love to. So let's start at the let's
Speaker 5: start the bottom level. So all of this is based
Speaker 5: on beat where one hundred percent bought into the VAT ecosystem.
Speaker 5: I believe it's I believe it's the future. So we
Speaker 5: wouldn't be able to do any of this without Beat.
Speaker 5: And at the end of the day, a lot of
Speaker 5: this boils down to just VEAT and Beat plugins, and
Speaker 5: some of it is going to use the new VAT
Speaker 5: six environment APIs, and some of it we can just
Speaker 5: do today already just by building multiple environments ourselves. So
Speaker 5: then on top of VEAT there's Nitro. So Nitro is
Speaker 5: this toolkit that it uses Beat, but it helps you
Speaker 5: build your back end code to work basically anywhere you
Speaker 5: want to deploy it. So you can use Nitro as
Speaker 5: this unified layer. Nitro is by the UNJS team and
Speaker 5: it has this unified layer for pretty much everything you'd
Speaker 5: want to do on the back end. You can write
Speaker 5: your code mostly one way and deploy it to basically
Speaker 5: anywhere that they may maintain an adapter for and it
Speaker 5: will just work.
Speaker 2: So they handle the deployment part of building a framework
Speaker 2: Slash Metal framework for you, because that's obviously a big
Speaker 2: challenge having to deploy to all the different platforms.
Speaker 5: Well, like to put it into perspective if you so, so,
Speaker 5: like next JS and Remix, they have to maintain their
Speaker 5: own adapters to build their projects into the right formats
Speaker 5: for all these different deployment destinations. Nitro does that. That's
Speaker 5: Nitro's job, and so if you just use Nitro, you
Speaker 5: don't have to worry about that and duplicate all that effort.
Speaker 5: You just get to use what Nitro has built. So literally,
Speaker 5: for me, I recently migrated a site from Versell over
Speaker 5: to Netlify, and it was literally the difference of me
Speaker 5: going into my config and saying deployment you know, I
Speaker 5: think deployment preset, I think is what it's called. I
Speaker 5: just changed it. It's a string, and just changed it
Speaker 5: from Vercell to Netlafi. And when I rebuilt it, it
Speaker 5: just rebuilt everything for Netlify instead. I didn't have to
Speaker 5: change anything.
Speaker 2: And it also assumes supports as cloud Flare whatever and
Speaker 2: so on and so forth.
Speaker 5: Yeah, and so Nitro is built on top of VEAT
Speaker 5: and they're upgrading to the new VAT APIs as well.
Speaker 5: So it's the clearest path for no duplicated effort. Really
Speaker 5: whatsoever is they're going to maintain these adapters and we're
Speaker 5: going to use Nitro directly, and you get to use
Speaker 5: the Nitro APIs in your apps as well, so they
Speaker 5: have wonderful products like un storage where you just kind
Speaker 5: of have this unified storage API and you supply the
Speaker 5: drivers and that driver may map to, you know, one
Speaker 5: type of memory on this host, or you could map
Speaker 5: it to another one. If you're using cloud flair, you
Speaker 5: could map it to D one or something like that.
Speaker 5: So they have a really great like abstraction for all
Speaker 5: of these different implementations of features that we like to
Speaker 5: use on servers.
Speaker 2: I'm curious aside from you guys, you and Ryan and
Speaker 2: who else is using them for what.
Speaker 5: It actually came out of the view and the Next ecosystem.
Speaker 5: So Next is built on top of UJS essentially like
Speaker 5: all of it, and that's what they use. So UNJS
Speaker 5: and Nitro is kind of like the lower level server
Speaker 5: toolkit and the primitives that came out of the Next project.
Speaker 1: I was wondering if there was a relationship because I
Speaker 1: remember talking with Daniel Rowe about Nitro when that first
Speaker 1: came in, when they first started using that, and the
Speaker 1: speed increase was supposedly real phenomenal.
Speaker 5: And you know who else uses it is Brandon who
Speaker 5: built analog JS. So that's it's the it's kind of
Speaker 5: the same approach, like, hey, let's build a framework that
Speaker 5: uses Nitro, but for Angular. So he built his own
Speaker 5: Angular meta framework and it uses Nitro under the hood.
Speaker 5: Very very cool. That's that's how powerful and portable it is.
Speaker 2: So it's certainly interesting that vit came out of you
Speaker 2: and now Nitro came out of you. So if he
Speaker 2: was contributing a lot to the framework space way beyond
Speaker 2: View itself.
Speaker 5: Yeah, absolutely, There's there's a lot of things about Next
Speaker 5: that have been pushing forward what we've been able to
Speaker 5: do outside of like Next itself. It's pretty sweet. So
Speaker 5: Vinchi Vinci is built by Nikhil Serov, and Nikiel was
Speaker 5: working on a Solid team for a little while. I
Speaker 5: think he still is technically started the part of the
Speaker 5: Solid team. But before VT six came out, there wasn't
Speaker 5: really a way for you to do kind of a
Speaker 5: unified Hey I'm building a full stack application, like a
Speaker 5: unified config you would have to have had like one
Speaker 5: VAT configuration and build setup for your client, and then
Speaker 5: you'd have to have another setup with Nitro or something
Speaker 5: else for your back end, and you kind of merge
Speaker 5: those together or you end up building something that something
Speaker 5: like that on your own, like Remix has done. But
Speaker 5: Nikkio wanted kind of this unified layer, and we also
Speaker 5: needed to do some multi environment things before VAT six
Speaker 5: came out, so he built Vinchi vin XI and Vinci
Speaker 5: is essentially a wrapper around that experience. So it uses
Speaker 5: Nitro directly and Beat directly to coordinate this full stack
Speaker 5: dev and broad build experience. And it was phenomenal, Like
Speaker 5: it helped me get off the ground really quickly and
Speaker 5: just start focusing on building like the run time and
Speaker 5: my framework APIs. Now that we're getting closer to one
Speaker 5: dot zero for Tanstak Start, we want I want more
Speaker 5: control over what we're doing with Nitro and what we're
Speaker 5: doing with VAT, and Nikkiel is also just very busy
Speaker 5: with other things, in my opinion, more important things for him,
Speaker 5: and that's totally fine. So Ryan and I have decided
Speaker 5: that we're going to kind of slowly start to supplant
Speaker 5: this Vinci logic with just a shared layer that we
Speaker 5: that we use between all the start projects implemented in
Speaker 5: what by the way, Well, sorry, what do you mean?
Speaker 2: What are you Well, of course, I of course I
Speaker 2: assume it's job Well typescript, but like, what libraries are
Speaker 2: you using there? Is it like based on signals because
Speaker 2: it's Ryan or no.
Speaker 5: So so this layer is mostly going to be a
Speaker 5: collection of veat plugins that are very configurable and they'll
Speaker 5: use Babel under the hood, and really it will all
Speaker 5: come together in hopefully what's going to be a very
Speaker 5: thin layer on top of Nitro. So essentially just feeding
Speaker 5: Nitro a unified config to say, here's here's what I
Speaker 5: want you to build for my server environment, for my
Speaker 5: SSR environment, and for my client environment, those the bundles particularly,
Speaker 5: and just to kind of make all that cohesive.
Speaker 2: Mm.
Speaker 5: Yeah, it'll just be typescript at the end of the day.
Speaker 5: What I would like to have it be is just
Speaker 5: a veat plug in itself, which kind of sounds weird.
Speaker 5: It's a beat plug in that would call into Nitro
Speaker 5: to produce many different environments and build even more veat
Speaker 5: the bundles. So but that's I think that's the beautiful
Speaker 5: part about it is that if we can boil it
Speaker 5: down to just Beat plugins, I think it's going to
Speaker 5: be really powerful.
Speaker 2: And that's basically going to be like under some sort
Speaker 2: of a start moniker.
Speaker 5: Yeah, most likely we'll probably just share internal packages privately
Speaker 5: for now, and each one of us will just export
Speaker 5: our own builders for it, so you'll still you know,
Speaker 5: you'll probably build something like create tan stacks start. VAT
Speaker 5: will be like one of our packages, and you'll call
Speaker 5: that function and it will produce all the VAT plugins
Speaker 5: that you need to add to your build essentially.
Speaker 2: And the way, by the way, one thing that you
Speaker 2: said before, or that the ten stack router was ninety
Speaker 2: percent of the way towards tenstack start in terms of
Speaker 2: being a framework, I think Ryan Florence more or less
Speaker 2: said the same thing about remix and React router. I
Speaker 2: think they even kind of merged the two projects together
Speaker 2: for that reason.
Speaker 5: Yeah, I yeah, I don't. I wish that maybe that
Speaker 5: had been recognized sooner so that they didn't have to
Speaker 5: go through kind of a snip snap, snip snap kind
Speaker 5: of a pattern, because it's always been apparent that the
Speaker 5: router is what drives much of what you do. That's
Speaker 5: where all the opinions are and where you're feeding you know,
Speaker 5: it's calling into your code and scheduling its own things
Speaker 5: and doing something, so it very much is the framework.
Speaker 5: I yeah, I don't have a whole lot to say there,
Speaker 5: other than I just wish that they had maybe it
Speaker 5: would have been better for their branding. I think if
Speaker 5: they hadn't have done like, oh, it's remix and then
Speaker 5: they took react router and put it into remix, and
Speaker 5: now it's React router and putting Remix back in there,
Speaker 5: it's very confusing. It should have just been incremental from
Speaker 5: the beginning. They should have built remix as an add
Speaker 5: on to react router. But I do everybody has their reasons.
Speaker 2: Well the reasons, and also, like you said, people realize
Speaker 2: things as they built them.
Speaker 5: Yeah, and you know, that was merely an idea that
Speaker 5: I had. I just wanted to build my own router,
Speaker 5: and I knew that I wanted it to be client
Speaker 5: side only and that server side features were going to
Speaker 5: come later. I'm very very grateful that they were willing
Speaker 5: to go guinea pig that process and probably find out
Speaker 5: the hard way that it should have just been React
Speaker 5: router all along. So I'm not complaining they they have.
Speaker 5: They've done me a great favor in research.
Speaker 6: And yeah, by the way, I'm curious, do you think
Speaker 6: that maybe routing client side routing, I mean, should have
Speaker 6: been part of the platform in some.
Speaker 5: Way, which platform, like the web platform.
Speaker 2: Yeah, like dome APIs for client side routing beyond the
Speaker 2: basic history APIs or.
Speaker 5: I don't know. I mean it's easy to say, yeah,
Speaker 5: that would be great, but uh, where would those opinions
Speaker 5: come from that would serve everyone? I don't I don't know,
Speaker 5: because even for projects that look that look a lot alike,
Speaker 5: even for like like react router and tan sac router,
Speaker 5: like I took good ideas from react router, I took
Speaker 5: the loader pattern and you know a couple of other
Speaker 5: patterns that I just thought, you know what, these guys
Speaker 5: really nailed these APIs, and then for other things I
Speaker 5: just did things completely different.
Speaker 2: So can you maybe talk a little bit about that.
Speaker 2: Can you elaborate a little bit about what is the
Speaker 2: loader pattern and also about some of the things that
Speaker 2: you've done differently?
Speaker 5: For sure? So the loader pattern is just a really
Speaker 5: fancy way of saying like life cycle management for navigation, Basically,
Speaker 5: you click a link and we know, hey, you're about
Speaker 5: to go to this next page, and before you even navigate,
Speaker 5: before we try and render, before do anything about showing
Speaker 5: the next content, you have life cycle methods that will fire.
Speaker 5: This goes way way back even to like knockout and older,
Speaker 5: older frameworks that were just like, oh yeah, they're about
Speaker 5: to navigate to this new page. Here's a function that
Speaker 5: you can run before that happened and potentially do some
Speaker 5: asynchronous work. So that concept, that's the core concept, and
Speaker 5: then the loader pattern is just applying that life cycle
Speaker 5: method to data loading, specifically to say, before we navigate
Speaker 5: to this route, we need to make sure that we
Speaker 5: have this data. So when you hear people talk about loaders,
Speaker 5: that's generally what they're talking about. It's just a life
Speaker 5: cycle method to ensure that data is present.
Speaker 2: By a synchronous By the way, in this context, you
Speaker 2: mean it's a synchronous to the operation of the browser,
Speaker 2: but it's not a synchronous to the actual navigation. I mean,
Speaker 2: you do need the data in order to display the
Speaker 2: quote unquote new page.
Speaker 5: Right, yeah you might. And again here's another reason why
Speaker 5: it doesn't really work to just have some universal web standards.
Speaker 5: Some frameworks will even wait to change the URL before,
Speaker 5: like until the data is loaded. And for me, for instance,
Speaker 5: I like as soon as they navigate, the URL changes
Speaker 5: synchronously and then the side effect of rendering what the
Speaker 5: user wants to see is asynchronous. So yeah, there's lots
Speaker 5: of opinions there.
Speaker 2: Interesting. So that's what is similar about about what you've
Speaker 2: done and react route. Can you talk a little bit
Speaker 2: about what is different because I also think that informs
Speaker 2: some of the differences between tintac and other frameworks.
Speaker 5: Yeah, so yeah, they both have loaders, they both support
Speaker 5: I mean, it's not even limited to remix. But let's
Speaker 5: just say, like modern routers, kind of the expectations for
Speaker 5: all modern routers is that they have nested routing, the
Speaker 5: ability to like nest route matching segments inside of each other,
Speaker 5: to do shared layouts.
Speaker 2: So I apologize for interrupting you. Just to clarify, nested
Speaker 2: routing means that you click a link and you go
Speaker 2: into uh, let's say call it a sub page or
Speaker 2: sub resource in a sense, or like and part of
Speaker 2: the page stays the same, and then part of the
Speaker 2: page changes or is that something else and I'm explaining
Speaker 2: it wrong.
Speaker 5: No, that's that's exactly right, And it's the difference of
Speaker 5: it's just encapsulation and reuse is what it is. You
Speaker 5: could write your entire router as a flat map to
Speaker 5: say this exact URL matches this exact component. And if
Speaker 5: you have components that share the same layout, like a
Speaker 5: nav bar or a sidebar, and this is back like
Speaker 5: with older versions of next JS, you would have to
Speaker 5: render that nav bar and sidebar on every single page
Speaker 5: that you wanted it to be on, right, and that
Speaker 5: has implications depending on the framework you're using that sometimes
Speaker 5: those components would unmount and remount even though they look
Speaker 5: like they're still there, you know they haven't changed. So yeah,
Speaker 5: that's that's one of the things too. Yeah, there's lots
Speaker 5: of these shared things. Nested routing is one of those things,
Speaker 5: but instead of having this flat list of URLs to components,
Speaker 5: you get to share those r l roots. So say
Speaker 5: you have you have an admin slash admin right, you
Speaker 5: might have a lot of sub pages on that slash
Speaker 5: admin slash admin, slash users or whatever. And instead of
Speaker 5: having to render like the admin sidebar for every single
Speaker 5: one of those sub pages, you just render at once
Speaker 5: in the admin layout component, and then every single sub
Speaker 5: admin page below that will get inserted into that layout
Speaker 5: wherever you render an outlet or rendered children essentially.
Speaker 2: So you got you have this sort of a slot
Speaker 2: where the sub page is like, well slotted.
Speaker 5: In yep, and that slot works for index pages, which means, hey,
Speaker 5: we didn't match anything, so we're just on the index
Speaker 5: and you can slot something in there or you can
Speaker 5: slot in subpages. Yeah, so nested routing is a big one.
Speaker 5: That's that was kind of that's that's one where react
Speaker 5: router really nailed it. You know, next js didn't have
Speaker 5: that for a while and it was really enraging and
Speaker 5: React router has had that for a long time. When
Speaker 5: next gs finally added that, it was like, oh, well,
Speaker 5: this is wonderful, and it's like, yeah, why didn't you
Speaker 5: do that sooner? And and that was a no brainer
Speaker 5: for us. It's like, yeah, we're going to support that.
Speaker 5: We're going to do nested routes, things like file based
Speaker 5: routing where you can you know, create that tree using
Speaker 5: a file structure, just to kind of have maintenance be
Speaker 5: nice and have some opinions and convention around just moving
Speaker 5: quickly loaders. We talked about kind of just your basic
Speaker 5: navigation APIs being able to have links and you know,
Speaker 5: imperative navigate calls to kind of move around your app.
Speaker 5: That all that stuff is pretty much the same where
Speaker 5: it starts to get different from both next JS and
Speaker 5: remix is so tanstack router basically was. I rewrote it
Speaker 5: from the ground up with type safety at the forefront.
Speaker 5: So every single decision that I made when I rewrote
Speaker 5: this router was so that we could have one hundred
Speaker 5: percent inferred type safety. Essentially, the goal was I don't
Speaker 5: want to have to write typescript zintax in my routing,
Speaker 5: but I want it all to be extremely type safe.
Speaker 2: Type safe means that if I put in an invalid route,
Speaker 2: I get read squigglyes. Is that what type safe means
Speaker 2: in this context?
Speaker 5: Yeah, I mean it means a lot of things. That's
Speaker 5: one of them, and that's what I like to call that.
Speaker 5: The That is the basic level one type safety that
Speaker 5: I would expect out of a router is that, yeah,
Speaker 5: you don't let me navigate static warn me that, hey,
Speaker 5: you're trying to navigate somewhere that doesn't exist. That's that's
Speaker 5: just the basic bear bones. There's a lot more to it,
Speaker 5: though I don't know how much you want to go
Speaker 5: into that, but.
Speaker 2: I think we talked about it actually in the last
Speaker 2: time you were here. So I don't want to go
Speaker 2: too deep because I want to talk about the ten
Speaker 2: stack framework and some of the RPC work is really
Speaker 2: interesting for me. I'd love to talk about that too,
Speaker 2: so just in a few words, just to mention it.
Speaker 2: As I recall, it's also type safety about r L parameters,
Speaker 2: so you can specify the type of a r L
Speaker 2: parameter and the value has to match that.
Speaker 5: Type, right, and that that applies to a lot of
Speaker 5: different areas of the API. So search perands is a big,
Speaker 5: a big piece of tan Stack router. All of our
Speaker 5: search parameters are validated and type safe and have first
Speaker 5: class APIs built in to manage search parameters like you
Speaker 5: would like use state essentially, like you're just managing state.
Speaker 5: That's that's a really big difference and something that really
Speaker 5: not many other routers, if any that I know have.
Speaker 5: That's a that's a big reason of why I wrote
Speaker 5: it as well. On top of that, there's there's type
Speaker 5: safety throughout all the other APIs that we have in there,
Speaker 5: So there's things like route context and middleware, all of
Speaker 5: that stuff is type safe as well. There's the configuration itself,
Speaker 5: like being able to use loader data inside of your
Speaker 5: components or use data from other routes, from different files.
Speaker 5: It's all type safe, it all works, it's all very magical.
Speaker 5: I don't know what else to say there other than
Speaker 5: you should try it because you're you're probably missing out
Speaker 5: if you haven't tried it yet.
Speaker 2: Let me put it this way, we are starting a
Speaker 2: new project. I basically made it part of our standard
Speaker 2: starter kit at Sisense, so you know, we might it's
Speaker 2: if it's a project that needs a full framework, like
Speaker 2: we might debate between that's a next JS or something else.
Speaker 2: But if it's a project that's mostly going to be
Speaker 2: client side rendered, then I've made ten stack like part
Speaker 2: of our standard config.
Speaker 5: I would agree, all right. So before we move on
Speaker 5: to start, there's another one more thing I want to mention.
Speaker 5: So tan stack router has caching built into it, which
Speaker 5: is like a really really lightweight version of React Query
Speaker 5: or tan stack Query built right into the router. So
Speaker 5: for very so for simple use cases, you may not
Speaker 5: even need tan sack Query. You just load the data
Speaker 5: you need in your routes and it's managed for you there,
Speaker 5: and you have things like stale time, s w R
Speaker 5: background refetching. It's all just built into the router. So
Speaker 5: that's very important, a very important distinction. And yeah, just
Speaker 5: generally managing state in the URL. If you're going to
Speaker 5: use search parameters like at all. If you're going to
Speaker 5: use search parameters, you should use dandsack router.
Speaker 6: Well.
Speaker 2: I love it when as many as possible configuration values
Speaker 2: are in the URL, So, for example, I use gfana.
Speaker 2: I've even spoken about it here on JavaScript Jabber, and
Speaker 2: one of the things I love about grafana is that
Speaker 2: most of their configurations are your parameters, which makes it
Speaker 2: very easy to share grafts.
Speaker 5: Yep. More state should be in the URL, not all state,
Speaker 5: but more of our state should be in the r L.
Speaker 5: And as soon as you want to start doing that,
Speaker 5: you'll realize that the tools you have at your disposal
Speaker 5: are not that great. So come use dan sack router
Speaker 5: and you'll be much happier.
Speaker 2: Okay, then can stack the framework ten sax start.
Speaker 5: Tan stacks start yep. So I wasn't planning on building
Speaker 5: it initially, you know.
Speaker 2: What I'm I'm not surprised. I mean, one person kind
Speaker 2: of taking on the whole next JS ecosystem. In a sense,
Speaker 2: it's a lot.
Speaker 5: It is a lot. I was I wasn't planning on
Speaker 5: building it initially because one I didn't need it personally,
Speaker 5: just building a lot of spas. But I'll be honest,
Speaker 5: I nerd sniped myself on this one really really bad.
Speaker 5: So I had this idea about a year basically a
Speaker 5: year ago, and I was like, you know what, I
Speaker 5: wonder if I could rewrite tan stack dot com and
Speaker 5: migrate it from Remix to just use tan stack router
Speaker 5: with a custom SSR setup. And I did that. It
Speaker 5: was really hard, and I was like, man, that was.
Speaker 7: Really by the way.
Speaker 2: As an aside, when I worked at WIS, I used
Speaker 2: to work at WIS up to about five years ago
Speaker 2: time flies four or five, yeah, four, four years ago,
Speaker 2: five years ago, something like that. Wicks. Actually, when I
Speaker 2: was there, we built our own SSR framework platform, and
Speaker 2: we did it for first of all, because none existed
Speaker 2: at the time. We predated next JS. I think also
Speaker 2: the use case was very different. I mean, you know,
Speaker 2: hosting millions of websites on on one platform is a different,
Speaker 2: you know, use case. So I know for a fact
Speaker 2: how difficult that can be, very challenging to do it efficiently.
Speaker 5: It's enraging a lot of the time to be honest,
Speaker 5: because I mean, the first thing you're going to realize
Speaker 5: is now you have hydration problems. Anytime you're trying to
Speaker 5: do SSR with ACT, you just have to get really
Speaker 5: strict about hydration. But yeah, it was it was difficult,
Speaker 5: and that's kind of what started tanstac Start because I
Speaker 5: was like, Okay, I just did this manually and it
Speaker 5: really really sucked. How can I make that better? And
Speaker 5: I started talking to Ryan Carniato and I was like, hey,
Speaker 5: what are you using for solid Start? And he said, well,
Speaker 5: I'm using Vinci to kind of put all this together
Speaker 5: to make my life a little easier. And I tried
Speaker 5: Vinci out and I just kind of again just built
Speaker 5: it manually, but using Vinci, and it made my life easier.
Speaker 5: And so you could see it's sort of snowball at
Speaker 5: that point. Then I decided, you know what this is.
Speaker 5: This is going to be pretty cool. And I showed
Speaker 5: it to some people that I trusted and they said,
Speaker 5: this is amazing. But I really wish it had server
Speaker 5: like like server loaders. How do I only do something
Speaker 5: on the server, And because in remix you have you know,
Speaker 5: server side loaders, and even in next days pages router
Speaker 5: you have get service props and stuff like that, and
Speaker 5: so I was like, okay, so it's not really complete yet.
Speaker 5: How can I how can I make this better? And
Speaker 5: that's when I started diving into server functions. Then initially
Speaker 5: those were implemented with Vinci, but designing a proper API
Speaker 5: around server function rpcs has been like my last six
Speaker 5: months of work.
Speaker 2: So let's talk a little bit about r PC because
Speaker 2: apparently it's a subject that's close to your heart, and
Speaker 2: I know for a fact that it's goes to mine.
Speaker 2: As I mentioned, we even had an episode about it.
Speaker 2: Can you talk a little bit about first of all,
Speaker 2: about what is RPC?
Speaker 5: Yeah? Pretty sure? It stands for Remote Procedure call, right,
Speaker 5: Am I wrong?
Speaker 2: No, you're you're absolutely correct. And by the way, I
Speaker 2: used rpc's by the way, as an aside back in
Speaker 2: the early nineties. Yeah, nothing nothing to do with weblogies. Yeah,
Speaker 2: things like COREBA or d coom mm hmm.
Speaker 5: Yeah, they have a they have a really like rich
Speaker 5: history in in computer programming, and uh, I've read a
Speaker 5: little bit about that. Ryan has sent me Ryan Carneat
Speaker 5: has sent me some stuff about them as well, and
Speaker 5: I just I love when we can like find old
Speaker 5: tech and make it feel new and great. But this
Speaker 5: is one of those things where it's like, yeah, we've
Speaker 5: been doing this for a really long time. But the
Speaker 5: idea behind the RPC is that you know, you get
Speaker 5: to uh, you get to create this function. Uh. In
Speaker 5: a very generic sense talking about rpcs, this this function
Speaker 5: that can be called remotely, and when it's called remotely,
Speaker 5: it has you know, an underlying protocol implementation and messaging
Speaker 5: implementation that sends those messages back and forth. But it
Speaker 5: creates a very like a very opaque interaction where you
Speaker 5: can just say, I need to call this function. It
Speaker 5: may happen on your machine, or it may happen on
Speaker 5: another machine, right, but it's a remote procedure call. It's
Speaker 5: going to happen remotely, and it feels very different than
Speaker 5: calling into say arrest API or graph QL or something
Speaker 5: like that. Well, just to know because similarities, Yeah.
Speaker 2: Yeah, because putting a side yeah, putting a side graph
Speaker 2: QL for a second. Yeah, if we're talking about RESTful
Speaker 2: APIs rest for API is to some extent, you know
Speaker 2: their requests response, which is the basic prerequisite for something
Speaker 2: that looks like function that you send the message and
Speaker 2: you wait until you get the response.
Speaker 5: Yeah, basically yeah, And you know, graph Ql even has
Speaker 5: a little bit of RPC vibes in it as well,
Speaker 5: where you kind of you can you can and do
Speaker 5: kind of create these functions that you that you call
Speaker 5: through the graph Ql like zintax and proto call. Right.
Speaker 5: So RPC is kind of in a lot of different things,
Speaker 5: and we even kind of implicitly create rpcs in rest
Speaker 5: environments all the time as well. You know, you have
Speaker 5: a rest API and you just kind of need this
Speaker 5: one off, like hey, you know, slash generate whatever, and
Speaker 5: you call it and it's going to do something and
Speaker 5: it's going to come back. I think in the modern
Speaker 5: in our modern definition of our PCs, though, I think
Speaker 5: a lot of it comes down to how you compose
Speaker 5: that logic, right, because generally when we're talking about graph
Speaker 5: Ql procedures and functions and and HTTP like rest APIs,
Speaker 5: these are APIs that you you kind of have to
Speaker 5: design in separate places. You say, Okay, I'm building an API,
Speaker 5: I'm building a graph Ql endpoint, and I'm going to
Speaker 5: build this function in this place and then in a
Speaker 5: completely separate location, either whether it's in your mono repo
Speaker 5: or a completely separate application. You're then constructing a way
Speaker 5: to call into that function through you know, URL schema
Speaker 5: or graph QL client that's been generated or something like that.
Speaker 5: So you creating that function and authoring that function and
Speaker 5: calling it are seemingly very separate places with an RPC,
Speaker 5: at least in our mod.
Speaker 2: Often, by the way, implemented by separate people. It might
Speaker 2: be the back end team that's creating the RESTful end
Speaker 2: points and then the front end teams that are putting
Speaker 2: some sort of facade on top of.
Speaker 5: Them, and possibly in separate languages too, right, often separate, yeah, often,
Speaker 5: And so our PCs, at least the modern way we're
Speaker 5: thinking about our PCs is more it's more of like
Speaker 5: an integrated approach to creating that messaging layer. So for
Speaker 5: anybody listening, who who could imagine you, I'm just going
Speaker 5: to tell you how we do it in ten six start.
Speaker 5: But basically, in any file you want in your application,
Speaker 5: you can call a function called create server function, and
Speaker 5: you pass that call a function, and everything inside of
Speaker 5: that function is going to only run on the.
Speaker 2: Server, even only exist on the server.
Speaker 5: It's only yeah, it's only going to exist on the server.
Speaker 5: So it like when we bundle your application, we literally
Speaker 5: take that function that's inside of there and we strip
Speaker 5: it away from the client, and what we do is
Speaker 5: we replace it with a fetch call. It's a fetch
Speaker 5: to to you know, an HTTP endpoint.
Speaker 2: Which is the sub.
Speaker 5: Yeah stub, right, you stub it, and we implement that
Speaker 5: stub we have with fet and with an httpn point,
Speaker 5: and then we extract that function into the server bundle,
Speaker 5: and on the server, we're listening to that same endpoint
Speaker 5: for that stub for that fetch call. And when we
Speaker 5: receive that call, we take their request and we pipe
Speaker 5: it through to the function that we extracted, And so
Speaker 5: they execute in completely different environments, but you author them
Speaker 5: in a full stack way. So I mean, these functions
Speaker 5: can live right next to a React component that renders
Speaker 5: on the client, and they could even live next to
Speaker 5: things that are client only in the same file.
Speaker 2: I think that's kind of the key. I think that
Speaker 2: three things I think enabled RPC for the modern Web
Speaker 2: because RPC has existed on the back end like forever,
Speaker 2: so you know, you obviously I mentioned the old technologies
Speaker 2: at Corbo and dcom. Now you have gRPC, so all
Speaker 2: this stuff on the back end is always been there
Speaker 2: on the web. I think three things that happened in
Speaker 2: recent years that's called it this way kind of enabled it.
Speaker 2: So one was the full stack frameworks. Yeah, because you
Speaker 2: needed to be able to write code that builds or
Speaker 2: compiles to both sides for this mechanism to be truly seamless.
Speaker 2: And you kind of said it it's intended for the
Speaker 2: full stack scenario. So that's number one. Another one is typescript.
Speaker 2: Without typing, this whole thing would have been moot because
Speaker 2: you need to be able to specify the types of
Speaker 2: parameters that you're sending over the wire. Now you could
Speaker 2: have done it explicitly using something that kind of looks
Speaker 2: like ZOD or something, but it would have been really
Speaker 2: uncomfortable or you know, the old component props that we
Speaker 2: used to have and react. It would have been really
Speaker 2: uncomfortable to do it that way. And the third thing
Speaker 2: that in my opinion, and I wonder if you have
Speaker 2: that kind of enabled it are is a weight a
Speaker 2: sink a weight The fact that you can call a
Speaker 2: function and have it execute a synchronously, but with the
Speaker 2: function called semantics.
Speaker 5: Yeah, I don't know about the third. I feel like
Speaker 5: it definitely helps. It definitely helps. We could have done
Speaker 5: it with callback functions. It wouldn't have been fun.
Speaker 2: Yeah, it would have been fun, and it would have
Speaker 2: broken the function called semantics. I mean, yeah, one of
Speaker 2: the big things about RPC is that it feels like
Speaker 2: a function call, and when it doesn't, then then you're
Speaker 2: missing out on most of the fun.
Speaker 5: Yeah, I would agree. It definitely a sinklewaight elevates the
Speaker 5: experience to more of the traditional RPC feel that definitely,
Speaker 5: But how.
Speaker 2: Do you do that in React client side? I mean
Speaker 2: you can't really do a sincle weight in in client
Speaker 2: side React. No.
Speaker 5: I mean they would like to make you think that
Speaker 5: you can with then you use API, but I mean
Speaker 5: it's not. It's not really intended for like end user usage.
Speaker 5: So again that kind of falls back to like that's
Speaker 5: why I built tanstat query is because React lacked and
Speaker 5: honestly to this day still lacks a really well vetted,
Speaker 5: good client side asynchronous primitive And maybe they don't add
Speaker 5: it because React query is there and it's good enough,
Speaker 5: or they don't or they just decided to skip it.
Speaker 5: But really, if you ask somebody today from from React
Speaker 5: purist Land or core Land, I'll say, oh, well, you know,
Speaker 5: you're just supposed to use server components for data fetching
Speaker 5: and and just pass promises and then you call the
Speaker 5: use or whatever to that, I say, that's making big
Speaker 5: assumptions about the way your author in your application.
Speaker 2: So yeah, well, to be fair, it's part of their
Speaker 2: their vision of the how do they call it the
Speaker 2: Uni directional data flow That RPC kind of kind of
Speaker 2: somewhat breaks that in a sense because with the Uni
Speaker 2: directional data flow model, you've got the data flowing down
Speaker 2: as props and you've got interactions flowing up as you know,
Speaker 2: let's say, server actions. I don't know do they still
Speaker 2: call it server actions or do they also call it
Speaker 2: server functions?
Speaker 5: Now, yeah, they call it server functions, which is kind
Speaker 5: of annoying, but that's fine.
Speaker 2: Yeah, it's it's functions that are not supposed to return
Speaker 2: a value though.
Speaker 5: Yeah, And see that's where that's where things differ. For me.
Speaker 5: I don't really think it breaks the React methodology, and
Speaker 5: most of that just comes down to how you're handling
Speaker 5: the responses in my opinion. But you know, for rpcs
Speaker 5: that just aren't doing anything. I mean, look at the
Speaker 5: way next JS handles server functions. Right now, you call
Speaker 5: a server function and they basically just indolidate everything they
Speaker 5: call back into the route on the server and they
Speaker 5: can re render your whole app. Now, there's a ways you.
Speaker 2: Need directional data flow. The events flow bubble up, the
Speaker 2: data flows down.
Speaker 5: It's just really not great for performance though, especially the
Speaker 5: way the React is even designed. It's it's kind of
Speaker 5: sucks to render your entire application from the top down.
Speaker 2: Let's put it this way. It's not surprising that you
Speaker 2: created React query rather than they.
Speaker 5: Yeah, no, I agree, Like I really like React, and
Speaker 5: I like this intact. I like the framework. It's it's
Speaker 5: really wonderful. If I had if I had a magic
Speaker 5: wand that I could wave, it would be that that
Speaker 5: we just use solid. But that's not going to happen.
Speaker 5: So for now, you know, I have to ride on
Speaker 5: the on the shoulders of this giant that has React.
Speaker 5: And that's fine because it's it's really good, and it's
Speaker 5: good enough and and and it's decent to work in.
Speaker 2: And No, but I'm not fired for using React.
Speaker 5: No exactly. But you know, It kind of goes back
Speaker 5: to the way that we're trying to build things with
Speaker 5: Tan SAC libraries is that it shouldn't matter really where
Speaker 5: you go. We just want to We just want to
Speaker 5: build great core functionality and bring it to all the frameworks.
Speaker 5: And yeah, I worry a little bit about reacts future
Speaker 5: with pushing server components so much because it's a wonderful
Speaker 5: technology that is kind of derailing a lot of people.
Speaker 5: And from where I'm standing this, it's very confusing for
Speaker 5: a lot of people. Well, it's very difficult to implement
Speaker 5: as a framework, and it comes with a lot of
Speaker 5: new rules and overhead that just don't really apply to
Speaker 5: I'm going to call it the more traditional way of
Speaker 5: building an SSR application that's just isomorphic and fully hydrated.
Speaker 2: So I'll derail us a little bit because I do
Speaker 2: want to talk a little bit about that. From what so,
Speaker 2: I've been looking at some statistics about the React usage
Speaker 2: and Metal framework usage. For those who don't know, more
Speaker 2: people are using reacts and all the other view frameworks
Speaker 2: put together. So React is number one, View is number two,
Speaker 2: but views less and half of React and everything else
Speaker 2: is less than the remaining part.
Speaker 3: Those stats are wrong. I know it. I can feel it.
Speaker 2: And in react Land, approximately almost twenty percent are using
Speaker 2: NEXTGS and the rest are not. They're not using any
Speaker 2: meta framework. But if you look at new websites, it
Speaker 2: seems that almost all of them are being built using NEXTGS.
Speaker 2: So any project, there's a good chance at any project
Speaker 2: older than two or three years that started two or
Speaker 2: three years ago is probably not using NEXTGS and may
Speaker 2: never use NEXTJS. But any project that's being started right now,
Speaker 2: there's a good chance that they're using NEXTJS.
Speaker 5: It's a fair assumption.
Speaker 2: The interesting question though, when they're using nextgs, are they
Speaker 2: also using server components and that I have no way
Speaker 2: to know, And I'm kind of curious about that, Like
Speaker 2: what is the buy in for server components.
Speaker 5: I don't know if it's easy to know the buy in.
Speaker 5: I mean, I we could we go back and look.
Speaker 5: I've done tons of polls. I mean, it's obviously biased
Speaker 5: off of my audience, but I've done a lot of
Speaker 5: polls on Twitter about people, how people feel about server
Speaker 5: components and NEXTJS and and if they want to use
Speaker 5: them or not, which framework they would use, and for
Speaker 5: the most part, what I've the conclusion that I've come
Speaker 5: to is that there are a lot of people coming
Speaker 5: into next JS who are who are using server components
Speaker 5: just because that is the happy path that they have
Speaker 5: designed for next JS.
Speaker 2: It's also the default unless you put client it's a
Speaker 2: server component.
Speaker 5: Yeah, and for me it's it's not interesting for me personally. Many,
Speaker 5: if not almost all the apps that I've ever built,
Speaker 5: I don't know if they would really directly benefit from
Speaker 5: from the capabilities of server components at this time. I mean, yes,
Speaker 5: they could benefit in terms of some bundle size, but
Speaker 5: the trade offs for me just are not worth it. One,
Speaker 5: I don't want to have to reason about this new
Speaker 5: mental model of you know, interweaving client and server components
Speaker 5: almost at every level of the component tree just to
Speaker 5: get you know, trade offs that don't matter for me
Speaker 5: or really won't matter much for my users at this point.
Speaker 2: But by the way, I'm going to interrupt because I
Speaker 2: need to. I think I always like to give a
Speaker 2: bit more context to our listeners. So first of all,
Speaker 2: we had two episodes with Dan Abramov and Jose Savona
Speaker 2: talking about server components. So if anybody is really interesting
Speaker 2: in the nitty gritty of what they are, I highly
Speaker 2: recommend listening to those episodes that were excellent. The key
Speaker 2: aspect about server components is that they are components that
Speaker 2: only run on the server, versus client components which run
Speaker 2: which can run both on the client and on the server,
Speaker 2: which is interesting.
Speaker 5: I'm even going to extend that to say that server
Speaker 5: components have the worst name ever. They should not be
Speaker 5: called server components. They should be called like static components
Speaker 5: are serializables, I mean, because you can technically generate server
Speaker 5: components at build time too, at bundle time. Really, really,
Speaker 5: all it is is you're just pre rendering a component
Speaker 5: and producing uh this output that is like stringified JSX,
Speaker 5: and then you're shipping that to the client from either
Speaker 5: the static build or dynamically during from the server during runtime,
Speaker 5: and then you're you're rendering that JSX stringified version. You're
Speaker 5: turning that into something you can I.
Speaker 2: Prefer to think about it as serialized virtual dome.
Speaker 5: Exactly what it is, it's serialized virtual dome. And when
Speaker 5: you talk about it like that, it becomes much easier
Speaker 5: to reason about what you would actually get from using them,
Speaker 5: which for me, out of the box, the things that
Speaker 5: I think, what are that are interesting about server components
Speaker 5: is that you could you could import and render and
Speaker 5: do a lot of complex work with using really large
Speaker 5: bundles and libraries on the back end that produce a
Speaker 5: really small uh jsx output and you would only have
Speaker 5: to ship that to the client. And that's something that's
Speaker 5: that actually is very useful, uh thinking about it from
Speaker 5: that way, and that's something where like it would be
Speaker 5: useful for like Meta. You know that that's the whole
Speaker 5: reason they built relay and the ability for relay to
Speaker 5: send components down in chunks with certain grapht QL responses
Speaker 5: was so that they could only send down the code
Speaker 5: that they needed to render the thing at that exact moment.
Speaker 5: So it's very much like the next generation of that idea,
Speaker 5: even though Meta is not using it, which is another topic,
Speaker 5: but that's this is the next generation of that idea
Speaker 5: is only sending the code that's needed to run on
Speaker 5: the client to produce that things. It doesn't really have
Speaker 5: a whole lot to do with data loading other than
Speaker 5: you can load the data on the server and then
Speaker 5: produce the HTML and the server and send the htmail
Speaker 5: down to the client. So it's very much like using
Speaker 5: a traditional rendering framework from like old back end days.
Speaker 5: You produce the HTML I'm air quoting here, but it's
Speaker 5: JSX and you ship that down to the user instead
Speaker 5: of having to ship all of your data fetching logic
Speaker 5: and you're rendering logic down to the client.
Speaker 2: So does ten stack actually support server components or do
Speaker 2: you solely rely on server functions.
Speaker 5: I will support them, so I've actually written all the
Speaker 5: code to proof of concept this out. It works. We're
Speaker 5: going to support them in a very safe way. I
Speaker 5: can go into depth and that actually I think it's
Speaker 5: worth talking about that. So server components. People look at
Speaker 5: server components through the lens of next JS right now,
Speaker 5: because that's.
Speaker 7: The only thing that we know and the implementation I think, yeah,
Speaker 7: next JS, their entire router, like the entire experience from
Speaker 7: the root of the of the application down, is a large.
Speaker 5: Server component. Essentially, it starts at the route and it
Speaker 5: starts on the server, and it interweaves between client and
Speaker 5: server going all the way down. That has kind of
Speaker 5: skewed the way that people look at server components. I
Speaker 5: think they think that that's the only way that it
Speaker 5: can happen, and that all of their routing files and
Speaker 5: their layout files and all these other things are going
Speaker 5: to be written in this like us server used client
Speaker 5: kind of handoff thinking about these rules well, similar to
Speaker 5: so if you caught next JS comp this last year
Speaker 5: Ryan Florence, they demoed how it could be different, and
Speaker 5: it aligns, it almost aligns exactly with how I was
Speaker 5: thinking about them as well, is that server components are
Speaker 5: really just another form of asynchronous state or data that
Speaker 5: you're getting from an API endpoint or some embedded static
Speaker 5: data that you have in your application, and so really
Speaker 5: it can happen at network io boundaries. Next JS has
Speaker 5: those built into the entire system, so it's just kind
Speaker 5: of that's just what's happening all the time. But for
Speaker 5: tansecs start, the way that we're going to do it
Speaker 5: is if you want to use a server component, you
Speaker 5: simply return jsx or react in a server function in
Speaker 5: an RPC.
Speaker 2: That's I felt that that was where you were going.
Speaker 5: That's it, And you know that fits right in with
Speaker 5: Remix too, because so they don't really have rpcs, but
Speaker 5: they do have loaders, which is kind of like they're
Speaker 5: hard coded rest their kind of rest flavor of an RPC,
Speaker 5: right and they're doing the same things. You just return
Speaker 5: jobs or you just return react on JSX inside of
Speaker 5: a loader. So server functions are really going to be
Speaker 5: the place.
Speaker 2: Where you can use server So a question about that. So,
Speaker 2: first of all, it seems kind of almost like you
Speaker 2: might be returning a string and then injecting it to
Speaker 2: be using what's it called unsafe in dangerously unsafe insert
Speaker 2: HTML or whatever a little bit. But the question that
Speaker 2: I have about that, what prevents that server function from
Speaker 2: returning JSX or virtual dome that the client doesn't know
Speaker 2: what to do with, like using components that don't exist
Speaker 2: or whatever.
Speaker 5: A lot of that just comes down to how it
Speaker 5: gets bundled. So the real feature, if you ever listen
Speaker 5: to Andrew from the React court is Andrew Clark. I can't.
Speaker 5: I think it's his name, right, Andrew, Yeah, I think so. Yeah.
Speaker 5: I like the way Andrew talks about it. He says,
Speaker 5: the real feature of server components is not a framework feature.
Speaker 2: It's a bundler.
Speaker 5: It's a bundler feature, and it allows you to basically
Speaker 5: render a component and only bundle up the things that
Speaker 5: it needs to render with with it. And so when
Speaker 5: you serialize that component, everything that ran on the server
Speaker 5: is going to turn into JSX markup. That's right there
Speaker 5: in that representation, and everything that can't run on the
Speaker 5: server that needs to run on a client is referenced
Speaker 5: through a manifest, and it gets a little tricky with
Speaker 5: how that that works, but that manifest is just a
Speaker 5: mapping of client component references that can come down through
Speaker 5: server components to the actual modules and bundler modules that
Speaker 5: it can go out and grab if it needs to
Speaker 5: grab them. So when you render something on the server,
Speaker 5: it comes down with this responses is here's all this
Speaker 5: server function or the server component markup, and there might
Speaker 5: be some client components in there, and if they're already
Speaker 5: loaded into your app on the client, then they'll just render,
Speaker 5: and if they're not, then they will suspend while they
Speaker 5: go and pull that client side bundle chunk that they
Speaker 5: need to render, and then they will finally render.
Speaker 2: So a key difference, it seems to me, and again
Speaker 2: correct me if I'm wrong, between the next GS way
Speaker 2: and your approach, is that with NEXTGS the root is,
Speaker 2: like you said, a server compon, whereas in your case,
Speaker 2: the route is a quote unquote client component, even though
Speaker 2: it actually might run on the server.
Speaker 5: Yeah, I think that's a good distinction, is that with
Speaker 5: next JS, everything's going to be server first all the time,
Speaker 5: no matter what well ver so, right of course. And
Speaker 5: then with tan SAX start even down to the way
Speaker 5: that the APIs are designed, everything's written to be isomorphic first.
Speaker 5: So if you don't do anything inside of a server function,
Speaker 5: what you write is just going to happen during SSR,
Speaker 5: and it's going to happen on the client.
Speaker 2: You know what I really like about your approach now
Speaker 2: that I'm thinking about it. So I have this presentation,
Speaker 2: this talk that I gave about different ways to overcome
Speaker 2: the cost of hydration, the performance cost of hydration, and
Speaker 2: I show the different ways, and I for each such
Speaker 2: method like this, something like six or seven approach and
Speaker 2: for each one of them, I give both the upsides
Speaker 2: and the downsides of each approach. And one of the
Speaker 2: approaches that I mentioned towards the end are server components.
Speaker 2: And one of the downside of server components that I
Speaker 2: presented in my talk is that they require you to
Speaker 2: basically re architecture application. You can take an existing application
Speaker 2: and just throw in server components into it. You need
Speaker 2: to rethink your entire architecture. You need to learn this,
Speaker 2: not even new technology, but new approach and then architecture
Speaker 2: application accordingly. And what I really like, Sorry go on.
Speaker 5: I was going to say, I agree, but I think
Speaker 5: there's some nuance there where with server But with server components,
Speaker 5: you can migrate incrementally, but you have to do it
Speaker 5: from the top down. You have to slowly move the
Speaker 5: server bound So at the top if you just say
Speaker 5: I want to render my whole app as a client component,
Speaker 5: you can do that in next JS. You can even
Speaker 5: do that, I think help you can render your entire
Speaker 5: app as a client component.
Speaker 2: Well, you can have a really thin server component that basically.
Speaker 5: Just right, and and then migration path is to slowly
Speaker 5: push that server boundary down through your component structure as
Speaker 5: far down as you can. That's the incremental migration strategy.
Speaker 5: And I don't like doing refactors from the root down.
Speaker 2: Uh.
Speaker 5: In fact, I like to my my leaf node up.
Speaker 2: Yeah, but you're absolutely correct. But if you if you
Speaker 2: basically do that, then you've not Again, my presentation was
Speaker 2: in the context of improving the reducing the cost of vibration,
Speaker 2: and if you just do that, you basically not elimit
Speaker 2: not reduce the cost of vibration at all. And yeah, slowly,
Speaker 2: but all it means is that you've slowly re architected
Speaker 2: your application exactly. But and what I like about Europe,
Speaker 2: it seems to me, is that you can get these
Speaker 2: this value without re architecting your application you want to,
Speaker 2: you can you think you have some components somewhere in
Speaker 2: the tree that could benefit from being a server rendered
Speaker 2: component because I don't know, it uses some d date
Speaker 2: and time functionality that would require you to download moment jas.
Speaker 2: Well you just turned that into a server function that
Speaker 2: returns gsx.
Speaker 5: Yeah, and you know you bring up you and you
Speaker 5: brought a cool thought into my head? Is that talking
Speaker 5: about refactoring?
Speaker 4: Right?
Speaker 5: Let's imagine a lot a lot of people are on
Speaker 5: create react app. At the very least, it's it's not
Speaker 5: too difficult to get into VAT at the very least,
Speaker 5: just saying hey, I want to use veat. But to
Speaker 5: be able to use what would it take for somebody
Speaker 5: at that point then to use server components?
Speaker 2: Right?
Speaker 5: Telling them that they would need to adopt an entirely
Speaker 5: new framework is a big pill to sw swallow if
Speaker 5: they just want to consume this new server component pattern,
Speaker 5: this new technology. It's a hard pill for them to swallow,
Speaker 5: and I would wager that a lot of people wouldn't
Speaker 5: do that. But what if you could say, Hey, all
Speaker 5: you need to do is just get off of create
Speaker 5: React app, which you should do anyway, get into beat right.
Speaker 5: All you need to do is get into VAT, and
Speaker 5: if you can do that, we can give you a
Speaker 5: VAT plug in that will let you call server functions
Speaker 5: and then let you return server components, and then you
Speaker 5: can just render those server components even without refactoring really
Speaker 5: any other part of your application. Even if you're still
Speaker 5: using React router version four or five, you could still
Speaker 5: make an API call using whatever you want using React
Speaker 5: query even and call into a server function, get back
Speaker 5: a server component, and render it. You would just need
Speaker 5: to migrate to VAT and be using real act nineteen.
Speaker 5: So that that's probably the path of least resistance if
Speaker 5: like you're, if you just want to get your hands
Speaker 5: on server components, that's the path of least resistance that
Speaker 5: I'm trying to make possible. So I know I said
Speaker 5: that start is ninety percent router. That's if you're consuming
Speaker 5: the whole the whole framework. But really at the end
Speaker 5: of the day, what Start is is just the ability
Speaker 5: to do SSR if you want and server functions. That's right.
Speaker 2: I love that. And and by the way, I told
Speaker 2: Dan Abramov when he was on the show that the
Speaker 2: because you know, they were they were getting huge pushback
Speaker 2: against React server components, and you know, and I know
Speaker 2: that it. The React team got a lot of pushback
Speaker 2: that they weren't used to get. That's put it this way.
Speaker 2: They were always The last time they got such pushback
Speaker 2: from the community was I think more or less when
Speaker 2: they introduced x and they had hoped that the reaction
Speaker 2: would have been similar to the reaction that they got
Speaker 2: when they introduced hooks, which were really quickly adopted by
Speaker 2: the creatity. And the key difference was that hooks you
Speaker 2: could basically take it or leave it. You could use
Speaker 2: it on a per component basis. So when you could
Speaker 2: take an existing React application and decide that I'm not
Speaker 2: going to touch any of the existing code, but new
Speaker 2: components that I'm adding would use hooks and everything would
Speaker 2: just work.
Speaker 5: Andiquire an architectural overhaul.
Speaker 2: Exactly. It was at the component level, and if you
Speaker 2: can do that for React server components. That would be amazing.
Speaker 5: In my opinion, it's fine that it requires an architectural overhaul.
Speaker 5: It's going to require something. If it involves a server,
Speaker 5: you're going to have to do something architecturally. I just
Speaker 5: think that rolling up that architecture change into hey, you
Speaker 5: have to adopt this entirely new framework, that's a hard
Speaker 5: pill to swallow. And you know that's both next JS
Speaker 5: is in and I think React routers hope is that hey,
Speaker 5: just buy into our router and will take care of
Speaker 5: the rest, right And unfortunately for me, that's that's the heart.
Speaker 5: That's an even harder pill for me to swallows because
Speaker 5: I don't really like the routers that I see out there.
Speaker 5: I don't like next JSS router, and I moderately enjoy
Speaker 5: React router, but it lacks a lot of things. For me,
Speaker 5: I'm definitely not happy using it anymore. And so knowing
Speaker 5: that other people are going to have to make that
Speaker 5: same sacrifice to say, oh, yes, I have to buy
Speaker 5: into next JS all of it, or I have to
Speaker 5: buy into React router at least if I want to
Speaker 5: get on a path to use these latest React features
Speaker 5: That's not something that I want to have to do
Speaker 5: even myself, and I don't want to have to make
Speaker 5: other people do that as well. So I'm trying my
Speaker 5: hardest to build start in a way that can be
Speaker 5: consumed without having to just turn your entire application upside down.
Speaker 5: There's always going to be a little bit of buy in,
Speaker 5: you know, you have to buy in a beat. You're
Speaker 5: going to have to buy into servers in general, Like
Speaker 5: I hope your company lets you run server code, because
Speaker 5: a lot of a lot of front end devs are
Speaker 5: not allowed to provision servers.
Speaker 2: So I'll put it this way. When a while not
Speaker 2: so long ago, I was interviewing at a couple of companies,
Speaker 2: and I was interviewing at senior technical rank. So one
Speaker 2: of the things that I was looking at during the
Speaker 2: interview process was actually the technologies and architectures that they
Speaker 2: were using for the front end. And what I saw
Speaker 2: is that all of them were using React, and almost
Speaker 2: none of them was using SSR or any other any
Speaker 2: consequently any meta framework. And if you could provide the
Speaker 2: ability for such companies to start leveraging the benefits of
Speaker 2: React on the server side in a way that does
Speaker 2: not disrupt their existing architecture and their existing code base.
Speaker 2: That that's a huge benefit.
Speaker 5: Yeah, I agree, And you know, I came from that
Speaker 5: world where like I wasn't going to start even on
Speaker 5: my small team, I didn't want to have to provision servers.
Speaker 5: My team. We had our APIs written in a different language,
Speaker 5: you know, distributed through a very different means, Like I
Speaker 5: wasn't going to touch server code anytime soon. I mean,
Speaker 5: a lot a lot of very successful applications and enterprise
Speaker 5: companies like to even think about, oh yeah, our front
Speaker 5: end developers are going to start running server side code.
Speaker 5: Is a big leap because just the way that you know,
Speaker 5: APIs need to scale, they get their own teams, they
Speaker 5: turn into different languages. I just think that there's so
Speaker 5: many more benefits that we should be looking to give
Speaker 5: front end developers right now who work on these kinds
Speaker 5: of applications and large enterprise applications, who you know, so
Speaker 5: many of them won't even be able to touch server
Speaker 5: components until their company finally decides years from now to
Speaker 5: let them run server side code. So yes, I'm excited
Speaker 5: about you know, the server and I'm trying to go
Speaker 5: down that path as much as I can, but I'm
Speaker 5: still so heavily invested in the client side tooling space.
Speaker 5: I think Query has been phenomenal for the industry. I
Speaker 5: think Table is great. I think tan SAK router is
Speaker 5: still the most underrated part of what I'm building, because
Speaker 5: if you're if you're a client, if you're a client
Speaker 5: side application, and you're going to stay a client side application,
Speaker 5: I really don't understand why you would even consider using
Speaker 5: next JS or React router at this point. There there's
Speaker 5: just if you if you're questioning that, then you should
Speaker 5: DM me and I'll talk to you about it. Because
Speaker 5: I built Tansac router for enterprise routing use cases and
Speaker 5: it truly shines. So yeah, those that in that part
Speaker 5: of our industry is very underrepresented and soft spoken, especially
Speaker 5: on places like social media and Twitter. There's very very big,
Speaker 5: successful applications being maintained by very smart people that we
Speaker 5: never hear from on Twitter or x or anywhere like that.
Speaker 5: So I know they exist though, and I talk to
Speaker 5: them offline, I talk to them in DMS, and I'm
Speaker 5: trying to represent them as well.
Speaker 1: Oh, Dan, we need to get wrapped up here because
Speaker 1: it's been a long time here, so let's do some
Speaker 1: last words from both of you guys, and we'll move
Speaker 1: on to picks.
Speaker 2: Now. One thing that I wanted to talk about, but
Speaker 2: I don't think we have time, so we can do
Speaker 2: it in the future time is but like some of
Speaker 2: the downsides of our PCs that existed again way back
Speaker 2: in the nineties, rpc's, for example, tended to be chatty protocols.
Speaker 2: They also tended to introduce a lot of endpoints and
Speaker 2: generally introduce various maintenance issues. But I don't think we
Speaker 2: really have time to delve into this this time, so
Speaker 2: maybe we should bring you on to talk about RPC
Speaker 2: in depth.
Speaker 5: Sometimes I can give you a thirty second teaser on
Speaker 5: that if you want. I think that there's some chattiness
Speaker 5: that can happen. But I think if you're using them
Speaker 5: for your actual source of truth on full stack stuff,
Speaker 5: some interesting things there, like actually building full stack APIs.
Speaker 5: But if you're just using them to then you know,
Speaker 5: do secure things on the server that communicate externally with
Speaker 5: your other API or back in, I mean, I think
Speaker 5: that some of that chattiness can be justified. And then
Speaker 5: also there's there's fun things about server functions that we
Speaker 5: didn't even get to talk about, but we've added validation
Speaker 5: to our server functions strategies. We've added type safe middleware
Speaker 5: to our server functions, which is very very powerful where
Speaker 5: you can wrap up client side and server side transactions
Speaker 5: through server functions and do really really cool things. And
Speaker 5: then also being able to do public rpcs in the
Speaker 5: future is something that we're considering. So once you've written
Speaker 5: an RPC in Tanstak, the only thing keeping it from
Speaker 5: becoming a fully blown rest like httpn point that's public
Speaker 5: just supplying a path, a static path. So we're we're
Speaker 5: considering allowing people to even build public rests and points
Speaker 5: like static paths that they'll be able to use not
Speaker 5: just in their application side by side as an RPC,
Speaker 5: but even call into with say an RPC client that's
Speaker 5: generated for their React native app or for a bunch
Speaker 5: of different projects and kind of create some tooling around that.
Speaker 2: You know what would be awesome if we brought both
Speaker 2: you and Ryan on the show to talk about our PCs.
Speaker 2: I think that would be amazing.
Speaker 5: Anytime you get me and Ryan together, it's going to
Speaker 5: be a party. So I would love to I would
Speaker 5: love to come on with Ryan.
Speaker 2: Okay, right right, friends, I'll try to organize it.
Speaker 1: Okay, all right, well, thanks thanks Tanner. If you wanted
Speaker 1: to learn more about canstackcanstack dot com is the place
Speaker 1: to go docs and demos and all kinds of goodies.
Speaker 1: So with that, we'll move on to Picks Picks, to
Speaker 1: the part of the show we get to talk about
Speaker 1: things that we want to talk about that maybe aren't
Speaker 1: tech related.
Speaker 3: Oh could be.
Speaker 1: Let's see, Aja, you've been quiet, what do you got
Speaker 1: for us for picks?
Speaker 8: So I was looking for something to play just I
Speaker 8: was in a video game mood, and I was very,
Speaker 8: very kind of disheartened that a lot of the games
Speaker 8: I really loved as a kid, they have not been
Speaker 8: recreated in a similar form like GoldenEye. I figured, there's
Speaker 8: got to be something like GoldenEye, but there aren't really
Speaker 8: any other games other than GoldenEye in Perfect Dark where
Speaker 8: you sneak around and assassinate people through a maze to
Speaker 8: accomplish some goal. And I ended up trying out something new.
Speaker 8: I've never even heard of the genre of four x
Speaker 8: but it's explore, extend, exploit, extinguish, something like that.
Speaker 4: It's like the Microsoft strategy.
Speaker 3: It sounds like Microsoft.
Speaker 8: Yeah, so Civilization six is kind of like Age of
Speaker 8: Empires or Command and Conquer mixed with SimCity. And it
Speaker 8: is heavily, heavily heavily discounted right now because SIM or
Speaker 8: Civilization seven is about to come out, And so for
Speaker 8: all the different platforms for Nintendo Switch, you can check
Speaker 8: on GG dot Deals GG as in Good Game GG
Speaker 8: dot Deals, or decu deals dot Com deku as in Decotry,
Speaker 8: and you can get either the premium package or just
Speaker 8: the base game for two three, four five dollars. And
Speaker 8: it's my warning is that it's addictive if you have
Speaker 8: an addictive personality, if you like things where you have
Speaker 8: to mind max and strategize to figure out the best route.
Speaker 8: It's every every time you play the game. The map
Speaker 8: is randomized, and but you have a civilization that has
Speaker 8: certain been fits like what it can build earlier or whatever.
Speaker 8: And you you get a couple hours into the game
Speaker 8: and then you're past or I guess past. You get
Speaker 8: into your next age and new things unlock and you
Speaker 8: have other civilizations on the board. It's like it's also
Speaker 8: kind of like Risk and that there's different civilizations on
Speaker 8: the board. And you're trying to basically gather more land
Speaker 8: before they do and and mass more points to some
Speaker 8: of the AJM.
Speaker 2: I'm looking at the GG deals page right now and
Speaker 2: they're selling them for under three bucks.
Speaker 8: Yeah, sont for the next one. My one caution would
Speaker 8: be don't buy it for Mac, because after I got
Speaker 8: it for Switch, I also got it for Mac. Basically,
Speaker 8: my it doesn't work. It doesn't work. The game opens,
Speaker 8: it crashes if you can keep it open long enough,
Speaker 8: you can't.
Speaker 4: You can't move it from one monitor to another. All
Speaker 4: of the key bindings or Windows key bindings like with
Speaker 4: numb pad and f F six and all that sort
Speaker 4: of stuff. You can change those key bindings, of course.
Speaker 4: But my assumption is that they never tested it on
Speaker 4: Mac whatsoever, that they use some sort of framework that
Speaker 4: allows it to compile on different operating systems, and they
Speaker 4: just hit the compile button and they said, oh, the
Speaker 4: Mac build finished, okay, uh, put up the digital code.
Speaker 4: But I don't think that anyone. I don't think any
Speaker 4: of the developers of the game have ever tested it
Speaker 4: on a Mac. And if you look at any of
Speaker 4: the reviews that are one star reviews, they're all mentioning Mac.
Speaker 4: It doesn't run on Mac. It doesn't actually like it
Speaker 4: will install, it will open, you can click two or
Speaker 4: three buttons and then it crashes, so don't do that.
Speaker 2: So you're basically saying, if you've got the computer at home,
Speaker 2: get it for ecne on Farmac.
Speaker 6: Yeah.
Speaker 8: I might even run on Linux. I don't remember if
Speaker 8: that was on there, but yeah, Windows or Xbox or PlayStation.
Speaker 8: You the consoles are good because Microsoft and Nintendo and
Speaker 8: Sony will rip you a new one if your game
Speaker 8: just crashes when you start it, whereas Steam doesn't care.
Speaker 8: Steam's like, oh, game just crashes when you start it? Uh,
Speaker 8: contact the publisher.
Speaker 4: We don't care. We just take the money, all right.
Speaker 4: That's my one thing.
Speaker 3: Thank you, Dan. You got any picks for us?
Speaker 2: Yeah, not a lot.
Speaker 5: I have a I have a hard stop right now,
Speaker 5: and I don't don't how many picks, So I'd be
Speaker 5: happy to do my sign off, but I gotta run.
Speaker 3: Okay, Thanks for coming, Tanner.
Speaker 5: Thanks guys for having me. I do want to come
Speaker 5: back on and talk about server stuff with Ryan Carneado,
Speaker 5: so let me know.
Speaker 2: Make sure to organize that. Now. You've given me extra
Speaker 2: incentive that would be so awesome.
Speaker 5: Thank you so much. Good to see you guys.
Speaker 2: Awesome, thank you. So my pick is I've been an
Speaker 2: Anthony justiniic fan for a long time. You guys know
Speaker 2: who he is. He's like this edgy stand up comic
Speaker 2: and I really have enjoyed his material over the years.
Speaker 2: We even had this one really pleasant surprise where when
Speaker 2: we went to this stand up club in LA and
Speaker 2: he made a surprise appearance there to try out new stuff,
Speaker 2: new material, So that was really awesome. And I really
Speaker 2: loved his shows that he did in the past, Thoughts
Speaker 2: and Prayers and Fire in the Maternity Ward. And now
Speaker 2: he's recently come out with a new show called Bones
Speaker 2: and All and it's okay. I watched it and I
Speaker 2: enjoyed it, but it wasn't as good as his old shows.
Speaker 2: So if you're an Anthony Justinic and you haven't watched
Speaker 2: it yet, you know you should. But don't expect it
Speaker 2: to be as great as his previous his past stuff.
Speaker 2: I don't know why that's that's just my take on it.
Speaker 2: But anyway, that would be my pick for today.
Speaker 1: Alrighty, I will go last year. Since I'm the my
Speaker 1: picks are always the high point. First pick is a
Speaker 1: reference to something that Tanner said during the when he
Speaker 1: was talking earlier and he talked about how we got
Speaker 1: Nerd Sniped reminds me of one of my favorite XKCD
Speaker 1: cartoons called Nerd Sniping. It's number three, five six, So
Speaker 1: considering where things are right now, it's a very early,
Speaker 1: early one and it's called nerd Sniping, and it's it
Speaker 1: describes it perfectly. Makes me laugh every time I read
Speaker 1: this cartoon. But yeah, I go check it out Nerds
Speaker 1: x k CD number three, five six. And for the
Speaker 1: dad jokes of the week, it's been a while so
Speaker 1: so I have a.
Speaker 3: Plethora to choose from.
Speaker 1: The other day, I was talking to a friend of
Speaker 1: mine and I told him, hey, I took my wife
Speaker 1: to the Caribbean last month, and he said Jamaica.
Speaker 3: I said, no, she wanted to go.
Speaker 1: Also, did you know that you're actually born with four
Speaker 1: kidneys when you grow up, two of.
Speaker 3: Them become adult nies.
Speaker 1: And finally, it really annoys me when people get well
Speaker 1: known phrases wrong. I mean, seriously, it's not like his
Speaker 1: rocket surgery. Anyway, those are the dad jokes of the week,
Speaker 1: We'll say thanks to Tanner for coming on and talking
Speaker 1: about tan Stack. Sounds like we're going to get another
Speaker 1: episode scheduled with him and Ryan Carneatto.
Speaker 2: I really hope, so I'll do my I can only
Speaker 2: promise to do my best.
Speaker 1: Dan has connect everywhere. Man, if we want to get
Speaker 1: somebody on, just talk to Dan.
Speaker 3: He knows more. Thanks guys for
Speaker 1: Coming on, Thanks to Tanner for coming on, and we'll
Speaker 1: talk with you all next time on Jobs Hit Gebor