Dan:
Hello, everybody, and welcome to another episode of JavaScript Jabber, your favorite JavaScript podcast. Today, I'm the one and only host and panelist, Dan Shapir, coming to you from Tel Aviv in Israel. And our guest is a returning guest. Always fun to have him on. It's Austin Gill. Hi, Austin.
Austin Gil:
Hello, Dan, good to see you again.
Dan:
So for those of you who don't know who Austin is, Austin, can you introduce yourself, please?
Austin Gil:
Yeah, I am a developer advocate for a company called Akamai. We do CDN, web application firewall, edge compute, all cloud computing services you would want, databases, object storage, BPSs. It's great, everything now.
Dan:
Yeah, you do lots of stuff at Akamai. I know a couple of people at Akamai. All of them great people.
Austin Gil:
Yeah, that's great. I personally work as, yeah, I'm a developer advocate, but I spend, I don't know, I spend most of my time on developer education. So just teaching
Dan:
Hmm.
Austin Gil:
developers where sometimes there's overlap with products that we offer, but oftentimes like in today's discussion, there probably won't be very much and that's okay. We just want to make sure that people are learning how to build the best websites possible.
Dan:
So you're being paid to engage with developers and teach developers.
Austin Gil:
I suppose so, yes.
Dan:
Fun
Austin Gil:
It's
Dan:
job.
Austin Gil:
a pretty good gig, yeah.
Dan:
Yeah, good gig if you can get it. And today we're going to talk about several topics, but the one that we're going to start with, I guess, is CSS in JS because it's kind of going to be the catalyst I gather for the entire discussion.
Austin Gil:
Yeah, I would even take a step back and just talk about sort of the CSS landscape in general and how it has evolved and some solutions have arisen in the JavaScript world.
Dan:
I think that's a great topic. I
Austin Gil:
Yeah.
Dan:
think many, if not most JavaScript developers do not know enough CSS or even are afraid of it. So anything that can be done to alleviate that fear and get the developers using CSS more correctly or better is a good thing. So go for it.
Austin Gil:
Okay. Yeah. So I guess it starts, it helps to start with a little bit of a timeline, at least from my experience. When I started, people were linking to CSS files from their projects and you basically had to come up with your own sort of solution to managing the challenge of working with CSS and the nature of its cascade and specificity and how do you grow that across a larger project and Eventually we had frameworks come in like Bootstrap or Foundation that would sort of provide these recipes or components, you might think of them, where you follow a little bit of a strict markup and class naming convention, and then they have provided the styles for you and that would apply to your webpage. And that was all well and good, except that then you would ship an entire Bootstrap file for a project that you may only be using a few parts of. And that,
Dan:
If I
Austin Gil:
sure.
Dan:
can interrupt you for one second, I do think it's worthwhile to touch on that point that you mentioned, which is specificity. Because probably most of our listeners are aware of this, but just in case, the key thing to remember about CSS is that by definition, unless, you know, otherwise specified or structured, it's global. That is, every CSS rule can impact effectively any element in the page. Whereas most developers when they're using frameworks want to use components these days and have certain stylistic choices as being global, like maybe light mode versus dark mode, but very often they want a lot of CSS rules to be encapsulated, I guess, within a specific component. Right? And that kind of goes against the whole concept of CSS as being cascading and global. And that's what I guess is what you mean by specificity.
Austin Gil:
Yeah, we're in kind of an interesting struggle right now between the way that CSS has worked for decades and was designed to work, and the way that the web is sort of shifting in the direction of more component-driven design or component-driven construction. And yeah, the global nature of CSS doesn't always lend itself well to component-specific design. So... Uh, it's interesting because then, yeah, the, the specificity thing led to challenges with, uh, modifying and customizing, uh, your own version or creating bespoke, uh, websites on top of these frameworks like bootstrap. And maybe you get into specificity battles where you want to override something and you end up putting important on the end of everything. And it's just like
Dan:
Yeah.
Austin Gil:
a big pain in the butt. Right. So, uh, sort of an, uh, next phase was introduced by, um, there were some. Well, maybe not the next phase, but another branch is the branch of atomic CSS, which has been around for a long time with a CSS, I think was one of the first ones. And then there was, um, tacky ons was another example, but I think it didn't really gain a lot of popularity until tail end. So I think in this discussion, there's probably some, uh, you know, comparing pros and cons. of libraries and I'll probably be speaking to Tailwind as an example, because it has a lot of great pros. It also has some cons and I don't want that to be reflective of how I picture the library or the tool as a whole, but just because we're having a discussion of some of
Dan:
Mm-hmm
Austin Gil:
the things about it, I may say some things that the things
Dan:
be
Austin Gil:
that
Dan:
spicy
Austin Gil:
I don't really like
Dan:
all
Austin Gil:
about
Dan:
you want.
Austin Gil:
it. Yeah.
Dan:
This is the podcast to be spicy on
Austin Gil:
Well, we'll see. Some of it will be truth or some of it will be truths and some of it will be opinions.
Dan:
Yeah, for sure.
Austin Gil:
Um, so anyway, we have atomic CSS and the whole, the whole pitch of atomic CSS is rather than having something that's like a button class that has 10 different property or CSS rules on it, you would have classes that correspond to individual rules, so they don't really have semantic meaning, they just have names like P five is like padding of, I don't know, five pixels or some, some arbitrary value. Um, And then you end up composing your button component together using all of these individual classes. So this has really lent itself well to component-driven development, because you can basically compose all of your styles at a component level and then use that as an abstraction layer so that people aren't dealing with just a spaghetti code of different class names, but they're working with individual components.
Dan:
So
Austin Gil:
Um.
Dan:
I have a question and a comment about this, or maybe two questions really. First, just to make sure that I understand what you're saying, is that if you're looking at a library like Tailwind, then all the CSS class names are global, but
Austin Gil:
Yes.
Dan:
the way that you compose them together is on a per-component basis.
Austin Gil:
Yeah, I mean, if you're working with components, yes. But really, you can think of it as composing classes on a per element basis where needed.
Dan:
Yeah.
Austin Gil:
So where in a previous life, you would have added a class name to an element and then added all of your styles to that class name, now you're basically just composing several class names on that element. And none of them have any sort of semantic meaning of what the element actually represents. but they do apply their classes. And because all of Tailwind classes are, or Atomic CSS classes are just a single class name, it's a relatively low specificity. So you're only dealing with the cascading nature of it rather than fighting over rules being overly specific.
Dan:
So the obvious question that I have whenever I think about something like tailwind is, what's the benefit of this approach over just inline styles? I mean at the end of the day, why is it better to add a class called P5 than simply having an inline style of padding five?
Austin Gil:
Yeah, that's a good question. I think that the biggest benefit is that you can put all of your styles end up in a CSS file somewhere, which can then be cached, where to some degree, having inline styles may be faster for things that are above the fold or what is loaded and visible when the page first loads. That's going to be faster than having to download a CSS file.
Dan:
No, but I mean,
Austin Gil:
But
Dan:
with inline style, what I mean by inline style is just instead of having a class attribute on the specific element saying class equals p5, why don't I have a style attribute on the element saying style equals padding 5? What's the benefit like just? The fact that I have the letter P instead of the entire word padding, you know, what's the upside here?
Austin Gil:
Yeah, so part of it is potentially the cache ability of a CSS file that you don't have to write quite so much into your markup. But then there's also considerations to make around specificity where inline styles are going to be more specific and may clash. Of course, presumably if you're writing inline styles, that's what you want on that element. But I would also say that inline styles don't have access to things like pseudo elements, pseudo classes, media queries. So you still need to write CSS to be able to
Dan:
Oh,
Austin Gil:
target those
Dan:
so
Austin Gil:
sorts
Dan:
basically
Austin Gil:
of things.
Dan:
what you're saying is that even though the attribute is called P5, in reality it might actually mean more than just padding 5, it might be some sort of padding that is also dependent on some sort of media query. So the name might be simple and imply a very simple concept that I could... that seems like an alias to a simple inline style, but in reality it might either mean or be adjusted to mean something more sophisticated.
Austin Gil:
Yeah, it could. It could be something like a complex rule, like a transition that has timing and names and other different things. You could have, I mean, especially with CSS variables, you could have a class that really just toggles a value of a CSS variable, which you could also do with inline styles.
Dan:
So it's basically like people looked at CSS and said, oh, we wish we could have done it differently. And hey, they use class name to do it slightly differently. And that's Tailwind.
Austin Gil:
Yeah, kind of. I would say that the biggest benefit or one of the large benefits actually that is lost on inline styles is that Tailend, any Atomic CSS library provides an idea. It's like a rudimentary version of design tokens. Or, yeah. So it provides a limited scope of available values to choose from, which
Dan:
Hmm.
Austin Gil:
can really help developers that either aren't very good at design or aren't part of the design team, stick to a limited set of constraints where just a blank CSS rule
Dan:
OK.
Austin Gil:
can have literally an infinite number of options,
Dan:
Yeah,
Austin Gil:
right?
Dan:
that makes a lot of sense. That they kind of, first of all, only have the p value. Again, going back to the padding example, they might have a p11 and p9, but not a p10. And
Austin Gil:
That's correct.
Dan:
also, they would guide you towards using certain class names together. Uh, and, and not just, you know, throw any CSS rule that, you know, that basically crosses your mind or something.
Austin Gil:
Yeah, or even managing units, like preferring rems over pixels or something.
Dan:
Yeah, so you don't need to think about the units, they do it for
Austin Gil:
Yeah.
Dan:
you.
Austin Gil:
And doing that makes for a more consistent, coherent look across an application, which coherency is an underrated sort of design hack.
Dan:
It's also
Austin Gil:
Just like,
Dan:
an underrated programming hack.
Austin Gil:
yeah, just consistent spacing and colors looks great. So that's, and I think the sort of big benefit to Atomic CSS, the reason why I want to focus on it as a good thing is Yeah, those design token things, I mean, Tailwind, I think, did particularly a good job of shipping with what they call sane defaults or good-looking default values, particularly around colors and fonts and stuff and spacing. But the big benefit around the Atomic CSS concept as a whole is that because you are your CSS for that, the CSS rules for those corresponding class names once in your entire application. So as your application grows, it sort of follows a, what is it, a logarithmic growth curve that eventually flattens out to align. Whereas if you rely on writing new class names for every single new component or every single new page that's added to the system, you end up having more of a linear growth curve that over time produces a much larger output than like an atomic version. And you also run into the problem where you can't modify certain class names because you don't know where they're being used.
Dan:
Oh
Austin Gil:
You
Dan:
yeah.
Austin Gil:
don't keep track of everywhere that they're being used. So making a change can break something somewhere else. And then you end up with the append only style sheet because you can't remove unused code because you don't know everywhere that it's being used.
Dan:
Yeah, that's one of the issues with CSS, obviously, that it's really scary to remove stuff out of CSS. I mean, certain tools, they help you, but they only really look at the state of the HTML at the load of the page. And if the HTML changes, while the application is running, it can be really challenging to verify that a certain style doesn't get used somewhere. So you're absolutely correct that you remove a style and then all of a sudden your styling breaks and it's really bad.
Austin Gil:
Yeah, it's hard to track down where.
Dan:
Exactly. And also, and just another comment that if people think that the problem with the ever-growing CSS is a large download, that's not really the issue in most cases. From my experience, the bigger issue is that just having lots of CSS rules in and of itself is a significant overhead on the browser because the browser needs to compute and apply all these CSS rules and if there are a lot of CSS rules and the page is complex in terms of the size and structure of the DOM and usually these two go together, then it's... can be quite computationally intensive for the browser to deal with it.
Austin Gil:
Yeah. The interesting thing with, um, I guess the arguments against something like Tailwind is that you end up shipping smaller CSS bundles, but that complex, you're really just shifting complexity because you're moving those, those same styles need to be applied to different elements, but you're moving it from being in the CSS file to now in the HTML as you're composing those classes. And I think that the counter argument to that is that You know, Gzip is really good about minifying and speeding up delivery of the HTML document if it's seeing a lot of this repeated code. I don't have a practical example of like a real world application that sort of went from CSS to Tailwind and showed what the difference
Dan:
Yeah,
Austin Gil:
was.
Dan:
I think it's more about really shifting complexity. Again, I'm not so much concerned about the size of the download, to be honest. I'm more concerned about the computational complexity for the browser, and even more so for the management complexity for the developers. So
Austin Gil:
Mm-hmm.
Dan:
you're really shifting the coalescing of common rules from the CSS into JavaScript. because you're basically relying that if you need similar styles for certain things, then there'll be common components in the JavaScript code. Because otherwise, if you've got two totally distinct components that you need to keep their style aligned, but you're not using a common CSS rule or class in order to define it, then it can become a maintenance headache. So you need to. Make sure that you shift this common code, as it were, into a shared JavaScript component.
Austin Gil:
Yeah, well, even that becomes really a challenge with Tailwind. Like, the most basic solution is, OK, we have a button. We want to make it border radius and a little bit of padding in purple. And you just throw those classes onto the button component. But then what happens when, in one case, you want to have a button with a red background? So now you have the Tailwind class for background purple on the component itself. maybe you implement some sort of logic that injects other classes at the implementation level where you implement the button, you can add another class name as a property and then that gets appended to the end of the button. Well, that's fine for anything that isn't already defined with the existing classes, but now when you have a clash of saying the original button has background purple and now we wanna add a class of background red, how do you do that? Or how does... Specifically, how does that work with Tailwind? And the answer is it just kind of tosses his hands up in the air because you can have a background purple class and a background red class both on the same element, right? That's valid HTML or class names, right? But then the question is, how does Tailwind decide who wins between background purple and background red?
Dan:
The last one,
Austin Gil:
And...
Dan:
isn't it? I mean cascading.
Austin Gil:
Well, and that is the tricky answer because in the HTML, maybe background purple comes first and then background red. And so you might assume it's background red, but HTML doesn't dictate the cascade of the CSS. The cascade of the CSS is determined by where in these actual generated CSS style sheet that background purple class is defined and the background red class. So it could be that in HTML, Background first, background purple comes first, and then background red, but in the CSS, background red is defined first, and then background purple. So the winner would be still purple in this case. Does that make sense, or was that?
Dan:
No, it makes sense. I'm just
Austin Gil:
Okay.
Dan:
trying to remember if that's how I picture that it behaved. I always assumed, I think, that if you had two classes assigned to the same element, and then the second one overrides the first one regardless of the order in which the classes were defined in the CSS. But you're saying that that's not the case.
Austin Gil:
No, because this comes back to just like fundamentally how the web works. If you have a CSS file and
Dan:
Hmm
Austin Gil:
you have two classes defined, it's for the same element and they have the same specificity, it is the latter one that is going to apply. So the way that Tailwind figures this out is essentially, it used to be that it would like do a build time step and generate your entire CSS file for you. And now what it does is sort of more on a dynamic approach, that it only creates the CSS that it sees in your project. So as you add class names in your project, it will start constructing the CSS file for you. So really it depends in the order that the Tailend transpiler walks through your project and finds those class names. If it comes across background purple first, that will be the first one in the style sheet. And then later on, if it comes and discovers background red, that will be appended after background purple.
Dan:
That sounds like a big mess.
Austin Gil:
It's something that there's a better solution here, or I guess there's solutions that we've come across which are like, well, you just have to provide some sort of runtime logic or maybe a build time logic, but some sort of JavaScript logic that says, in this case, instead of having both of these class names, have some sort of logic that can turn one off and turn one on so that you never come into the case where both exist. in the actual generated class names.
Dan:
So again, it's basically shifting logic from
Austin Gil:
Yeah
Dan:
the CSS, from the cascading mechanism
Austin Gil:
Yes.
Dan:
into let's say React codes that generates the appropriate virtual DOM or JSX.
Austin Gil:
Yeah. So that's kind of as far as I wanna go with the Tailwind introduction.
Dan:
Mm-hmm.
Austin Gil:
I wanna get into another branch of CSS authoring practices which is CSS and JS. So this was kind of nice because it allows you to... Well, it allows you to reuse knowledge that you may already have. So we call this transferable knowledge. Like if you come into a project and you know CSS, you don't have to look at the documentation to write for how to write or accomplish what you want in a CSS in JS solution. You just start writing CSS and that's what you have available. And that's where I think Tailwind is close, but not quite on. They did some naming conventions that are not at all. related to the CSS spec, like letting and kerning. And basically for their design tokens, they have to come up with what they want to call the property or what the class name should, what the class name that corresponds to different properties has to be. So there's always someone making the decision on what to call these things
Dan:
So just to
Austin Gil:
and
Dan:
make
Austin Gil:
you have
Dan:
sure
Austin Gil:
to learn
Dan:
that
Austin Gil:
it.
Dan:
I'm understanding what you're referring to, so for example, I know that in Svelte, for example, when you define a Svelte component, you can specify the CSS for that component inside the Svelte file. And that component and that CSS, while it looks like regular CSS, is, by definition, the way that the Svelte compiler processes it is encapsulated or scoped, would be a better term, for that component. Is that kind of what you're talking about?
Austin Gil:
So that is Scope CSS. That is not what I would call CSS in JS. Scope CSS is exactly what you're describing, where you have some sort of authoring experience to write styles that are associated with a component. It might be some sort of tooling, but there's frameworks like Vue and Svelte that have a way of just writing essentially in a style block. The CSS that corresponds with just this component. And then there's a transpilation step, which we're going to get to. Uh, but the translation step, basically as it's building out this component, uh, it generates a custom class name. That's like machine understandable, just totally random garbled text to create a class name that corresponds with that one component, and then it takes the CSS that was associated with that and puts that into a static file that is then part of like just the static assets when you, when you ship your code. So it's slightly different. CSS and JS, I believe, is generally implemented as a runtime solution. So it's not transpiled away. It's not sort of built and then removed at build time. It actually runs when your application is running.
Dan:
So it's basically
Austin Gil:
And...
Dan:
embedding effectively. So it might be, let's say, using an import statement, but to import CSS instead of JavaScript. And then the bundler effectively transforms it into a big string that it embeds in the bundle that it generates. Is that what you're talking about then?
Austin Gil:
No, so that would still be like the scoped CSS solution. So CSS and JS, there's different libraries and different implementations, but I think what they eventually do is, let's say when you use a component that has this CSS and JS implementation, it doesn't get compiled away, that runtime. What that runtime does is it will actually append a style sheet to the page with the CSS for that component as that component's being used. So it's probably following some sort of singleton pattern when this component is used, add this style sheet or style block to the page, and then only do that once each time the component is sort of used.
Dan:
But again, the fact that it's called CSS in JS is because rather than working with independent CSS files or SAS files or whatever, the CSS itself is handed over to the bundler as it were as part of the build process.
Austin Gil:
Yes, yes. Yeah, and it has some interesting use cases, but I think a lot of the arguments against CSS and JS specifically is the dependency on runtime, on runtime code. Like we're starting to see, or we've been seeing for a while, a pushback against a lot of client-side code because it adds a lot of unnecessary overhead, not just like you said in... download times, but specifically around runtime code, the concern is around how much client side resources it's using to
Dan:
So let
Austin Gil:
accomplish
Dan:
me ask
Austin Gil:
things.
Dan:
it from a reverse perspective.
Austin Gil:
Mm-hmm.
Dan:
What's the upside of sticking the CSS into the JS? Why do it in the first place?
Austin Gil:
I, well, I'm probably not the best person to ask because I never quite got on board with it. But I would say a lot of the benefit or a lot of the draw was around the authoring experience. So being able to co-locate your styles with your markup is really nice because that has sort of automated dead code elimination when you either modify the styles on that. component or just stop importing the component altogether. Yeah, that's probably what I would say. I mean, there's, there's a lot of benefits as well with the runtime code where you can do sort of the logic that we described with Tailwind. One of the challenges of having like conditional style or conditional CSS styles, um, CSS and JS solutions, because they run in the runtime code, it's a lot easier to apply this sort of dynamic runtime based logic to say whether. the color of a button should be red or purple based on the props that it receives. And especially if you need those props to be something that's defined at runtime, then it's not even something that's possible at build time.
Dan:
So, if I'm understanding correctly, basically in the same sense that React put HTML inside the JavaScript files, you know, thanks to the concept of JSX, so basically if JavaScript is eating web development, so if we put the HTML into... the JS files and it's a good thing, why not also put the CSS into the JS files because that must be a good thing as well. And then we can kind of have like this everything that's related to the components look, functionality and behavior being encapsulated in a single file or please folder, something like that.
Austin Gil:
Yeah, yeah, and I think that, I mean, you know, everything in moderation, right? But generally, I think that it's a good thing. It's at least good to have the option.
Dan:
I'm guessing that, and it's a guess, that maybe one additional concern, at least back in the day, was the fact that the CSS download is render blocking. And putting it into the JavaScript means that I can load CSS without blocking, but it'll be there when I need it, because the JavaScript that's used to put the relevant HTML into the page, you know, is also
Austin Gil:
Mm.
Dan:
the JavaScript that also includes that CSS that it needs when it puts that HTML into the page.
Austin Gil:
Yeah, so some sort of performance or like perceived performance sort of thing. especially in like a spa.
Dan:
No, it's actual performance because again, it's avoiding downloading render blocking CSS when you don't actually need to block for that particular CSS, but the browser can't know.
Austin Gil:
Yeah, in like a spa setup, that would make a lot of sense. If you have to render, if you're doing server-side rendering, you would still want that CSS
Dan:
Yeah,
Austin Gil:
to be available.
Dan:
I understand what you're saying. So basically I'm in a spa, I'm going to the second page, I'm downloading some additional component code for components that are used on the second page that weren't used on the first page. I download their code, I'm also downloading the styles that they will need because it's all bundled together. Okay,
Austin Gil:
Yeah.
Dan:
I get that.
Austin Gil:
So yeah, and that's interesting. And so I kind of, so as I said, I've never been much of a fan of the CSS and JS solution, particularly because I was really anti JavaScript as a means of delivering CSS. I think the browser does it. I just think, I don't know, the browser does a really good job and has done a really good job of receiving a CSS file, caching it, being able to parse it quickly. download it and not have to add more JavaScript as code that needs to be parsed during the runtime and during user interactions. So I never really got on board with that, although I did see some of the benefits, particularly around authoring and co-location of styles and sort of the maintenance, and also the fact that I know CSS and I want to be able to bring that knowledge and the fact that... Well, I'll get to this. actually in a moment. But then I did try Tailwind and I like a lot of things about Tailwind. I think I've used it in several projects because I haven't had anything better to go for. Again, I don't want to speak disparagingly about the project. I think that they do an excellent job but I think that I have very particular intentions and goals. So I love the fact that there's this... design token language to choose from, right? Limited amount of choice, very coherent styles, everything is consistent, that's great. But I never liked the fact that every time I had to look up something that I knew how to do in CSS, I had to go to the documentation in Tailwind, and I just could never remember it all. They've gotten better with VS Code having sort of some CSS IntelliSense or some packages or things like that. And at the time that I was really using it, they didn't have the sort of syntax where you could add just arbitrary CSS values to the rules.
Dan:
Mm-hmm.
Austin Gil:
That's like a new syntax that's been pretty cool. But the fact is that I wanted to sort of have a little bit of both. So for years, I had been sitting on my hands, knowing what I wanted and not actually having it. So eventually I said, you know what, let me go for it. I wanna create a library that has the benefits of atomic CSS with the authoring styles of CSS and JS
Dan:
Thanks for watching!
Austin Gil:
so that then I can come with my own like design tokens, my knowledge, my transferable knowledge of CSS, be able to write what I want and have all of those benefits in one place, co-location with my components, but then have a step that takes that function execution, that CSS and JS function declaration. and basically replaces it with just the list of class name, atomic class names. And at the same time, sort of in the background builds my CSS file for me.
Dan:
And that
Austin Gil:
So.
Dan:
ladies and gentlemen is how open source projects get created or born.
Austin Gil:
Yeah,
Dan:
Somebody
Austin Gil:
so
Dan:
has
Austin Gil:
let me
Dan:
an
Austin Gil:
see.
Dan:
itch!
Austin Gil:
Yeah, it's, it was funny because eventually, yeah, just got to the point, it was like, no, it's a good idea. Someone's going to build it though. Like we're close, we're, we're really around it as a, as a, as a community, someone's going to do it. And in fact, someone, someone had done it. There's a couple of authors that had pursued something similar and, and accomplished some things, but still none of them were quite what I was looking for. So again, I'm just being very picky. But the idea is that when you can write things this way, you can, well, with CSS and JS, you can kind of get like TypeScript benefits where you can author a library that has a type definition that can help people write their styles using both what is available in CSS, but then also maybe providing some sort of configuration file that has these sort of design tokens. and have the nice experience where as I'm typing, I'm being recommended which of the available design tokens I can choose from for sizing or color or fonts or things like that. There was a really funny sort of, I don't think this is how you should be using TypeScript, but I'm going to use it that way anyway in building this project, because I guess let me take a step back. The project is, and even a step back further, don't use this project. We'll get to the end of the story. We'll get to the end of the story where I basically was, I built it, I got it working, I was dogfooding it, and then the developer experience is terrible, and I'll explain why. So it started as this, basically I want to author in my JavaScript files and I wanna remove that code, right? So inherently right there I have to have a transpiler
Dan:
Yes.
Austin Gil:
because you have to do code, no, take this code and replace it with something else.
Dan:
Yeah, going back to
Austin Gil:
Uh...
Dan:
the Svelte example that I gave a while back, you're taking CSS rules or classes or whatever that are injected into that you as a developer write in the JavaScript itself. But because you want to have it not be dependent on JavaScript at runtime, on JavaScript load and JavaScript execution, you actually need to move it into a separate CSS file that the browser can just load. that requires effort from, let's say the bundler or the builder or the transpiler, whatever you want to call it to
Austin Gil:
Yes.
Dan:
take, extract that code out and stick it somewhere, transform it a bit maybe, and then stick it somewhere else.
Austin Gil:
Yeah. So, so the way that works is, um, when you have a transpiler, there's a, there's a number of different options to choose from these days, sort of the far and away winner is VEET, which itself is not really a transpiler, but more of like a, a build tool
Dan:
It's
Austin Gil:
sort
Dan:
a
Austin Gil:
of framework.
Dan:
rapper to, yes, build or something, isn't it?
Austin Gil:
Yeah.
Dan:
And
Austin Gil:
So
Dan:
others,
Austin Gil:
it,
Dan:
and other things.
Austin Gil:
yeah. So it wraps ES build for, uh, for the production build and I think it wraps roll up.
Dan:
for
Austin Gil:
I think
Dan:
the development,
Austin Gil:
roll up is the,
Dan:
yeah.
Austin Gil:
yeah, during development. And that's so that, or one way or the other, but yeah, essentially at development, you wanna be using ES modules in the browser because those are faster to reload instead of having to build the whole thing. But then for production, ES modules are still not quite the right solution for most projects.
Dan:
It's because
Austin Gil:
Like we...
Dan:
you might end up with way too many tiny files.
Austin Gil:
Yes, and a weird waterfall of network requests for
Dan:
Yeah,
Austin Gil:
dependencies,
Dan:
yeah, exactly.
Austin Gil:
or circular dependencies, or something like that. So anyway, yeah, so it uses Rollup under the hood. And that led me into the journey of learning what the heck a transpiler is, and how to write a plugin for these things. And it was a surprisingly painful process for someone that had never done it before. But I think it's incredibly valuable. And that's sort of been the big takeaway of this whole journey is I want to get the word out there and teach people what transpilers are and how they work because I think that they're basically, they're like magic for your source code. They can take your entire code and transform it into something completely else. So.
Dan:
Yeah, and they're definitely all the rage these days.
Austin Gil:
Yeah. And I think that there is some interesting discussion around moving away from build tooling and JavaScript these days, you can have a pretty interesting development process with components and you know, certain nice CSS features and just like ship the actual code that you write instead of having to go through a build step. But I don't think we're, I don't think I'm ever going to step away from a build process. for a lot of different reasons. But anyway, so you get this transpiler, you write a plugin for it, right? So in this case, you write a plugin that's compatible with Rollup that will work with V as well. And the way that I wrote this plugin to work is, essentially a transpiler, what it will do is it will walk through every single file in your... code base starting from a specific file. So you start at like a root JavaScript file and it will walk through all of the things that it imports and all the things that those import and allow you to tap into different places in that file based on what the code looks like. So in order for it to know how to do that or do it efficiently, it will generate an AST, an abstract syntax tree, which is a whole other completely different world that application developers never need to learn about. But what is it, platform developers? The people that work on like build tools or whatever. That is like very relevant.
Dan:
Yeah, you can kind of think of it in a way if it helps some of our listeners. Like if you've got HTML in the DOM as a tree of objects that represent a DOM, then you can think about an AST as a sort of an object tree that represents your source code. And then you can do transformations on it effectively. So you can... transform your code into, you can inspect your code, see what's, you can traverse your code, inspect your code, and then modify your code, and then generate code from that modified AST. And effectively, like, as you said, modify the code that you originally had. So it's kind of a way to do transformations on your code that at build time, like you said, for example, in order to extract certain things out of the code and move it somewhere else.
Austin Gil:
Yeah. And it's pretty fascinating. I would say if you've never seen what an AST looks like, it's like mouth blogging it on a podcast. It is not the best format. So I would encourage people to go to ASTexplorer.net. And this provides you with, on the left side, somewhere that you can write a JavaScript application. And on the right side, it shows you the actual generated JSON or tree representation of that thing. So like... const a equals hello world will literally generate 34 lines of JSON sort of nested JSON things that explain, you know, that the entire thing is a program and inside of which it has a variable declaration inside of that there's a variable declarator, which is the name of the variable and then the value of the variable and then the type of variable it is. And it's fascinating. It seems like a whole bunch of stuff that you don't would never need. And in general, you don't need that information unless you need to do some uh, translation or transpilation. And then all of these things become very interesting because what a transpiler will do is allow you to take an AST of your entire application and then write what's called commonly referred to as a walker or a program. It's like the plugin that basically walks through the code, but instead of walking through every single line of that entire AST for your whole project, or for every file in your whole project, it allows you to also hook into just very specific things. So if you only wanna hook into every time that, let's say in the Svelte compiler, that the let keyword is used. Svelte does something kind of funny with let. It doesn't use,
Dan:
Kind
Austin Gil:
it
Dan:
of
Austin Gil:
doesn't
Dan:
funny.
Austin Gil:
do, it doesn't, yeah.
Dan:
An understatement.
Austin Gil:
So it doesn't, yeah. So it doesn't do, it doesn't behave the way a vanilla JavaScript let
Dan:
Yeah,
Austin Gil:
works, right? And
Dan:
it's reactive.
Austin Gil:
so what the compiler has to do is basically find every instance in your entire code base that you use let to define a variable and then replace that with its own sort of reactivity system. So that's amazing if you think about it, how that works. So that was all very fascinating, but the hardest lesson, all right, is it any, should we move on to the lessons there or?
Dan:
Yeah, go
Austin Gil:
We good
Dan:
for
Austin Gil:
with,
Dan:
it.
Austin Gil:
yeah, okay. So that was all very fascinating. I was able to write a plugin that would basically find, so I wrote, the way that Particle CSS works is it provides you with a function called CSS inside of which you can put in an object style notation. You can use string style notation for like your CSS rules, right? So the first challenge is I need to be able to, I need to be able to, look at my source code, find all of the instances where this CSS function is being used, and then parse the value of that into to generate just a string, replace the function execution with just the string of class names, right?
Dan:
Yeah, in a way, it kind of, again, if I'm going to use a bit of an analogy, it's a bit similar to what happens again with JSX, because JSX seems to be translated into a series of function calls, but since these function calls generate effectively JavaScript objects, you might think of an optimization that just replaces those function calls with the actual resulting JavaScript objects that you can... uh you know figure out at build time so basically what you're saying is you have something in the code that looks like a function and that function seems to be returning a string but since that string can be known at build time then why do we need to have that function call in place we can just in the resulting output just have embed the resulting string and be done with it
Austin Gil:
Exactly. So that is essentially how the plugin works. It walks through your code. It finds all of these instances that's being executed. It replaces them with the static value. And at the same time that it replaces them, it takes whatever properties you wrote and actually creates the corresponding CSS in a different file somewhere. So it generates the CSS for you. And that's all interesting, but it creates... a lot of challenges, first of which is not everyone likes to use the same name for that function that it was imported with. So you can rename imports when you
Dan:
Mm-hmm.
Austin Gil:
use them, right? So my library exports a function called CSS, but if you want to do something different, you might say import CSS as style or style or vacation, whatever, you know?
Dan:
Yeah.
Austin Gil:
So, so as as a transpiler or plugin author, you have to add some logic that says, okay, Mr. AST, Mr. Transpiler, I want you not just to find when my CSS function is called, but I want you to find where it's imported because we also might as well get rid of the import statement.
Dan:
Yeah, for sure.
Austin Gil:
And when you find that import statement, is it doing any sort of renaming? In that case, we're no longer looking for a function called CSS, we're looking for a function called, you know, fill in the blank.
Dan:
Yeah, it's interesting because I'm thinking, for example, about what, let's say, quick does where it has the
Austin Gil:
Mm-hmm.
Dan:
server dollar and then all those other types of, you know, everything component dollar and, and stuff like that. Uh, and, uh, and to be honest, I don't know what they do if, if somebody tries to rename those, if, if it just breaks or they can deal with it. It's an interesting question.
Austin Gil:
Yeah, I imagine, I mean, you can get it to work. I was able to, it's just, part of this story is around the CSS, the nature of CSS these days, and part of it is here is what my journey looked like and some of the stumbling blocks and things to consider if you wanna go this way.
Dan:
But
Austin Gil:
So.
Dan:
by the way, so quick and also bling intentionally decided to just put dollar at the end of those things. And so I'm assuming that, you know, their treatment of names is much more strict. Let's put it this way.
Austin Gil:
Yeah, I think that's an important distinction that they chose because you really want to call out when you're doing something funny, that the compiler
Dan:
Yeah.
Austin Gil:
is doing something funny. And it's not going to work the way that the code looks. It's basically going to be rewritten.
Dan:
Yes, for sure.
Austin Gil:
I did some work with Solid and it's sort of the same thing.
Dan:
Yeah,
Austin Gil:
They have
Dan:
bling.
Austin Gil:
a server thing. And essentially what they do is they take one function execution that represents your server code. And they replace that with part of the section that needs to go in the client and part of the section that needs to go in a completely different file away from where the component is.
Dan:
Yeah, it's
Austin Gil:
That's
Dan:
integrated
Austin Gil:
like the server
Dan:
into the bundler.
Austin Gil:
endpoint.
Dan:
Yeah, exactly.
Austin Gil:
It's fascinating. But
Dan:
So
Austin Gil:
yeah,
Dan:
you were
Austin Gil:
so
Dan:
doing a
Austin Gil:
this,
Dan:
similar thing basically.
Austin Gil:
yes. And this is where we get to the part of the story that everything sort of caught on fire and fell apart because then I got it working, right? In theory, where we are in this conversation, the code is working, it's building the CSS, it's replacing the stuff, the function executions with just static strings. Great, love it. Except when you get to that same button example that we had before, where you have some border radius, some padding, and maybe two different buttons, one's purple and one's red. So you say, okay, let's create an object that has all of the shared properties for both buttons, font size, whatever. And then let's take that object in a variable and then call the CSS function and destructure the value of that object and only then add background purple for one and background red for the other. So now what you're doing is picture a JavaScript file where you say const shared styles equals object, couple of properties on it, and then Later on, you reference that variable. Very, very basic. One of the first things you learn how to do in JavaScript. Variable into a function. take that into a transpiler and it's incredibly difficult to do. Because now the transpiler is giving you a look at your code as an AST, not as a runtime where you have access to the variables that are alive and present in the file.
Dan:
Basically what you're saying is that in for this to really work perfectly What you kind of want to do is effectively run some of the JavaScript at build time or transpile
Austin Gil:
Yes.
Dan:
time and be able to kind of share data across both these separate run times like you know an object might be created at build time transformed at build time, but by code that executes at build time, gets to some sort of final state, and that final state is the start state for the runtime.
Austin Gil:
Exactly. And it's really, really difficult because the AST will tell you the exact line that your target expression was found on in the source code. So when I'm when I'm executing the CSS function with a reference to that variable, the transpiler will tell me, yeah, it's on this line. And this is what it was called with. It was called with variable styles. But then there's no way to ask the transpiler, well, what is the value of styles? It's like, I don't know, it's just a string basically.
Dan:
It's the name of the variable. That's all you get.
Austin Gil:
Yeah, that's all you get. So you can then take the name of the variable and walk the AST and find the reference of it in the same file and then grab the from, the first line to the end line of that variable. And then you can use something like, what is it that they tell us never to use in JavaScript? uh, where you,
Dan:
There's
Austin Gil:
where you
Dan:
so many
Austin Gil:
execute,
Dan:
things.
Austin Gil:
where you execute
Dan:
Evil,
Austin Gil:
it, you, you take us
Dan:
evil.
Austin Gil:
eval. Yes. Which spoiler spoiler, I did use eval to get my code to run, but I think it's fine in a build tool. Um, but anyway, you could take this. It's again, not an object representation. It's a string of an object and you could JSON parse it or eval it or something. But then the sort of boss mode. or like the final boss of this transpilation nightmare comes, which is what happens if that variable is not defined in the same file, but it's actually imported from a different file. Now you have a variable defining your styles in one file, being imported into this file that we're working on and being used in your CSS file. It's, I don't know, it's an impossibility to figure that out, if you ask me.
Dan:
Well,
Austin Gil:
So.
Dan:
it's interesting. There are some programming languages that kind of take this in stride, like Lisp has its own macros concept and stuff like that. So code that modifies code. But I, but I agree that it's much more of a challenge in something in JavaScript or TypeScript or whatever.
Austin Gil:
Yeah, so I spoke with Daniel Rowe from the Nux team who had basically mentioned that you could potentially have some sort of sandbox that does... What is it? It... It tracks the code that the transpiler is looking at and analyzes it as runtime code. And I think that you had mentioned something before we started recording.
Dan:
Yeah, so something like a month ago, or actually less, like a few weeks ago, Manu, one of the main developers working on QUIC over at Builder.io, announced that he got something like bun-styled macros working in Vite. So effectively, he's really talking about something really similar to what you're doing. And indeed, he says, and I quoting him here, that this will have huge impact for all kinds of new libraries, particularly styling ones like Panda, CSS. So yeah, it's really similar to your intention. So I've seen this post by Manu, but I've not played with it yet. So I have no idea. about the capabilities and limitations of what he's done. All I know is that he's a really smart guy.
Austin Gil:
Yeah. Well, so that's it's funny that you mentioned Panda CSS, because that was actually going to be maybe the next thing that I mentioned, or at least what I was going to shout out at the end of the show, because the state of particle CSS is I basically gave up on it, I hit that roadblock and said, and I, you know, implemented a lot of great features had a lot of cool learning experiences, but ultimately, I wasn't going to get over the transpilation step. of potentially shared styles that are imported from different files. No, I'm not, I'm not that guy. I'm not smart enough. Uh, but, uh, I did come across this project, Panda CSS, which, uh, is very similar. So they, uh, Sage is the, the sort of developer behind chakra UI and now Panda CSS, and I was able to, between the time that we, uh, scheduled this call and. are recording it today. I discovered Panda CSS and was able to have a call with him and like talk over, you know, the architecture and the future of it. And we went down this path of talking about transpilers and the challenges here. And I was like, somehow in Panda CSS, they were able to figure
Dan:
Thanks
Austin Gil:
out this
Dan:
for watching!
Austin Gil:
problem. And they did it by avoiding transpilers actually. So they ship a little runtime code. But instead of the sort of CSS and JS approach of taking the code and injecting it onto the page. They sort of do some build time code generation and then the runtime only does the styles to static class name generation. It's pretty fascinating. I haven't dug into it enough, but so far I'm really enjoying it. And they provide some really cool solutions around not just the atomic CSS thing and the CSS and JS thing, but providing something that I think would also make CSS purists a bit happier where you can define recipes
Dan:
Hmm.
Austin Gil:
and patterns that would correspond to, think of like a class name, like a button class name that has all of the different rules for a button. except you're not relying on an abstraction like a component level abstraction. And you're also not relying on it living within just a CSS file somewhere. So I don't know if I've explained that clearly enough, but there's a lot of benefit there in that you're not relying on a component level abstraction, which we've seen in the JavaScript world can have performance implications. where you have a lot of
Dan:
Yeah.
Austin Gil:
components just for like just a lot of wrapper components for nothing. And yeah, it provides a way to sort of retain or regain that sort of semantic meaning of what these styles are, while at the same time still offering the benefits of atomic CSS.
Dan:
So basically what you're saying is that we should be looking at Panda CSS.
Austin Gil:
Yes, I would encourage it. I am not affiliated in any way except that I had a meeting with Sage and was a big fan and now I'm trying to promote it. But
Dan:
Interesting, I'll
Austin Gil:
doing,
Dan:
definitely give it a look.
Austin Gil:
yeah. Yeah, I've been enjoying it. I think it's not quite as straightforward or quick at prototyping things as just Tailwind is because with Tailwind you start writing your. markup and then you're just right there with the class names, very easy to get going. Um, but you can drop in, you know, you can, I guess the, the barrier there is you have to import a CSS function and then you can just start writing your CSS in place of class names.
Dan:
Cool. Yeah, by the way, which framework are you currently using it with?
Austin Gil:
Uh, so I am using it in a project with quick, uh, just getting started with a, my next sort of teaching series and giving these two ago. Uh, I've tried quick a couple of times and hit some stumbling blocks, but I'm, I'm giving it another go. And I find, I think I finally got my head wrapped around, uh, what I needed to. So it's not, not so much
Dan:
Ha ha.
Austin Gil:
the library as much as the, the author or the developer.
Dan:
Yeah, we've had, by the way, we've had Mishko on our show twice, and we're actually scheduled with him to bring me on a third time. And I actually got to meet him in person, like a few weeks ago when he visited Israel. So we went out together. It was really fun to, you know, chat about tech and about life. He's a great guy.
Austin Gil:
Oh yeah, he seems incredibly intelligent.
Dan:
Yeah, very outgoing. So before we wrap up and move on to PICS, because we are now we're in, is there anything else that you would like to cover in the context of the stuff that we were talking about?
Austin Gil:
I think we covered a lot and it was kind of a full journey. So hopefully that, I mean, short answer, no.
Dan:
Hahaha!
Austin Gil:
I hope that people learn stuff and I hope that people that are curious and want to scratch that itch of wanting to do something that you can't do with just JavaScript would look into transpilers and be encouraged to and hopefully also like learn some things and some potholes that you won't be able to do.
Dan:
Yeah, for sure. I think that the advent of transpilers and compilers is like the new horizon or the next horizon in front-end development. I think all of the frameworks are embracing compilation or transpilation in some form or another. Even React, which for the has the core team is working on react for get as their own compiler. So it will be really interesting when we get to this point in time where all frameworks have their own compiler.
Austin Gil:
Yeah, I think the future of the front end developer is... going away because there's just, well, there's just so much
Dan:
AI will
Austin Gil:
that you
Dan:
replace
Austin Gil:
have to,
Dan:
us!
Austin Gil:
no, not necessarily that. It's just that there's, you're gonna have to specialize. Like there's so much to learn at this point that and the lines are getting so blurred that to really be effective, you have to be knowledgeable on what the front end can and cannot do. what the backend can and cannot do, because now you're moving some of your backend code sitting right next to your front end. You have to be aware of different types of runtimes, like is this going to run on a server or an edge runtime? And then now you also need to be aware of how transpilers work and when you need to reach for one. And if you do, what limitations you have in that context as well. It's just... There's so much and somehow all of this is still related to the front end.
Dan:
Yeah, but aren't like meta frameworks or whatever we decide to call them effectively supposed to address this complexity like just use next. Yes, and we'll handle all the complexity for you.
Austin Gil:
Well, yeah, until you hit those edge cases where, you know, you're, you're kind of stuck in why is this working or why is this not working or why am I allowed to do this or should I be writing a SQL queries from this file input? I don't know. Like, you know, like, uh, I don't think, I think that these tools are going to allow us to be more productive and not need to know those things in order to build it, but we still. we'll need to know some of these things in order to understand how they're working and where the, where the edges are.
Dan:
The question that I'm asking myself, and that's probably a topic for discussion for another day, is, okay, we're getting all this extra power and the complexity that comes along with it, but do we actually need it? I mean, at the end of the day, most web developers are pretty much writing the same web applications that we were writing 10 years ago. So the question then... becomes why do we actually need all this extra power and complexity? What are we actually leveraging it for? You know.
Austin Gil:
because it's fun, you know? Because our generation was raised on home improvement and Tim the Toolman Taylor who said, "'More power, rrrr, rrrr.'" Never mind
Dan:
Yeah.
Austin Gil:
that. Let's cut that out. Just cut that part out. Ha ha
Dan:
No,
Austin Gil:
ha.
Dan:
we're keeping it in. Anyway, okay, great then.
Austin Gil:
Hmm.
Dan:
So with that, let's move over to picks. So I'll start. So my first pick is that I want to shout out again how great attending conferences really is. I mean, we had such a lengthy break from, you know, in-person podcast. conferences because of the whole COVID thing. And also it seemed that a lot of conference organizers, like, kind of gave up. So even when COVID ended, there was a pretty lengthy duration where conferences were more scarce and far, and, you know, further in between, but it seems that they're finally making a comeback. And I can't say how great that, you know, can't say enough how great that is. Uh, and so this year I'm actually. participating in a whole bunch of conferences. I'm up to five conferences so far, and there's a sixth on the way, something like that. And the last one that I participated in, actually a week ago, relative to the time that we were recording this, it was on June 27th, that was React Next Conference in Israel, actually. So I didn't actually have to travel for that one. Turns out that it's the second largest React conference in the world. We had something like, I think, somewhere between 1,000 and 1,200 attendees and lots of great speakers, some of which have been on this podcast, like Tejas and Gil Tayar and others. And also some that we will have, like Eric. I forget his last name. Eric I'll remember in it in a bit Eric Wendell we are so we are actually scheduled with him He'll be coming on this on the future episode of this podcast. He also was at this conference And and that's the thing I wanted to say about these conferences as for me It's the best thing about the conferences are the people you meet are the hallway Conversation the conversations that you get to do in the speakers room all the You know you go out for you know for drinks or for dinner afterwards. It's really, really great. The people are wonderful, very knowledgeable. I always learn a bunch of things. And again, not necessarily from the talks, but just from meeting people. Another person that was speaking there is Noam Wozntal, who we've had on the show. So yeah, it was really great and I had a wonderful time. So my first pick is conferences and participating in them, especially as a speaker. My second pick is a TV show that I'm watching. It's not too smart or sophisticated, but it's just a lot of fun. And it's called The Recruit. It actually paints the CIA as a bunch of crazy psychopaths who are out to sabotage each other. But like I said, it's a lot of fun. It's obviously... Not very realistic, but uh, I enjoyed watching it Uh, you know when you want to turn your brain off and you know at the end of the day It's uh, it's a fun. Uh, it's a fun series to watch on netflix. So that would be my second pick My third pick is a fantasy series of books that i'm currently reading It's a series called the series itself is called the faithful and the fallen by john guinn The first book is called Malice, the second one I think is called Valor. I'm currently in the second book. It's a bit challenging to get started with because he throws a whole bunch of names at you and they're all kind of Celtic inspired, so they all kind of read funny and sound similar and you start forgetting, wait a minute, who is who? Because you know, every chapter is a different character, but once the story gets rolling... It's actually quite engaging and fun and I'm enjoying it so far. So that would be my third pick. And my final pick is kind of a downer. So I apologize for finishing on a low note, but it's the ongoing war in Ukraine, which we've kind of normalized because it's, you know, been going on for so long. I don't think people are thinking much about it anymore, but the people in Ukraine are still suffering. And there's a whole lot of devastation going on and what and you know, so whatever you can do for the people of Ukraine You know, I'm talking to our listeners whatever you can do. Please do it, you know, and don't forget what's going on and Now over to you. What are your picks Austin?
Austin Gil:
Yeah, thanks. I really appreciate that you call out the war in Ukraine for every episode. I think that's a good thing to be doing and keep people
Dan:
Yeah,
Austin Gil:
aware
Dan:
we tend
Austin Gil:
of.
Dan:
to normalize things when they take place for such a long time and it feels like there is nothing that we can really do about it. So, yeah, it's really discouraging in that regard.
Austin Gil:
Yeah, and it's important to reiterate that there's so many people in the developer community that are currently still being affected
Dan:
Yes.
Austin Gil:
and impacted by what's going on. These are colleagues and friends and
Dan:
Yeah, when I went
Austin Gil:
people.
Dan:
Wix the company that I used to work at Uh actually has offices or had offices in ukraine. I don't think the people in ukraine are actually working there. I think You know a lot of them They moved them to other places but um But i've actually visited ukraine several times while I was working at wix, you know And met some great people and visited lovely places and it's really heartbreaking to think about the current situation
Austin Gil:
Well, yeah,
Dan:
Now
Austin Gil:
I guess in addition
Dan:
bring
Austin Gil:
to
Dan:
us
Austin Gil:
that,
Dan:
back up now. Lift our spirits.
Austin Gil:
great, great. Yeah, remind me to do picks first
Dan:
Hahaha,
Austin Gil:
next time.
Dan:
yeah.
Austin Gil:
So I'm gonna jump on with your conferences thing. I think that conferences are wonderful, particularly around meeting people. I'm also going to give a shout out to, in that same thread, local meetups, because I think that as great as conferences are, as much fun as they are, I think local meetups provide a more unique opportunity to interact with the same people on a regular basis. And
Dan:
Hmm
Austin Gil:
I think there's a lot of value in that.
Dan:
and your local community
Austin Gil:
That
Dan:
which obviously has also value
Austin Gil:
yes, which conferences as great as they are, they're great in different ways and meetups can offer that which conferences cannot. And then I would also say Panda CSS, since we mentioned it, definitely give it a look. Have fun. playing with it, let me know what you think. I would love to see what people are doing with it. And then lastly is something that's just kind of a fun thing. There's a show called Jury Duty
Dan:
Hmm
Austin Gil:
that I've been watching. It's fantastic. So I really try to send a message to people that are learning and new to the developing community and people that have been around for a while to practice extending. empathy and compassion and kindness both to others and to yourself as we're all going through this journey of learning. It's a hard career,
Dan:
Yes.
Austin Gil:
so try and keep that in mind. I think Jury Duty is a funny show that takes place where an entire trial is basically staged and everyone's an actor except for one jury duty member. He gets put through progressively more and more absurd scenarios with what's going on with the trial. And somehow they had managed to just like cast at random this guy who ends up being the sweetest and kindness and like it's just hilarious and
Dan:
So it's a
Austin Gil:
it's
Dan:
sort
Austin Gil:
very
Dan:
of a
Austin Gil:
wholesome.
Dan:
Truman Show sort of a thing?
Austin Gil:
It's very much a Truman show. It's like a Truman show. It has the same sort of good feels as what is it? Ted Lasso. So if you like
Dan:
Hmm.
Austin Gil:
Ted Lasso, you're going to like this person. He's like the real life version kind
Dan:
So
Austin Gil:
of.
Dan:
what? This is like they did a sort of a reality show. He's a real person
Austin Gil:
Yes.
Dan:
that he did know that he was being injected
Austin Gil:
It's all hidden
Dan:
into.
Austin Gil:
camera.
Dan:
Oh, interesting.
Austin Gil:
Yes.
Dan:
Where is it running, this show?
Austin Gil:
Uh, I don't remember off the top of my head. I think
Dan:
Well, that's what the
Austin Gil:
maybe,
Dan:
internet is for.
Austin Gil:
yeah. Yeah.
Dan:
We'll put a link in the show
Austin Gil:
I think
Dan:
notes
Austin Gil:
it,
Dan:
afterwards.
Austin Gil:
yeah,
Dan:
Now, don't
Austin Gil:
it's,
Dan:
sweat
Austin Gil:
uh,
Dan:
it.
Austin Gil:
okay. Cool. Well, that's it.
Dan:
Okay, so if people want to get in touch with you, you know, talk about the stuff that we talked on this episode or whatever What's the best way to reach out to you?
Austin Gil:
My website Austin Gill with 1L. AustinGill.com is where you can find all of my links and stuff I do a lot of blogging there. I'm also on Twitch and YouTube and stuff but Twitter but
Dan:
while it's survived.
Austin Gil:
Yeah, I don't know just go to my website is probably the and then you have your choice of
Dan:
Yeah,
Austin Gil:
preferred
Dan:
we keep trying
Austin Gil:
flavors
Dan:
to like, you know, kind of leave Twitter and then get pulled back because there's nobody, nowhere else really to go.
Austin Gil:
Yeah.
Dan:
So for a while, you know, everybody was heading over to Macedon and now Macedon
Austin Gil:
Yep.
Dan:
seems kind of dead. And now there's blue sky, but we'll see. I don't know.
Austin Gil:
Yeah, it's alright. Just, I don't know, I'm trying to make my own little weird space on the internet and you can find me there.
Dan:
Cool, very cool. So Austin, thank you again for coming on our show again. And it's been a great conversation. I really enjoyed it a lot. I've learned stuff for sure. And
Austin Gil:
Well, that's quite the compliment.
Dan:
you're welcome. And you know, and to our listeners, we'll see you next time. So bye.
Austin Gil:
Bye.