Hey, welcome back to another episode of Javascripts Jabber. This week on our
panel, we have a j O'Neil yoyo coming at you live from a fish
tank. Dan Shapier, Hello from an Israel, unbelievably still at war.
I'm Charles Maxwood from top End Devs, and this week we're talking to Sam
Selikoff. Sam, do you want to introduce yourself? Let people know who
you are and why we all love you so much? Sure? Thanks for
having me. Yeah, I'm Sam. I am a friend end developer,
fell in love with it. I don't know eight years ago, but started
out kind of in PHP. Perl actually was my first language, but then
I fell in love with JavaScript and was doing Ember development for a long time.
And these days I'm doing React and a bunch of other stuff in the
React ecosystem and now courses I build you I with my business partner Ryan Toronto
and make YouTube videos. So yeah, started in Pearl and lived to tell
about it. There you go, I have I have blessed a reference in
order to get an object in Pearl. I jumped on just to see and
we had you on what back in twenty nineteen to talk about Ember Octane yeah,
there you go. So I was still slinging a number in twenty nineteen,
but I remember that. I'm not sure if AJ was there, but
Charles, you and AJ. You guys are a big part of me my
early learning in JavaScript. Actually, I used to listen to the jobscript ever
religiously and I think AJ. Actually I learned about event delegation and JavaScript from
AJ in one of the episodes, and I remember that one. Well.
So, yeah, it's always awesome to be here with you guys. A
good deal. Yeah, we're all old old. I've got the gray hairs
and my beard to prove it. I know when I grow mine out,
my wife's always like, I think those those of you have hair basically just
shut up. Yeah. I shaved mine off because it's embarrassing, embarrassingly sparse.
Soyo, So let's let's compare notes. When when when did you write
your first line of JavaScript? I think it would have been like twenty thirteen,
twenty, how about you, aj Um. I'm going to go probably
closer to two thousand and eight, two thousand and nine, and you chuck.
So, I have a question on this question because I was playing with
web development in high school. But I wasn't really seriously writings JavaScript corre did
that counts? That counts. So it was probably ninety six ninety seven,
but like kidding into actual programming with actual you know, where I was running
against maybe a prototype JS or jQuery. That was probably six. So I
wrote a large scale front you know, single page application as it were back
in ninety seven ninety eight about out Yeah, offline first, by the way,
Wow, there you go. Ninety eight should have been impossible. Kind
of no fat error functions back then. Eh nah, no closures, no
try and catch, no closures, no try and catch. Wow, if
you wanted to catch an error that you know you had window on error.
There you go. I do everything I can to avoid write and try and
cat. But yeah, crazy, that's crazy. Yeah, all right,
well it'll we dive into our topic here. It sounds like there's a bit
of a backstory here because Sam, you reached out to us. There's been
some back and forth on Twitter. Do you kind of want to set the
scene for us and then we can kind of fill in the gaps? Absolutely?
Yeah, So you guys had a podcast. It looks like it was
November fourteenth. It was called RPC resurgence from client server applications to next chest
edit frameworks. And I think it was U three talking about it actually,
and you guys mentioned the slide from my talk that got turned kind of into
a meme. But you were talking about server components and server actions and you
know, the new React features that kind of have been trickling out over the
last year or so. And it was a really good conversation and there was
just some stuff in there that I I thought would be fun to dive into
a little bit more, and yeah, just unpack. So that was kind
of the backstory, and I guess that if we wanted to kick it off,
Dan was talking about had a really good kind of survey of like the
history of r PC. Maybe it was when you were writing that that SPA
in ninety seven, you know, and then you also I had a tweet
about my slide and about server actions and you had kind of replied saying,
like, we used to do this and we chose not to. So it's
there and there was a reason we chose not to. So maybe that is
one way we could kick off the conversation. Basically, our server actions just
our PC. Are they the same thing? And if so then why should
we not or why should we not do them or do them? And if
not, how are they different? So that's kind of actually so it's a
really interesting conversation for me because on the one hand, like you said,
and it's funny, by the way, how we a minute ago spoke about
the really old JavaScript and the early two thousands and late nineties, and now
we've moved to the very latest form of JavaScript with server actions and reacts over
components and whatnot. And again we're going back in time talking about our PC.
So in a lot of as I was saying back in that episode,
there are a lot of similarities, but there are also some very significant differences.
The similarity is that you're using the and the function called syntax syntax exactly
for over the wire community. So you're sending, you're performing an operation that
looks like a function call. You're sending parameters like you would into a regular
function, and you're getting a return value like you would from a function,
but it's actually being sent over the wire, and it's type safe and whatnot.
And that's exactly what our PC is, and that's what we're bringing back.
At the same time, there are some really notable differences because back in
the day, if you looked at systems that did this sort of thing back
in the nineties and even more modern systems like gRPC, it's also about being
able to communicate between different programming languages and different architectures, whereas OURPC that we're
seeing in the context of React kind of lives and exists because everything is that
is like this React app, and it's just trying to abstract the way the
concept of some stuff running on the client and some stuff running on the servers.
But it's not as a means of communicating between separate systems and even separate
programming languages. It's more of the concept of doing everything within that same React
app using typescript all the way, you know, up and down. So
there are some like key differences here as well. So you know, I
found that really interesting to see both the similarities and distinctions. But I think
I might be pulling us forward maybe too quickly. Maybe it's worthwhile to talk
again a little bit about what there was in your slide and why you think
that maybe people got so hot and bothered about it. M Yeah, So
the slide was showing a server action where you clicked create a bookmark and write
in your component's JSX. It basically had an on click and then it the
event handler had the used server directive, which meant that that code ran on
the server and it used the SQL with the template tag literal to insert a
new bookmark into the database. And folks, there was a couple of things
that that kind of sparked it off. One was it looking like an SQL
injection vector, which it wasn't because template tags and the SQL function sanitized that.
But setting that aside, it was more about the separation of concerns,
or the lack of separation and concerns from the perspective of those folks, and
that's kind of what got the conversation going. So it was kind of like
showing, you know, normally you have a button and like you were saying,
the form or the button can make a post request to an API and
over the network, and there's a separation there. It's like call the front
end, calls the back end logic, and then the back end can be
written in any programming language and it has can be using Ruban, rails or
layer vel or node server, and there's a nice separation here. And we
are used to thinking about front end and back end development separately because they have
different constraints, they are in different environments, they have different responsibilities. That's
a good thing, and so putting all these things together maybe is not the
best idea. So that was that's kind of the argument and the criticism with
the demo. So and you also mentioned that you used to work on PHP,
and I think it brought PHP back to a lot of people, and
not just PHP, but also ASP all these technologies that a lot of them
intentionally or unintentionally mixed data access to the data layer alongside within the UI generation
because you know, if you ignore for the for a minute, the fact
that maybe you're also doing some JavaScript on the client side when you're doing PHP,
you're actually constructing the UI. You know, it's all HTML templates,
and people have had very bad vibes from the concept of mixing together within the
same file the UI layer and also all the data access operations. Yeah,
so one way to think about that is if you go back to when React
first came out, a similar kind of criticism that was probably the most popular
one levied against it was that it broke the separation to concerns and these folks
had come from backgrounds where they worked on PHP apps with one big file and
everything mixed together. It was hard to maintain those applications, and so separating
it out made it easier to think about the views only respond for the view.
It passed the data through a controller layer, and then the controller was
narrow and sent the messages to the model layer. And so the model layer
was this clean business logic area and the view was separate from that. And
so that NBC architecture or whatever variation of it that the service side frameworks adopted,
helped with maintainability. But when React came out, it made the argument
that a lot of what we were doing with our front end code, especially
as we work writing more sophisticated front ends with richer client side interactivity that needed
access to data and needed to have logic and air handling and all this stuff,
is that putting these things in separate files based on the technology needed for
each part of the UI to work. So you have a jobscript file because
you need the jobscript behavior to respond to events. You need a CSS file
for the styling, and then you have your back and stuff to handle the
network requests. One of the reacts original arguments was that these things are all
related, and they're all needed for a piece of UI to work, and
the React component was a new abstraction that enabled this because you could put a
slice of the Java script, a slice of the CSS, a slice of
the HTML markup that you needed in a single file so that you're dropped down,
which had which required all three of those technologies for it to do everything
it needed to do, would be co located. And so separation of concerns
is a design principle that helps you organize code because one part of the code
doesn't concern or doesn't share concerns with another. But reacts argument was that these
all had the same concern They were all there in order to enable a drop
down to work, and therefore they are related, they should be, and
therefore the code should be co looking. And I think over time we've seen
that that has proven to be has proven to be good, and in particular,
the component as an abstraction has proved to help us organize this code that
used to be in a single PHP file. Let's say, because we have
the component and are able to break up our apps into components. The fact
that they have multiple technologies inside of them. HTML, jobscript, and CSS
is not a problem anymore because we have the component and we can define boundaries
based on actual concern. The dropdown doesn't have to be in the same file
as the header, even though both of those files have all three technologies.
So yeah, I was just going to jump in and say a lot of
people that I've talked to, when they talk about separation of concerns in some
of these same ways, they try and bring up the single responsibility principle from
solid and effectively say, yeah, so we don't want to mix all this
stuff together. But I've talked to Bob Martin actually quite a bit, and
when he talks about the single responsibility principle, it's you want to put the
code together that's likely to change together exactly and drop down and you're looking at
oh, we have to open the JavaScript. Oh, the JavaScript is adding
an event listener to document dot Query element by class. Boom. Okay,
let's go to the class or the HTML to find the element that has the
class, and then we need to update the style of that. So let's
go open the CSS file and find where that class is declared. If you're
opening three file m Yeah, then those should be together. So that's a
real simple way to think about it. So I agree with package structure.
I mean that's like the whole architecture of Go is that things are organized by
package by component, if you will. The problem that I have is that,
Okay, yes, the three files change together, but they need to
be edited by three different people. There needs to be the engineer that's editing
the JavaScript, and then there needs to be the you know, designer that's
editing the pixel information, and then there needs to be that crossover front end
person that's editing the CSS and the HTML. So that's that's where And I
think that trying to say, oh, a front end person whose primary concern
is adapting design is also supposed to be a JavaScript engineer, to me,
that just seems ludicrous, Like, what, what are the odds that someone
who is great at adapting design is going to really be a great programmer.
I think it's it's interesting because I think you just illustrated what is it,
Conway's law, where the structure of the code reflects the structure of the team.
And I do think that AJ is the issue that AJ had just highlighted
is a real significant concern I I and I've seen teams stumble with it,
like getting the design, the design into the components and whatnot. You know,
various solutions have come up along the way. First of all, if
you're using some sort of a design system, it kind of partially solves that
issue for you. And and you know, there are only certain components where
you really need to deal with with the details of the pixel placement, and
those are created once by like you know, joint teams. There's also to
an extent, tailwind exists to address UH and and and similar technologies or exists
to address UH such issues to an extent. But and we're now even seeing
AI being put to use in this context, you know, of taking designs
out of FIGMA and and translating them into JSX that you know, developers could
then embed within their components. But I totally agree that it's it's it's it's
a problem. But I'm not sure that it's a problem that that components,
you know, necessarily make worse than before. I mean, at the end
of the day, you still had that issue of HTML and JavaScript and CSS
needing to work together. Yeah, I think I've definitely heard of teams working
more along the ways that AJ mentioned. You know some people and there's there's
different expertise, right, someone who is an expert in CSS, you can't
be an expert in all three things because there's people whose whole careers are just
about HTML, the semantics of HML elements and all the attributes, you know,
and a generalist doesn't isn't going to know as much as they do.
But I think that those teams could still impose boundaries and maybe firewall off a
developer from making changes to the design side because that suited them. But those
boundaries should come from the organization and the coders and the designers, as opposed
to being artificially imposed by the technology. So just because we can write HTMLCSS
and JavaScript in the same file doesn't mean we have to. But if we
could, if we had to write them all in separate files, then we
could never write them together. And you know, someone who's starting out could
never just make that change all in a single file when it's you know,
for a lot of the parts that are simple, and they still change together.
So I think that the fact that the technologies were artificially imposing those constraints
on everyone was not the best way to come up with those boundaries. But
we still see people, we still see teams having boundaries today between designs.
For example, if you do have a design system of component library, you're
developers who are experts on the JavaScript side and doing the actual UI programming,
pull in the predesigned components from this design system, and those have a limited
public interface that the design team controls so that the developers, you know,
stay along with the brand and everything. So I think those boundaries can be
important and can still be created by the teams, but I think it's good
that they're they are derived from the team's needs and you know, instead of
imposed by the technology. I'm going to agree with you on this. I
think people don't talk about agile development anymore, but this was one of the
thing, one of the ideas that came out of some of the different agile
methodologies was that you know, you get together every so often and have a
retrospective where you talk about what's working for you and what's not. And at
that point, yeah, you can say, look, we're going to keep
using JSX because it solves these problems for us. We're going to adjust our
team structure or our team responsibilities or educate people who work with us or whatever
to handle the other piece, right, and so then yeah, maybe you
teach your designers, Look, this is how components go together, and so
if you need to adjust styles, you're going to have to look in one
of these places, right. But this is how we've structured the the the
components that have an area of control, and so it should be relatively easy
for you to figure out which component you're tweaking and then you can go and
edit js X. By the way, I wanted to say that for me,
the component model that you talked about works best in React when it's when
it's coupled with the unidirectional data flow. When when you're when when the data
flows properly, then components really work. When it doesn't, it becomes it
can become a hot mess. Mm hmm. Yeah. I think that's definitely
aligned with with the overall React philosophy. I mean, especially when it came
on the scene, it talked a lot. They talked a lot about one
way data flow because the prevailing frameworks at the time used two way bindings to
try to get a lot of things done. So you just drop an input
in, you bind into a model. You know, Ember was like this,
Angular was like this. By the way, do you remember that Back
when React came out, it actually had to weigh data band binding just to
be on par with the other frameworks. It kind of had that mechanism built
in, and then it kind of, you know, fell by the wayside
over the years. I don't remember that. Actually, what was the syntax
for that. I'm trying to remember. I'll find it. I'll try to
google it while while we talk about the other stuff. But yeah, actually
you could actually bind the field to a state. That was Angler's big selling
point. They were kind of the big dog before React, so I can
see why they did that. Yep, And you know that was it was.
It was nice that the framework was able to keep your UI and sync
with your state. But as it got more complex and I've got more complex,
and there was two way bindings happening in lots of places that were triggering
effects or other running other functions as a result of a change, it was
hard to follow. So one way data one way data flow, I think
is is a core principle of React. It's one of those like unwritten rules
that you really need to understand and follow. If you're going to be successful.
And interestingly, one way to think about server components and server actions is
that it's bringing that one way data flow to the whole app across the network.
That's actually how a lot of the core team has talked about it.
And so going back to the slide that you showed, so we talked about
like the two reasons that people were kind of I wouldn't say upset, Well
maybe some of the words triggered, that's the best word. So one,
like you said, this was escual injection, and we already spoke about why
that wasn't really a concern because it looks like a an SQL string, but
in actuality, it's actually a function call, so it can actually sanitize that
string before it actually uses it, and that overcomes that issue because it's a
templated string literal. But I think the bigger issue was the mixing of concerns,
and I think you know, people will say, okay, like like
you said, I'm encapsulating the relevant logic in the same component like this,
but how do I now overcome the fact that I've got my SQL code spread
all over the application and if I ever need to change anything in the structure
of you know, my data layer that I basically need to go throughout my
entire UI layer and fix it all up. Yeah, so kind of along
the same lines that we were talking about with with the React component first,
bringing HTML, CSS and JavaScript in the same file, you could kind of
make the same argument there. Well, if every React component can define a
new CSS rule and set a color, then we can just set a color
and that way, that means that our colors are going to be spread all
around. And so if we need to change a blue somewhere and we're using
this hex code, now we have to open up all of our React components
and change it there. But of course that's not what people do these days.
They have abstraction layers and boundaries based on what changes, and so if
every React component should use the same blue, then they reference it or import
it from a module or in a design system or as a CS that's variable
and the components reference that instead. So you know, libraries, frameworks,
teams come up with different boundaries for their abstractions based on what things change.
So that just because you can do have the full power of all technologies in
the file doesn't mean that's how people write applications, and so the SQL example
in my talk was because I was just using the simplest version to explain the
actual server action API. But in a real app, you would do something
that resembles how you would do it today, even if you weren't using server
actions, and if you had traditional API end points. If you looked at
your API end point handlers, whether they're a node or they're written in PHP
or Ruby, those things also are not going to be calling directly to SQL,
even though they can, right. They usually use a model layer like
Rails. You have active model, so your endpoints, your controller methods,
and a RAILS app are accessing the SQL database via the model layer via active
record. And again that's an abstraction point, so that your controller can say,
you know app dot user dot first name and first name can be a
method on your model derived or a full name. It can be derived from
your first name in last name. Feels the controllers aren't queering SQL directly and
doing all that work together. So these different abstraction points and boundaries can and
responsibilities. Right, that's the real single responsibility principle being applied. Because you
have an area for your business logic and so The way that would look here
is instead of just importing SQL and going directly to your database, you would
import you know, a dB module or a model layer like a Prisma.
You could import Prisma and call Prisma user create you know, or any other
O r M you use, or any business layer, or you could even
delegate to another service that's the HTP. So basically whatever you're doing with JS
uses Prisma that way. Yep. Basically, however, you're writing your API
end points today that your that your your SPA is already hitting. Whatever logic
is in there is just it's going to be the same exact logic that you
can now put inside of the component with the server action. So again,
it's not about saying it's not it's not about making an argument about where your
boundaries should or shouldn't be. It's about enabling the co location of code that
changes together in a way that we couldn't before. So and the way that
I like to think about it is basically saying that you know, at at
the at the leaf node, let's say, of the component tree, Uh,
you've got some client side interactive component and it captures some event and then
it invokes a function that was probably passed to it as a prop so it
effectively now bubbles up that interaction. Now, in the past, at some
point you needed to explicitly send that across the wire into somewhere which wasn't React
anymore. And now it bubbles all the way up to some component that actually
does access the data, and somewhere along the lines of that bubbling it crosses
the network divide. You don't necessarily need to think about it as explicitly as
you did before. It feels like it's functions all the way up. It's
just that at one point or another that function is an OURPC function that effectively
sent the data over the wire. But it feels like it looks and feels
like a regular function. Yeah, I think part of it is the is
the ergonomics, which is what you guys talked a lot about in the last
episode, because you can import a function and REACT can take care of serializing
the arguments across the wire and de serializing them and giving you type information about
that and errors as opposed to what we have to do today right, which
is just right fetch put in a string to a URL and then pass along
the data and the request body that's a very error prone process in a lot
of ways. If you were to give me a React SPA and ask me
to tell to show you all the ways that all of the user flows that
that SPA can make network requests, it would be hard. I'd have to
search for fetch or whatever abstraction around fetch exists. I'd have to look at
the URLs that are hit and the data that is collected, because data has
to be serialized across the wire, and everyone's kind of doing it their own
way. Whereas a nice benefit from server actions is that, especially because if
you're writing typescript, that they're traceable just like any other module is. So
if we were looking at your SPA and you were using radicks drop down,
you know, from Radix a UI library, and I asked you to find
all the places you're using that, we could just do that very easily because
we can just look at the module import graph. And so now you can
do that as well. For kind of like what you're saying, the RPC
calls have become first class modules in effect, and they take part in the
module graph. So that's a nice DX win and it just takes a lot
of the work off of our hands in terms of I think, in terms
of how we are going to go about serializing things. There's kind of a
standard now with form data and Action and React, and it just takes a
lot of the work off. But I don't think that that's the most important
part of this. I do not think it's about DX and it's not about
elimiting some of that boiler plane. It actually is about bringing those back end
pieces of functionality to inside of the component boundary. So and I took it
a step further and saying yes, it's part of the component boundary, and
it's also part of that uni directional data flow. It's it's the data flowing
from React server components down into client components as props, and it's events bubbling
up from client components to server side operations where the data is actually persisted as
function calls. Right yep. And you know, I think something you said
earlier is, you know, there's a lot of folks who have reacted spas,
and spas are nice because you can deploy them and they can make network
calls to any service, and those services can be written in any code because
it's server side code. So a lot of companies have React apps that are
talking to Python back ends and Ruby back ends and Php back ends. But
now React is moving in a direction where they want us to write our back
ends in JavaScript so that we can take advantage of things like server components and
server actions. And I actually don't think that's the right way to think about
this, because you don't need to write your entire services layer, your entire
service layer in JavaScript to take the advance to read the benefits of the of
the architecture. If you were deploying a front end, a React front end
has a drop down that when you click on it, it makes an API
request. It's true that that React app can run anywhere and you can just
deploy it, but if someone were to use that code, someone else on
the team use that code, the back end would have to be there as
well. So if you were to deploy that somewhere, the back end API
call that the front end makes has to also be there, right, It
has to be running. It's basically you can think of it as a dependency.
The front end has a dependency on the server side endpoints, and what
server components and server actions let you do is bundle the dependency so that if
I render a drop down and it needs to run some server side code.
It's going to come along for the ride. It's a way to bundle the
server side logic and code that needs to run just by rendering the component.
And I think that's the most important aspect of server components and server actions.
So what yours look? The reality is that what I'm seeing is that a
lot of organizations out there have not necessarily embraced JavaScript or type script as the
back end language. So in order so what you're, if I'm understanding correctly,
what you're saying, is you're saying, you know, you can keep
on using whatever programming language framework you like, but you will need some sort
of you know, be it next jes or or Redwood or something along these
lines as a kind of you know. The term I think these days is
b f F. It's like a back end for front end. We used
to call this thing middleware, but basically a translation layer on the server side
that is the endpoint for the RPC calls and and and translates that into action
access to various micro services written in whatever is that? Am I like?
Presenting what you said correctly? That is one that's one way you could you
could use it is to if you did have a running node server, then
you could have that kind of BFF model where your React components can interact with
other server side services at run time because you're running it. You can also
use them at build time, and we can talk about that. But I
think I think runtime is the more interesting, interesting idea, and maybe one
way to think about this is think about integrating something like Stripe Checkout into your
app. So let's just take Stripe right. It lets you charge your customers
money for your products. Let's say I have a PHP app. How do
I integrate Stripe with my PHP app that renders a React front end. Let's
say I have a create React app. Well, they're going to give me
like a Stripe Checkout React component that renders the front end, and then I
need to import and use their SDKs in my PHP app so that when my
React front end their component, their checkout component can talk to my pH server,
which can then interact with stripes APIs right because we put that kind of
logic web hooks and all the logic that needs to go between our trusted server
and Stripes as a service, right with all the secret keys there that needs
to run on our service. So point being, if you were going to
add strip checkout to your site, there's a client side component and a server
side component. Not there's a client side aspect and a server side aspect to
getting a full integration of full stack integration with a service like Stripe. And
the cool thing about server components and server actions is that you can imagine a
world where that Stripe checkout component can include the server side logic and now you
can just render it. It's going to do the same thing and talk to
your trusted server, but the logic for integrating it, the surface area of
that is much much smaller. Maybe you just give it an environment key and
it's on your trusted service. That's safe. But now the back and forth
communication, the airror handling, it's not left up to you to do that,
to make fetch calls or to wire up a new endpoint to do that.
They can bundle it inside and then, yes, if you have the
capability to run node at request time, you could do certain levels of this.
But even if you only could do it at build time, libraries could
ship a lot more of the logic by including that service side piece. So
that's kind of One way I think about this is that most librarries integrating with
services is a great use case for this, and today to integrate with a
service, we have to have a front end piece and a back end piece.
The front end piece is really easy to use because React now has all
the primitives on the client to let us do things like just render a stripe
checkout, and that Stripe checkout component. That React component is going to do
all sorts of things in our browser. Right. It can render drop downs
that the user can do used to choose their credit card. It can use
any browser API at wants to set up the UI. But React has all
the primitives needed or strike to be able to bundle those things inside of the
component boundary. Right because of use effect and use state, they can access
the entire array of browser APIs and encapsulate that within the component. But we
don't have a similar tool for the server. There's no way to encapsulate server
arbitrary service side code inside of a component. But now with server actions and
server components, there is so companies can companies, services, and even teams
can start to bundle that in the same easy to use component interface and way
to think about this is like it's a missing primitive that enables more powerful components
in the same way use effect and use state. We're missing primitives that have
enabled richer client components, bundle it and also compose it. One of the
things exactly I really liked in your talk, which I highly recommend people watch
if they haven't for some reason, is how you highlighted the fact that with
server components, before you even got into server actions, you highlighted the fact
that we're with server components, you can actually uh like uh, because they're
components, you can I'm gonna leave clients exactly, Yeah, compose them together.
Yes, exactly what we're looking for. Yeah, And that's another really
important point. I just don't have enough faith in humanity. I just don't
think that's smart. I just don't, you know, I don't don't think
people are that smart. But but they don't need but they don't now know,
they don't necessarily but they don't necessarily to be because if you if you
build a component interface correct, Stripe did the work and build their component appropriately,
and they should have the resources to do that. Then effectively you're just
dropping a Stripe component into your code and you don't need to know anything about
you know, what's what's it doing on the back end, what's it doing
on the front end, because it's self contained. That's the goal, that's
the dream. We are in an early stage. Obviously, this is a
new technology, so right now it's we don't have technology. It's PHP.
Like it's literally PHP. It's the exactly and thing we're gonna and we're gonna
have we're gonna render this, and we're gonna render that, and we're gonna
have some of the we're gonna have some of the server code in there,
and we're gonna have some of the client code in there. Like yeah,
but with PHP you were Yeah, but with PHP you were wearing But that's
like the whole thing of object oriented like with PHP or you were wearing your
underwear on the outside in the sense that the the the the the all the
interface that connected to the front end part which was self contained to the back
end through your your own code was all out there in the open, you
know, all the end points, all the code that did the translation and
stuff like that was not encapsulated. It was, yeah, this is what
you can't do with PHP. You can't render something that fetches data a list
of countries. Let's say you're doing a drop down you need to show all
the countries, and the list of countries comes from your database. You render
something that is a country list, and then inside of that you render a
drop down component from a UI library like Radix, and you pass the countries
from the country's component into the dropdown, and now you have a UI that
is driven by dynamic data. But Radix is doing a dropdown that renders a
portal and has virtual scrolling and keyboard shortcuts. So the way those things compose
together is the novel aspect of this, and the way I think about what
it will enable in the future is the same way I think about how React
enabled libraries UI libraries like Radix to exist today. Because when React first came
out, if you needed to render a dialogue, you might have to render
the dialogue right here, but then in the root of your app you might
have to do something like, oh, we need a separate div, right,
we need a separate div outside of our tree, because when we render
the dialogue, it can't be inside of the content. It has to kind
of portal out so that it lays on top of it. So there was
two steps to rendering a dialogue. You could you could render it, but
then when it was open somehow you had to tell the route that it was
open. And then you had to hook into this sibling div that was outside
of our application so that the dialogue showed on top. Then React came out
with portals. Portals solve that problem. So today if you install a dialogue
component from a library like Radix or Reaction to the HTML portal spec, well,
where where is it? Where did that come from? I frames,
well, oh, is that a news spec that's coming or yes? Yes,
So it's unfortunate that they called it portals because there actually is a thing
called portals that basically it's but it's is it is? It's Is it still
a thing? I think the whole portal thing was kind of deprecated somewhere along
the way. I'm not sure that they're coming up with it, but with
paskeys it probably won't matter because I think the primary use case of portals would
have been single sign on and I think past are going but I think we
digressed. Yeah, anyway, I'm just saying that it's not no relation to
the portal spec. Okay, talking about related got What I'm saying is there's
already a thing in HTML called a portal. We're not talking portals, okay,
got you. So there's a feature in React called portals, and basically
every UI framework has something like this now that does let you render a div
elsewhere in the tree if you need to render it outside the tree of where
you currently are. Right, if you're toggling something and you show and hide
a paragraph and it moves the page, that's like what you want. That's
fine. But for things like drop downs and dialogues, you want those to
be able to render outside the current tree, so that that UI element is
on top conceptually in the z index and it doesn't interfere with that. It
sits on top of the existing content, right, And so there used to
be a step to do that. So if I was an author of React
modal library, I would say to use my modial library. First render capital
M modal and put your content in there, but then also come here and
render you know, modal root alongside your body tag, so that when the
modal renders, it behaves like a well behaved modal. It renders on top
and it doesn't none of the other contents of your page obscures it. But
then React added portals is a feature to the library. It was a missing
primitive which let which let you move that logic inside the component boundary. And
so today if you install something like Radix or React Aria or headless UI,
you get to render a modal wherever you want and behind the scenes, within
that component boundary, it's going to set up a portal, it's going to
set up context, it's going to set up effects that add keyboard listeners.
All of the features of those UI components are contained in the modal in the
component boundary, and using those components is the easiest part of working with React
to day because you get to just render them their declarative they take props and
you can conditionally render them in JSX. It's like the most base. It's
just like rendering HTML elements, right because that's what it's based off of.
The contain all this functionality, all the browser API is that they need inside
of that component interface. That makes them easier to use. So exactly like
Dan was saying, you can imagine a world where a CMS like contentful gives
you an you know, a text field component and text field you can say
what's a prop. The prop the model name is user and the idea is
one two three. It's coming from the URL and that's it. You just
drop that into your app and now it's going to be able to read the
data from contentful on the server side. It'll populate it as you type and
make changes. You could hit save and hitting save is going to run a
server action that's bundled inside of the component by contentful and makes a right back
to your CMS. And you didn't have to do that. One two step
integration where to use contentful, you know text field. First, import the
React component, add it to your front end, and second, create a
new at API endpoint and integrate with our SDK on your server. Because all
of it can be bundled in the component boundary, and it respects the data
flow from your reactory, it can trigger rerenders, it can pass a draft
version of the content to other React components. That's the composition story that we
never had in PHP, and that's the goal of what these new primitives enable.
So I've got two concerns. I'll start with the first one. The
first one is the and I mentioned these concerns by the way, in that
episode when we spoke about r PC, my first concern is the proliferation of
endpoints or APIs like in the old days, because creating APIs was so explicit.
We were very intentional about creating those API end points, and you know,
we tried to minimize their number simply because they were not that easy to
create. Uh. And we, you know, we, if we were
doing things right, we use let's say, RESTful APIs or maybe graphic you
well, but let's stick with RESTful APIs, and we modeled them according to
the structure of our data. And and you know, we use them that
way. These days, you know, an API is you know, as
easy as creating a function. Uh. So it's likely that we're going to
have a ton of internal APIs within our application and they are going to be
wholly distinct from you know, the external APIs that we create. So maybe
nobody is actually checking that the external API still properly work because we're not using
them anymore. Uh. And that's that, you know, that kind of
scares me, This this cavalier approach to endpoint creation. Yeah, I've I
think I would kind of take the same thinking as when we were talking about
how react originally brought HTML, CSS and JavaScript into the same file. Just
because that enabled you to write any thing you wanted in a single file doesn't
mean that that's what people end up doing, and they end up creating abstractions
and boundaries for things like you know, design tokens for CSS so that we're
not just writing CSS rules from crats in every component. I think it's reacts
job to enable that low level colocation, and it's a frameworks job to impose
healthy conventions and constraints. And the same way that Ruby is a programming language
and you should be able to do anything you want with it, but you
can can't do anything you want in Ruby on rails, or if you try,
you're going to have a really bad time. So Ruby on Rails has
guidelines and conventions that you follow that keep you on the happy path, that
keep your app easy to maintain. You know, skinny skinny controllers fat models
is a popular one right, Well, you know, it's kind of a
best practice in rails apps to keep your controllers skinny. So if you have
controller methods and they have a ton of logic, they check your user logged
in and if there's permissions, and then they check if there's database entries,
and you open up your controller method and it has all this logic that maybe
really belongs in the model there, and you're missing like a new abstraction there.
And you know, RAILS and DHH has done a really good job creating
these conventions and guidelines to help people build maintainable applications. I think of React
as a programming language for us, and I think of server actions and server
components in the same way I think of feature client features like use effect and
portals and context. They're primitives that enable kind of higher level abstractions, but
they were missing pieces in the programming language. And now frameworks like Next and
Remix can impose conventions and constraints for what developers need to do most of the
time. And that's going to look like you know, maybe that looks like
not going willy nilly and having you know, low level server actions anywhere,
but instead you have something like what Remix has, which is, let's give
each route a loader and an action. So now if you want to know
which pages in your application talk to the network, you just know you look
in the routees file and you just see a loader or an action, and
you also know as a developer, every time I define a loader or an
action, I need to secure it because that's an endpoint that's exposed to the
public Internet. And that's what Remix developers know. And there's there's also you
know, linters and guidelines in Remix that help you remember that. So I
think the kinds of framework level app level concerns you're talking about, things like
security and maintainability, I think those are the jobs for the frameworks, and
I think people who are building an app with React should be using a framework
for the same reason I think people who are building an app with Ruby should
be using a framework like Rails and not starting from scratch with Ruby. I
agree with everything you said, I do think that I'm not sure frameworks can
take us all the way. I think that best practices will need to evolve
beyond what frameworks can and should enforce, like maybe pulling the like we said
we talked. I talked about the fact that you know, the events bubble
up and now with the with sever actions they cross the wire somewhere along the
way. Maybe you want to pull that point higher up within the component tree,
like to the highest snow that still has the appropriate context. So that
you kind of minimize the number of these kind of crossing points that you have.
But I guess basically what remix does remix hoists the actions and loaders to
the route level. So if you want to know how your React app is
interacting with the network, you only have to look at the route file.
You don't you don't have to worry about leave components deep down. Yeah,
I totally get it. I actually think that reacts over components are intentionally not
that uh and and the stripe and the stripe example that you got that you
gave before is a perfect example because you know you can have the stripe component
dropped in within the page and and then you know the router doesn't need to
know anything about it. Yep, that's true. So it is true that
if you are in a world of server components and server actions, part of
the whole point is that any component can interact with the network's that's part of
the benefit is that they're encapsulated inside of a component. And so yes,
you could drop a stripe check out deep in the tree and now it's making
a net requests that you don't that you didn't maybe intention like you didn't opt
in too intentionally, I guess, but I still think there's a way for
frameworks to kind of solve this problem. I see the possibility to create that
Stripe component as something that React is trying to solve, and now we have
the primitives for that to exist. And then the question of how best do
we use these new powerful full stack components in a way that doesn't expose our
apps to new security risks or keeps our apps maintained. That's going to be
something that we figure out and that we get advice from with frameworks and different
opinions. All I'm saying really is that it does make a lot of sense
to tie the communication to the router in many cases because at the end of
the day, in a lot of cases, it is the navigation that's all
about changing your state. But as we say, as you know, that
Stripe example shows that's not always the case. It's not just the case.
So it's a very powerful model, but it shouldn't be the exclusive model.
Yeah, and it's it's also not the exclusive one because another primitive that has
recently come to react to suspense and suspense is all about coordinating things like data
requests so you can drop in your Stripe checkout component, and let's say it
has to load data first before actually charging someone, like just to render.
It requires data, It requires the current user, It requires your catalog of
products and the prices. So you just drop that in and you say,
well, isn't that bad because my route already loads this other data. Now
I'm dropping in a Stripe component deep down in my tree and it's going to
do its own data fetching. How does that all work? This is where
suspense comes in. Suspense lets the whole tree of components tell the parent,
Hey, I'm not ready yet, and so I have this network request or
this one. You can hoist them, but basically suspense lets you keep those
at a choke point but still have the logic inside the component boundary so that
you do get to do things like if a frameworks to decide we only want
to load data on URL change, they can do that without breaking the encapsulation
of the fact that the Stripe checkout component knows what it needs from Stripe.
I just know that it needs to rent to load data, but I don't
know how it gets that they can do that for me. Don't want and
you don't want to be blocked on. It is the most important aspect I
think at the end of the day. Well, sometimes you might sometimes you
might want to block on getting every data loading component to fetch its data before
it renders. Sometimes it might be below the fold and you want to let
it render lazily with the loading spinner. And again suspense is the answer.
That's the primitive that lets you have control over that. But but you still
get the benefit of having the component have its own logic inside of the component
boundary. So one point that I did want to mention is like another as
a final point on my end. That's kind of related to RPC, which
we've also brought up in that discussion. It wasn't a problem when RPC existed
back in the in the in those days in the nineties, and it's and
it's also a problem with with quote unquote RPC here within server actions as far
as I can tell. And that's versiony that you're tying the version of your
clients to your server. Now you might I think, hey, that's not
a problem. I mean, you know, it's everything part of that single
next JS app which I deploy as a whole. But you're not thinking about
the situation where somebody keeps a client up and running while you're let's say,
updating the server version. So you can get even if it's like all a
part of that single app, you can get into version mismatches between the client
and server fairly easily with long living client side web apps. Yes, and
that's a problem. That's a problem that's existed, I guess, you know
since since we started doing long lipped client development. Right, if you have
a route split create React app and uh, you only load the first page,
the person leaves it open for a day or two, and then they
navigate, maybe they get a different version of the next chunk, or that
chunk references a different version of something because there's been a deploy since then and
they haven't refreshed. So I think that this this comes up a lot with
long lived clients. But I think either React or next has some built in
stuff. I think React has some built in stuff to kind of fingerprint the
version of the server action that a particular client component may have gotten referenced to.
I'd have to look more into that, but yeah, but that's definitely
something. But then like API versioning on your rails app or PHPI exactly.
It's like that, Yeah, you're using V one in your path instead of
V two in your path. Yeah. But like when you're doing RESTful APIs,
you're cognizant of that. You're very explicit about it, you know,
and you can make sure to maintain backward compatibility at least one version back it's
pretty straightforward when you're doing everything with RPC and it's intentionally made to look like
a function called you know, you've added a parameter in the next version and
it's suddenly incompatible. So yeah, I do know that there's I'd have to
look I don't know, if the top of my head. I know that
they have some solution to this, and I think they've thought about it,
but I don't know off the top of my head what it is, but
I think it's Yeah, I'd have to look more into it, but that's
definitely something. The good The good news here though, is that between the
cookie banner and the subscribe banner and the did you want more content banner,
the people are probably never going to get to your site, so they'll probably
never notice there. You go, all right, well, if we're going
there's just one more thing, it's just one more thing in the list of
things we're gonna go wrong on your site. Yeah, all right, I'm
gonna push just to picks, uh Sam, if people want to follow you
or check out build u I, what are all the links U r ls,
et cetera. Yeah. Buildjoy dot com is our our site with our
our courses. We've got a tailwind course, We've got a React Server Components
course, and remix course. We really love building a remix and Frame of
Motion which is a cool animation library, and this week we're putting out one
on Radix, which is a UI component library, so nice. If you're
into that, you can check that out. We have a newsletter buildow dot
com slash Newsletter. It's a nice way to keep up with what we're doing.
And then I'm on Twitter, so Sam's hellicof on Twitter. Awesome?
All right, Well, let's go ahead and do our picks. Then we'll
put all those links in the show notes and if you drop them in the
little chat over here, we'll make sure they also wind up in the comments.
AJ, what are your picks? So? Had I had some last
week that I didn't Well? First, okay, so first and foremost,
I'm going to pick this no back end. There was a movement called no
back end that started, I don't know, one hundred years ago, something
like that, twenty seventeen maybe, and I don't think that it has any
chance of succeeding. But it's kind of the idea of if you just created
standards for common actions, then you could have components for the back end.
I mean essentially kind of what we're saying, but it would be API.
It would just be a well standardized API, so that on your front end
you didn't have to be aware of the back end. So same kind of
effect. You'd be able to install a component for front end back end for
lots of different things. And the person who put the site together has examples
of like user accounts, generic data storage, emails, permission sharing, file
conversion, payments, et cetera. Well, the only other one on there
was make coffee or tea, but that's kind of a joke because of the
the HTTP four nineteen. I am not a teapot. But anyway, so
that that idea I really like. The reason that I say it'll never take
hold is in comparison to this like RSD type thing, is that our entire
foundation of the Internet is built on money that doesn't exist. It's low interest
rate loans from the Federal Reserve that get pumped into investor money that get pumped
into businesses that don't ever need to have a thought about being profitable that you
know, the only thing that they need to do is to grow. And
as long as we have that, the proprietary nature of creating a payment's API
that only works with one provider is going to always trump over having a payment's
API that any provider could use, because you're not trying to get profitability and
then compete in a free market. You're trying to take advantage of government regulation
and investor you know, hot potato to just create businesses that have growth and
you want to trap in you know, this one little niche thing like what
Stripe is done. You know, it's funny people Stripe in particular, like
they have way better documentation and way prettier pictures on their website. Other than
that, huh oh. Other than that, they kind of look like the
other you know, fifteen different options that you can choose from, and it's
like you put a credit card, you pass it like it's not anyway.
So, but I like this idea, this is This would be my dream
is that we use protocols rather than companies h and that it's a free and
open market where the company that can provide the best is the one that wins,
rather than the one that is able to use invest your money to create
advertising hype to you know, create a proprietary API for something that should be
relatively simple and open, like messaging or file storage or whatever. But old
man yelling at Cloud's clouds aside, there were a couple of things that I
had to pick. One was Home Assistant, which I just mentioned last time
because we were really running low on time. But Home Assistant is, you
know, it's also a bittersweet that it works at all, is what's really
cool about it is definitely not end user friendly whatsoever. But if you are,
you know, an it guy or a programmer, you can probably get
it set up and get it working. And it doesn't really matter whether you
buy the box where it's pre installed or not. It's it's basically like Apple
Home Kit or Google Assistant or Alexa Home. It's it's that type of software,
and in fact, it integrates with those things as well, so it
can piggyback on those If you happen to buy a device that doesn't have a
way to have a local API or zigb or z wave or any of the
standards that have existed for you know, home assistance and smart home stuff before
you know, the Google Assistant type of things kicked off. But anyway,
I was, I was able to get it working. I got it wasn't
it was. It took me a few hours to get my thermostat set up
on a schedule, which is not I mean, I guess it would take
that long if I just bought a thermostat at lows and then press the buttons
on it going through the schedule menu thing. But anyway, it's it.
It works like you can have cameras. I've got a camera connected to it
that's using en viv, which is the open video standard for security cameras.
I've got a thermostat via z Wave. I'm going to get a power device
via Zigbie, and I think that that's probably going to be as easy to
detect as z way. But it's all event based, and the problem is
that it's like there's no modules for you know, here's your thermostat module.
Everything is if this, then that style, So your thermostat has an event
like temperature change that it fires off, and something can listen for that,
and you can have a schedule system like a calendar for example, and say,
okay, like nine am is an event, and what should the event
do. Well, the event should trigger the thermostat to be set to seventy
two degrees or you know that sort of thing. So wiring it up is
very tedious, but at the end of the day, it works at all,
which is better than the alternative of not having any way to do any
sort of smart automation in your home without having Google and Amazon listening to every
conversation that you have and knowing when your lights are on and what your power
bill is likely to be and all that stuff that you know can just kind
of feel creepy. So I'll pick Home Assistant. There's there's a couple of
different sites. One is a Marriadroid, another is cloud Free, and those
are sites that particularly sell things that are known to be compatible with Home Assistant,
and probably some of the other ones like habitat and whatnot, And then
a lot of the stuff you can get on Amazon, but it's very difficult
to do any sort of search on Amazon and actually know whether or not the
thing is actually going to be compatible, whereas if you use a Marriadroid or
cloud Free. I mean it's you know, they're selling all of these DIY
smart devices. You know that they're already pre flashed with the right firmware,
or they're already you know, they're already kind of set up so that you
can start using them in your home with the different sensors and relays and whatnot.
One of the things I'm going to do is get my garage door opener
so that I can open it and I don't have to worry about you know,
some data leak happening, and then you know, anybody that gets the
Amazon database being able to open my garage door or something like that. So
yeah, it kind of a love hate relationship at this point. Love that
it is allowing me to do things I couldn't otherwise do. Hate that it
is extremely geared towards people that want to edit Yamel files and do if this,
then that's just have a module for the thermostat or the garage door or
you know whatever, like so, do you have a Docker container for your
thermostat? So it does that, it does that automatically that's how it works.
So you install Home Assistant. Hom assistant boots up the Docker container.
So there probably is a Docker container for the z wave module. I don't
know exactly how it does it. I just put it in a virtual machine
and then pass through the USB device to the virtual machine and let it do
its thing. And it's working, and I have it segmented, so I
have a separate network in my home that's an IoT network where any of the
home devices like our laptops and phones can access the IoT network, but the
IoT network can't go back and access anything else. So it's it's like even
if I buy some weird device that has hacked firmware on it, I'm relatively
safe. Now. Obviously that's not something the average person is going to do,
and even as a programmer, you're not going to have any idea how
to do that. But the thing is, one day, one day,
it'd be nice if we did have a box that could just do the stuff
that's just plug and play. And some people have got to deal with this
iteration of technology in order for us to get to that iteration of technology.
And then one other thing that I will pick today is chaos walking. I
did I mention that I watched the movie. I don't know. If I
mentioned I watched the movie. Books are good, it is okay, Yeah,
the books are good, and the movie was. You despaired on the
quality of the movie. It's just it's a completely different story that happens to
have a few of the same characters. So if you for anybody that watched
Jurassic Park two and read Jurassic Park two, it's like it's the same kind
of thing, Like, completely different story. A couple of the same characters,
have the same names, and a couple of the same catchphrases. But
other than the first thirty seconds of the movie, which is exactly the same
as the book, a boy walking through the woods talking to himself, from
that point forward, it's just a completely different story that has a few of
similar motifs in it, you know, like Jurassic Park two was a completely
different story, but it was also a story about dinosaurs. So that that's
what I have to say about it. So, yes, if you did
not like the movie of Chaos Walking, I highly encourage you. But you
like the premise, like the trailer was interesting, the movie was terrible.
Take a look at the books because the books have a coherent story and uh
and it's really good and compelling and it is nothing like the movie other than
there is a Mayor Prentice and there is a viola, and there is a
Todd Hewett and they and they have noise. So that's those will be my
picks for the for the day. All right, Dan, what are your
picks? Okay? So my first pick is going to be a series that
I'm currently watching on Netflix which is amazing, and it's called Blue Eye Samurai
And if you've not watched it, you need to watch it now. It's
an adult show, so there's some nudity and some sex and lots and lots
of violence, but the artwork is amazing, the storytelling is excellent. I'm
really enjoying it, so I highly recommend it. And it reminded me of
another excellent story show about samurais which has a which is surprisingly which is really
different but in some ways surprisingly similar, which is that old show Samurai Jack
from you know, like originally like twenty something years ago and then with a
few more episodes twelve years after that, which is also highly recommended if you
can find it. But like I said, it's like a totally different character
of show. It's mostly intended for like it's it's effectively, you know,
a show for kids, but it's one of those shows for kids that adults
enjoy more. But Blue Eye Samurai is definitely a show for adults, not
for kids. So cool. Yeah, I highly recommend it. So those
would be my pick for today. All Right, my picks are going to
be a little bit heavy. So sam why don't you go ahead and go
first? I was going to say Lessons in Chemistry. A bunch of people
were recommending it to me. It's an Apple TV Plus show and it's really
great. It's like a timepiece in the fifties, I guess, and that's
about uh, chemistry and cooking, and it's just really well made. So
I've been enjoying that. Cool. We started watching it and then we let
our Apple TV subscription, you know, and we and we didn't renew because
I just, you know, I can't abide by the fact that, you
know, you pay for a subscription, but then you also need to pay
for the movies that you want to watch, so you know, it's kind
of annoying. Well, the other thing is is I think, are we
quit paying our cable bill way back when when it was like a hundred bucks.
But I think we're already halfway to there with all of our stream services,
and so yeah, unless there's something really compelling to keep you there,
you know, just pick the ones that have most of the stuff you want.
Anyway, So I'm gonna get a little bit heavy. I'm gonna get
a little bit personal as well, and I feel like I just want to
talk about this for a minute, mostly so that if there's somebody in your
life that you can help out, that you can do it. And if
my talking about self harm or suicide will bother you, then turn off the
episode at this point. So, right before Christmas, my brother, he's
thirty two, attempted to end his life and he he bought himself a pistol
and he wound up. He put the gun to his temple, but when
he pulled the trigger, his hand moved forward and he shot his eyes instead
of his brain. And so you know, we still have him here,
is essentially what I'm saying. We kind of I got lucky in that sense,
but he's blind now, and so a lot of the things that I've
been talking about releasing, I haven't released because I've been dealing with family stuff
for the last month that all said. What I really want to put forward
is I've talked to so I'm involved in several other things, right, and
so I've had to explain to some people in other areas, hey, look,
this is what's going on, and so this is why I've been in
the place that I have been and why i haven't done everything that I wanted
to do for you. And you know, everybody's been very understanding. But
the thing that really surprised me was that a lot of people basically said,
my son or my brother, or my parent or my family member, my
friend attempt at suicide and and so it's I'm finding that it's something that touches
a lot more people than I thought. And you know, you kind of
hear the statistics, but it never really hit home to me as much that
you know, a lot of the people that I talked to have had experience
with a friend or family member who has tried to end their life. And
so a couple of things that I just want to put forward is, first
of all, you know, my brother and I, I mean, we
didn't have a bad relationship. We just didn't really ever talk all that often,
and he was kind of a loner, and so you know, that
kind of happened. But for one, if you haven't talked to somebody in
a while, if you have a relationship with ship with somebody where you feel
like or wish that it could be better, I mean, even if there's
history there, right, because sometimes that's the way it is. Just take
a minute and reach out and let them know. And then the other thing
is is that what I'm finding. I actually went and talked to a therapist
last week, you know, after i'd kind of got I set it up
when I was really suffering and then you know, I had kind of gotten
through most of my anger and frustration and things like that, which is why
I haven't talked about it to this point because it's just been really hard for
me to think through and deal with. But I'm feeling a lot better now
about things and you know, just working toward how I can help him out.
But a lot of people have that hole in their life, right and
I'm not going to tell you how you feel it. I also haven't been
that low in my life where I felt like I, you know, wanted
to hurt myself. I also have a number of friends who have addiction issues,
and they they tend to fill that same kind of hole with with some
kind of an addiction, whether it's drugs or pornography or something else. But
just realize that a lot of people out there really are suffering and they're going
through a lot of things, and you need to figure out if you're feeling
that hole, how to fill it. And for me, I feel it
with my family and my faith and things like that, you know, and
if you can't figure out how to feel it, then go talk to somebody,
Go talk to a professional. The other thing is is that if you
have a friend or family member that goes through something like this, just realizes
that if affects you too, and that if you need help, you should
also go talk to a professional, or go find a church leader or somebody
that you can confide in and find that help. Because I can tell you
I have a couple of really close friends. We get together every Wednesday night
and play board games. And we played board games basically the week after and
and just talked and it helped so much. Right, And they're not professionals,
and they weren't telling me, oh, you should really do whatever,
Right, but yeah, if you're experiencing this kind of anger or frustration because
somebody did something, you know, whether it was personally directed at you or
you're just angry that you know they did something like what my brother did,
go find somebody to talk to and go find that help. Humans are social
creatures. We need that human interaction. But I totally agree with what you
said that you know, find somebody to talk to. But if you really
need professional help, then you know, go for it. Don't don't you
know, don't assume that just talking to a friend is a sufficient substitute,
right exactly. So, I mean, I don't know if I'm giving any
specific or concrete way of knowing where you're at some of the stuff, and
a lot of times it's really hard to figure out, and you know,
one day is great and the other the next day it's not. But just
just be aware and you know, look out for other people, the people
you care about in your life, and look out for yourself. I think
that's all I really have to say about this, But it's just kind of
been it's it's something that I've really wanted to just tell people to just think
about. All right, we'll go ahead and wrap it up there. Sorry
to get all deep and thanks for sharing man. I'm sorry you're going through
that. That's rough. Yeah, I appreciate you sharing man. That's you
be thinking about your family for sure. Yeah. Thanks. All right,
well we'll wrap it up here. Till next time, folks, Max out h