Powered by RedCircle

Alpinejs, Microservices, Code Completion, and Getting Paid for Open Source with Caleb Porzio - JSJ 497

  • Guests : Caleb Porzio
  • Date : Aug 17, 2021
  • Time : 1 Hours, 4 Minutes
Caleb is the maintainer of several popular open source projects and frameworks including Alpinejs and Livewire, and is also an avid user of GitHub's CoPilot. Also, he's living the dream - writing open source full time. 
We talk about declarative, imperative, moving from SPAs and APIs back to simpler server-oriented design, design architecture, code style and linting, and how Caleb's achieved the near-impossible task of monetizing open source in a way people love.

  • Aimee Knight
  • AJ O'Neal
  • Caleb Porzio 
Contact Aimee:
Contact AJ:
Special Guest: Caleb Porzio .
Sponsored By:

AJ_O’NEAL: Well, hello, hello, everybody and welcome back. I am your host for today's show, AJ O'Neill, and I am coming at you live from the Ghost Ship, where we have our skeleton crew today of our special guest, Caleb. Want to introduce yourself real quick? How's it going? 

CALEB_PORZIO: Yeah, I'm Caleb Horzio. I am a full time open source maintainer. I work on Alpine JS and LiveWire, Laravel LiveWire. Those are my main projects. Yeah, that's my thing. 

AJ_O’NEAL: All righty, and Amy Knight. 

AIMEE_KNIGHT: Hey, Amy from Nashville. 

AJ_O’NEAL: All right, so welcome to JavaScript Jabber one and all. 


This episode of JavaScript Jabber is brought to you by DigitalOcean. DigitalOcean recently announced their new App Platform service, which is a solution to build modern cloud-native apps. With App Platform, you can build, deploy, and scale apps and static websites quickly and easily. Simply point your GitHub or GitLab repository and let the App Platform do all the heavy lifting. As it has support for Node.js, Python, Go, PHP, Ruby, Static Sites, Docker, and Container images, DigitalOcean runs their App Platform on their own infrastructure so your costs are significantly lower than the other products on top of DigitalOcean Kubernetes, providing a smoother migration path so you can take more control of your infrastructure setup. As a listener of JavaScript Jabber, you can get started for free. Better than free because DigitalOcean is giving you $100 credit when you go to do.co.jabber. Again, go to do.co.jabber to get your $100 free credit on DigitalOcean's new app platform. We want to thank DigitalOcean for sponsoring this episode of JavaScript Jabber.


AJ_O’NEAL: And Caleb, why don't you just give us a little bit of why you are here today? 

CALEB_PORZIO: Yeah. I mean, I'm here to talk about Alpine specifically. I just released Alpine version three. So yeah, so that's been released out into the world and I'm got an email asking to talk about Alpine V3 and here I am. 

AJ_O’NEAL: All right. So most of us, I think I could be wrong, but when we think of Alpine, we think of Docker and I don't think that that's the Alpine you're referencing. 

CALEB_PORZIO: That is not the Alpine. 

AJ_O’NEAL: Okay, so what is Alpine? 

CALEB_PORZIO: Yeah, so it's like a lightweight JavaScript framework. It's sort of like a modern jQuery in its spirit, but it looks very much like Vue. So you use it very much like you use Vue. But the idea is that I had been, when I got into web development, I was using jQuery for JavaScript sprinkles. And I primarily come from like a backend driven life, like PHP frameworks on the backend kind of thing. And so, when I found Vue, I loved it, got really into it, and started writing basically like SPAs in Vue with Laravel backends, but eventually kind of walked down from the SPA approach for a bunch of reasons, but still needed something for JavaScript sprinkles that wasn't so, I don't know, grimy as jQuery. Grimy is a derogatory word, but you know what I mean, just like imperative and a lot of heavy lifting to do simple things. And I realized I just wanted a small framework that felt like Vue but didn't require like a whole JavaScript bundle. I want to be able to just pop in a CDN and do stuff right in markup. So it was also sort of inspired by Tailwind where I'd sort of bought into the idea of putting your styling right in your markup, co-locating it, and I found all the benefits of that. And I wanted sort of the equivalent for JavaScript. Like what if I could just put simple behaviors right in my markup? If I want to toggle a dropdown, I want to do it right in the markup. So I don't have to have a separate JavaScript file that has all the heavy lifting under the hood. So Yeah, I wanted freedom from the sort of modern JavaScript world, but still wanted the declarative nature, the reactivity stuff like that. Yeah. That's where Alpine's born on it. That's what it is. 

AJ_O’NEAL: Okay. So you're halfway speaking my language here. Cause I like the idea of, 

CALEB_PORZIO: what's your language? 

AJ_O’NEAL: My language is freedom from frameworks. 

CALEB_PORZIO: Okay. Interesting. Yeah. 

AJ_O’NEAL: I just, I am really, I think that the front end world has become insanely complicated. It gets more complicated by the day. And it's like the insane running the asylum. I look at the stuff that's coming out and I'm like, I, I don't get the appeal of it. I don't get why people anyway, that's, that's aside the point. Also, I, so you don't take it the wrong way. I'm this blunt person. That's like the devil's advocate and everything. And I'm going to give you a hard time. We, I didn't tell you that before we started the show, but I'm going to give you a hard time, but it's just to drive the conversation. Right? So first of all, imperative, declarative, blah, blah, blah. I'm calling that CSBS. Everybody says that their thing is declarative or it's imperative. What does, that doesn't even mean anything. 

CALEB_PORZIO: I'll go to back for it. Let's do it. What does it mean? Let's tussle. 

AJ_O’NEAL: Yeah, like, because I think it's a bunch of garbage. Because I, you tell me what it means. What does it actually mean? Why is it good? 

CALEB_PORZIO: Here's exactly what it means. If you want to toggle something in jQuery, if you want to show and hide a dropdown, you are finding that dropdown, that element, whatever, and you're calling.show or.hide. You're imperatively telling it to do something. And, you know, maybe it's more complicated than that where you're changing classes and you do class list dot add. And then if you need to change the class list later, you have to do a class list dot remove, or I guess back in the day using jQuery, you didn't even have class. So with Alpine or Vue or any of these reactive declarative frameworks, what you're doing is describing the outcome. Like that's, that is the, that is declarative-ness. So instead of me saying show or hide this thing, I'm saying I want this thing to attach its shown state to a variable. So if that variable is true, you should be shown if it's false, you should hide and you handle all that imperative stuff under the hood. Under the hood, you can actually call class list add hidden or style display none. You can do all that under the hood. And so sort of the same thing with with style bindings and or any sort of thing like in jQuery, you have to do it all yourself. And what I mean by imperative is you're walking through steps, executing low level code that mutates things where with Alpine, you're describing outcomes. You're saying, I want the class of this element to be equivalent to this piece of data. And then it will watch that thing for a change and it will automatically update it. So all that imperative stuff happens under the hood and all you worry about is the declare is describing or declaring the state of that thing.

AJ_O’NEAL: Okay, so I'm going to just looking at the docs here. I'm on Alpinejs.dev. 


AJ_O’NEAL: I think I get what you're saying. And what I would say it is this and correct me if I'm wrong. Declarative looks more like JSON. Imperative looks more like code. Totally. Okay. I'm with you. 

CALEB_PORZIO: CSS is a, is like, maybe I shouldn't have used that word declarative, but what I mean by it is like CSS is a hundred percent declarative, like you could do calc and that would be like imperative CSS function, but everything in CSS, you're describing the state of things. You're saying this thing is red. You're not saying make this thing red. You know what I mean? 

AJ_O’NEAL: Yeah, like the closer you get to declarative, the more likely it is you could serialize the thing into a format you could store in the database. And the closer you get to imperative, the more you have to have an interpreter to run it. 

CALEB_PORZIO: Yeah, that's one view of it. Yeah, you can take really zoomed in views or really zoomed out views, but the essence is when you're imperative, like imperative language in English. Like every commit message I write, I use the imperative form or tense or whatever, where I'm saying like fix this thing. That's imperative where declarative is like this thing is fixed or describing the result. So it's like used in language as well. But yeah, the idea is like a command, a list of actions, like, and in code, that might mean, mean a for loop, like loop through this thing and each iteration do this thing and add this item to this array. That's all imperative. Whereas you're using like a map or something like dot map or dot filter dot reduce. It's declarative in the sense that you're not saying go through this each iteration and do this. You're saying you're describing the state of things. 

AJ_O’NEAL: Okay, so when I'm looking here, it does look like view. I see an X data equals, I have no idea what that would mean. I'm guessing X is the Alpine prefix. You see an X show equals open. I think that's what you described before. So X show equals open means there's some sort of variable somewhere called open.

CALEB_PORZIO:  So you see the variable in X data, right? 

AJ_O’NEAL: Oh, okay. 

CALEB_PORZIO: So X data is a little JSON blob. You just pass in the state. That's the state for that component. Every DOM element inside of that element will have access to that data and can attach itself to it or change it, you know, whatever. 

AJ_O’NEAL: Okay. Yeah. I think, I think I'm getting it then. So, well, first of all, I want to know how big or small is this thing? Do I have to bundle it? Do I have to transpile it? I mean, it looks like from the example here, you are literally just including a pre-minified version. And then you have little in the spirit of jQuery esque snippets of code, but they're in the HTML. 

CALEB_PORZIO: They're in the HTML like tailwind. Yeah. Yeah. So it weighs, now it weighs like 10 point something kilobytes, broadly and minified. So yeah, if you're pulling Alpine in, you're pulling in a 10 kilobyte library. You can run your own builds of it and basically any direct the directives are the X hyphen thing. So if it's X hyphen on X hyphen show X hyphen there's a bunch of those and you could build your own version and decide which ones you want. It's totally basically Alpine has a plugin system and it uses its own plugin system for all of its API. So you could get it down to probably like five kilobytes with like a really minimal version but but I don't know. It started as two kilobytes. And it grew over a year and a half to 10. And that's sort of where I've called it a day is like, I'm happy with the API. It has a ton of internal robustness that costs those extra few kilobytes, but it, yeah, who cares? It's 10 kilobytes. It's like a JPEG, a small JPEG. 

AJ_O’NEAL: Okay. So what I'm looking at here, so this is my problem when people say declarative is that declarative seems to be really, really easy. It's like the learning curve is one of those things where the learning curve line is like a zero for x equals one and a zero for x equals two and a zero for x equals three. And then when you get to about like x equals four, where x is an arbitrary unit of how much code I'm writing in this thing, all of a sudden the learning curve jumps up to like y equals 10 and then continues for a little bit and then goes back down. And so this looks super cool from the perspective of, okay, yeah, if I wanna do a little toy project with a to-do list, I could do this all in HTML and Alpine and I don't even need an API for a toy project. I've got all the tools I need for a toy project right here. But what if I want, I mean, like in one of your examples, you know, it shows the post in post or to do in to do's, but what if I need to fetch those to do's or have authentication or can this handle an application or is just, just kind of like for blogs and I don't know. 

CALEB_PORZIO: No. So first I'll say that I think you need to get over the word declarative. If I could be blunt, because that has nothing to do with declarativeness. That's just like, you could have your, your question is, is this thing robust enough to handle the needs of a big boy application? 

AJ_O’NEAL: I want to clarify when something is imperative, you have a list of keywords and you can use those keywords to construct anything. It is Turing complete. Like you, you can use, you use the tools of the language and it is programming. It is actually programming and you are telling it what to do. You are giving it instructions. So you can give it any number of instructions, right? But here, what you have appears to be a list of about, I don't know, it looks, what is it, 20, maybe directives, or I don't know what to call them exactly. 

CALEB_PORZIO: 15 directives, yeah, they're HTML attributes, prefix with X hyphen, we'll call them directives. 

AJ_O’NEAL: Right, and so if I need to do something that's not one of these 15 things, I imagine that then I need to go write a directive in JavaScript and then and then use it as a plugin to Alpine. And then that's my imperative behind the scenes, tell it exactly what to do. And then I'm surfacing it declaratively in the HTML. But at some point I have to learn that. 

CALEB_PORZIO: So what's an example of something that you would need to do? It could be outlandish, something beyond Alpine stock offerings. And I understand you don't know all of Alpine stock offerings, but come up with something that would be, something that you would want to do that you'd have to undergo this process of creating a plugin imperatively. 

AJ_O’NEAL: Well, I don't know, because I don't know enough about it. I'm just assuming, like for example. 

CALEB_PORZIO: And I'll tell you if Alpine can do it or not. 

AJ_O’NEAL: Okay, so well typically we have the model view controller, right, so we, the backend is the model. When we get it on the front end, it's JSON, you know, by the time it comes to us. And then our, we have our controller logic, which is typically very imperative because it's business logic rules. If we need to display something in a particular format, if we need to filter through a list if we need to zip two arrays together or transform an object into an array like all of this type of stuff, it has to be done in code, because you have to tell it how to get how to get the data in the right shape. And then you've got your view logic, which is hopefully your simplest stuff where maybe you do have a filter to be able to transform a date into the right format. So you define a function somewhere and then I don't know how this would do filter logic, but we I think in the other the other frameworks, we call them filters where you transform a date, for example. 


AJ_O’NEAL: And so like at some point, I think you have to write the other code. So I need to, every single app needs authentication. And that seems to be authentication and routing seems to be where every, everything always kind of throws its hands up and it's like, well, we're not, we're not going to tackle that problem precisely, or we're going to tackle in a really limited use case. But I think every app I've ever come up against.Like you go through the to do example, but then when it comes to the point where you need to add authentication and every single page needs to redirect, if it's not authenticated unless it's a public page and so on and so forth. 

CALEB_PORZIO: Let me stop you right there. Okay. Missing again. I think we're talking about two different things here. 

AJ_O’NEAL: Sure. 

CALEB_PORZIO: Let's just throw out the word declarative and burn it in a fire. Pretend. Okay. So if you're a word, then the word you should hear me saying is describing outcomes in code. And, but that's a totally different thing. You can write declarative code inside of a controller method where you're doing business logic. There can be a declarative style to the imperative code you're writing. But this is a conversation that has basically not much to do with Alpine anymore. So let's throw it out. 

AJ_O’NEAL: Sure, sure. 

CALEB_PORZIO: Let's answer the question that's on your mind, which is what happens with routing, authentication, validation, all of that stuff. The answer is that's not what Alpine's for. Explicitly not what Alpine's for. Not in a way that you're describing that Alpine is somehow like solving one problem and throwing its hands up and saying like, it doesn't address these other problems. And so it's a half baked framework that maybe is popular to beginners, but then cripples as you need real things. That is not the story. Story is you're using framework like Laravel, Django, Rails, Express, something I won't say Express. Let's say Django, Rails, Laravel, these types of backend ecosystems, these frameworks where you're using the backend templating language to generate your templates. You're doing form submissions that have backend validation. You're doing session like cookies off that's baked into these frameworks. This comes out of that context. It also is great for the little stuff, like you said, blog, marketing page, Alpine sings in that realm. It also sings in the backend templating realm. That's what it's meant to be as a companion to backend templating environments, basically. 

AJ_O’NEAL: Okay, that makes a lot of sense. 

CALEB_PORZIO: You would never write a full application using only Alpine. If you even could, it would suck. 

AJ_O’NEAL: And you said that at the start, like I took a step back from SPAs and I guess SPA is another one of those words where everybody says it. So it just didn't register as like having any meaning because whether or not something's an SPA, people are always like, SPA. So no, I get what you're saying now. So this is not for SPAs. This is not for that use case. This is a helper. So this is something that would be great if you were doing like a WordPress template or a bootstrap template, or basically like any type of template, because all the templates, they suck when it comes to doing exactly what this does, where you just want something to toggle a button and show hide. And all of those HTML template systems seem to just get really nasty at that point. And this looks like, yeah, this looks really, really, really clean for if your backend is primarily the driver. 

CALEB_PORZIO: That's the thing writing the for loop from the database. And that's the thing doing that heavy lifting, you know? 

AJ_O’NEAL: So this is really, really, it's just for the view part of the MVC. This is like your backend is handling thing. It's giving you stuff in the exact format you need your session authentication, your redirect to the login page. All of that is something that you're detecting on your backend. So, but what if. 

AIMEE_KNIGHT: Let me jump in and ask the question here before we move on. If that's cool. Yeah. Okay. So. When we're talking about like sprinkling it into our template, walk me through how this would be different or advantageous to using web components or like LitElement. 

CALEB_PORZIO: Oh, sure. Yeah. So let's say with LitElement, you have to have a build process, right? Like you have to have you want to. So let's say that you have a drop down, you have your backend template, app, whatever, and you want a simple drop down. If you want to use LitElement for that, you would have to have a JavaScript file for that know, the imports lit element from npm. And you would have to declare that element using their, their string literal templating syntax, you're not actually using HTML, you're doing that, whatever they call that in JavaScript, the string template template strings. 


CALEB_PORZIO: eah. And so and you would declare state and whatever. And then you would run that whole build. And then you have access to an element that you could reference inside of your backend template called whatever you call it dropped. And then there's questions like, well, okay, so I want the content to be different because the drop-down component is presumably genericized. So you maybe have a slot that you put the content into, maybe have two slots. One's the button toggle, one's the content toggle. And let's say something inside of one of those slots needs to change that closed state of the drop-down. Like you open it, but then there's maybe one of the items inside the drop-down should have control to close the drop-down itself. So to do that, you'd have to have, I've never really used LitElement in a real application. So you can view it or React might be like, yeah, view would be like scope slots, slots that have access to scope from their wrapping component. So you would need something like that to change the state of the outside thing. And I don't even know if that's possible with an exported web element. So you have all that. And then I'm gonna keep adding frosting layers here. This is, I think, a good point to demonstrate. 

AIMEE_KNIGHT: You're convincing me, so. 

CALEB_PORZIO: Sure, yeah. So let's say you want to open that, you're writing this dropdown, you click to open the dropdown, you have your two slots that are shoved inside of some element. You click to open the dropdown, the internal component state goes to true. And we didn't even get into styling. Like I don't even know what the lit element story is for styling. But with web components, obviously, if you're using like Shadow DOM, they don't have access to the outside CSS. And there's all those things, those hoops to jump through. But now when you click away from the dropdown, you want it to close. So inside LitElement, you would have to say, you have to listen for click events on the window, detect when they happen outside of the dropdown and change that dropdown state to false. Well, all sorts of stuff, whatever. And okay, now let's say that you wanna add transitions because you want the dropdown to do a quick little fade in, right, like a nice little simple fade and swoosh in maybe or dropdown or something like that. So how do you even do that? Like LitElement, I'm sure doesn't have a transition system baked in. So you probably have to download some extension or plugin that applies CSS transitions at the proper frames and have a way to interrupt it so that when you toggle it on and toggle it off while the transition is happening, it doesn't like clobber itself. So I'm going on and on and on because I could go deep and deep and deep. Here's how you do this in Alpine. That whole story is littered with complexity. With Alpine, you drop in a CDN, that's it. And then you have your drop down that you wrote up in CSS and HTML right in your backend template. You say, X data open is false if you want it to be false initially. Then the button you say at click open equals true right on the button tag itself. Then on your little div that has the drop down you say x show equals open. That's it. You're done. You want to add transitions x show dot transition and there's an extreme. Sorry x show there's an x transition directive you would add and it will now make that the show toggle. It'll make a transition or you could specify all the classes you want to be added to every phase of the transition, just like in view. And then if you want it so that you click away on your button that has at click open equals true, you could say at click dot outside equals open equals true. And Alpine has a helper for that. So it'll automatically handle all the complexity of clicking away from a drop down, clicking outside of an element to register the click inside. So I could go on and on and on, but I wrote it because like at the end of the day, if you're in a backend template in context, the only JavaScript I was really writing is like outside of the occasional like doodad that takes a lot of complexity. But the stuff that I needed jQuery for that I needed to what like lit element what I would need that I used view for inline templates was like drop downs, toggling stuff, a tab component here and there, basic stuff, maybe a little infinite load trigger, maybe a scroll back to the top thing. Maybe little inline password validation, something like that. So huge speech to answer that question. But this is a pitch for Alpine. 

AIMEE_KNIGHT: Yeah, that is helpful. So it really is like the most bare bones thing of quotes on the market right now that I could use if I don't want to just go with vanilla JavaScript. 

CALEB_PORZIO: Yes, it is. And it's much easier than vanilla JavaScript. There's like nothing easier to sprinkle in interactivity into your HTML templates than Alpine. 

AJ_O’NEAL: Well, in a way. It's just giving you it's giving you handlers so that you can write little tiny snippets of vanilla JavaScript because what I see here, there's not like a bunch of Alpine methods that I'm calling. It's I get an Alpine Exxon click. And I've got what is it basically six, six things that are actually part of JavaScript that all begin with a dollar sign. 


AJ_O’NEAL: you know, so it store L dispatch watch refs next tick. 


AJ_O’NEAL: So that Yeah, I mean that that's pretty close to vanilla. Yeah, when you're writing out, you have a little helper. 

CALEB_PORZIO: You're writing a lot of vanilla JavaScript, but you're not having to do the annoying Dom API wrangling of adding event listeners and preventing default and all sorts of those things. Like if you wanna listen for a key down in a text area or something, you wanna listen for like hold command and press K or something in a docs app to pop up like an Algolia search. To do that by hand is obnoxious. And you're basically just stack overflowing the like E.key code is not equal to this. And then the command modifier and trying to get that logic right. With Alpine it's axon key down dot command dot K and you're done. And it will just work. It handles key combinations. You can write the key itself. And then you do your imperative or I'll stop using those words. You do your vanilla JavaScript right inside that little, that quotation. What do you want to do? You could do whatever you want to do. You could call a totally unrelated function. You can do any JavaScript. 

AJ_O’NEAL: Okay, so I'm looking through the docs here. All of the HTML attributes look like they make sense, I think. 

CALEB_PORZIO: Yeah, and the majority of those, so they have a history of, if you know, Viewer Angular, like... 

AJ_O’NEAL: Yeah. 

CALEB_PORZIO: Yeah. Most of them are straight from View, which most of those are straight from Angular. So it's a lot of established conventions, like XShow was originally NGShow, then VShow, now XShow X model was V model than an NG model, you know, the same sort of idioms of these declarative template. 

AJ_O’NEAL: Okay, what's the Alpine.data in the Alpine.store? Looking at it, it looks like that's something that goes in a JavaScript file separately from the HTML. 

CALEB_PORZIO: Right, that's the escape hatch. Sometimes you don't wanna sprinkle it all directly in your HTML. Sometimes you have too much code to write in there. Sometimes it doesn't feel right or you want to reuse a chunk of data or something and that's what Alpine.data is. So people who use Alpine.data generally are, they're like, no, I actually want a bundle. Um, because I want, let's say I want to use, uh, modern JS and I need it to like transpile down to older browsers or something. Maybe they like the organization or the syntax highlighting or whatever. And maybe, maybe you have a component that's extremely complex and really warrant something like that. And that's where you use Alpine.data. It's basically like, Hey, instead of writing all this crazy stuff inside HTML attributes. At some point that gets ridiculous. You can, this is an escape patch. You can use Alpine.data, pass it a, and this would look, this is what would look like a view component or not necessarily React, I mean, maybe a class-based React component, something like that, except there's no templating concerns at all. That's the main primary difference. There's no render function or anything. It's like a data provider. 

AJ_O’NEAL: Okay, so let's say that I'm an idiot and I want to abuse Alpine. 

CALEB_PORZIO: Yeah, yep. 

AJ_O’NEAL: And I'm gonna...I'm going to try to write a controller in vanilla JavaScript and just do a lot of fancy stuff in there. Is that reasonable that I could just write it in JavaScript and then reference it the same way that you can reference new date, whatever? I could just attach it to the global, reference it, and then have things work reasonably as expected? Or if I'm passing in some sort of object that's changing, would it need some sort of hook at the end to know, okay, now redo the checking of properties of what's changed. 

CALEB_PORZIO: So anything in Alpine.data or in Xdata for that matter, any data that Alpine owns essentially is wrapped up in a reactive proxy. So anytime any external force changes, even a deep property, everything that depends on it will reevaluate. So you can put in whatever kind of JavaScript array or object. If you had an array from the server or something like that. When you made a new API call that updated that array to add a to do item or something, Alpine would just react to that. So you could totally abuse Alpine and you can abuse it pretty far. And it's fine. I mean, like performance wise, the nice thing about Alpine v3, the way it works is if you render all the Alpine on the page on initial load, if you update some piece of data from wherever, it could be from any JavaScript. If you update that piece of data that Alpine is depending on, it will make only that DOM mutation. Like that's it. There's no other, there's no virtual DOM rendering. It doesn't re-walk through the whole tree. So it's very much like Svelte in that sense that it's DOM manipulations only, and they're mapped to their JavaScript dependencies. And there's a reactivity engine that when it detects that dependency change, it will make that DOM manipulation in an isolated, targeted way. So kind of a tangent on the inner workings of it, but it's totally performant. It's not like you're using some small tool that's meant to be used in a small way. No, you could use it to render a thousand rows, delete one, and it'll be nearly as performant as the big boys. 

AJ_O’NEAL: But now, now my head's going to explode because my whole life I was told that angular bad, dom bad, virtual dom good, react good. And now you're telling me that, that I've been lied to and, and, and that I could just rely on more native things. Can I trust you?

CALEB_PORZIO: Yes and no. There's a lot of truth in both camps. There's some extreme benefits of virtual DOM that Alpine doesn't have. There's certain areas where Alpine's individual DOM mutations will crumble where a virtual DOM won't. But there's lots of misconceptions. It's not as simple as DOM bad, virtual DOM good. That's a broad stroke and there's a lot to be gained by losing the purely unnecessary work. Because at the end of the day, the virtual DOM's just making DOM manipulations, you know, after you do the diff and the patch. But there are times where if it's like a huge template that has one small change in it, I have to do more like walking of the real DOM, where a virtual DOM, if you're walking JSON is faster than walking normal DOM, like that's just a fact. So there are benefits at those edges when you have like big work to do and only a small actual DOM manipulation to do. And caching, yeah, whatever. We could go like deep into the, my opinion on this has evolved many times. Yep. Back and forth. And I've landed somewhere in the middle. They both have advantages in different scenarios. And you can find benchmarks that highlight either camp. Evan Yu just posted that whole thing, how like Svelte's not actually faster for all of these things. And it's not actually a smaller bundle for all of these things. So there's lots of...and whatever the svelte guy Richard Harris, he did that whole post on views. Virtual DOM is just unnecessary work. View and reactor spinning their wheels where I don't have to because of pre-compiling. But anyway, lot of yin and yang virtues on both sides. 

AJ_O’NEAL: OK, all right. Well, to be honest, I don't have other intelligent questions at the moment. What's some other stuff that I should be asking you? 

CALEB_PORZIO: Yeah, I don't know. We talked about internals. We talked about the API, its usage, maybe the one piece of the Alpine puzzle it came out of is so I built LiveWire. It's a tool for Laravel that allows you to have dynamic interactivity, very SPA feeling apps, but only using backend templates. Inspired by Phoenix LiveView. Familiar with Phoenix LiveView? 

AJ_O’NEAL: I am not. Okay. 

CALEB_PORZIO: Cool technology. I'll give you the quick gist of it that, you know, if you so well, here's how Phoenix LiveView works. You have some MVC, classic MVC stuff think MVC backend stuff. You got your controller, you call some models in the database, you render a backend template. And let's say that you want to change something about that backend template, like on the page, live on the page. Maybe you're, I don't know, closing a comment or like commenting on something inline and you don't want to do a full page reload. You want to, this is something where you'd think, okay, if I want to easily hit type in a comment, hit submit have it add right to the DOM, not re-render the whole page, not do a full form submission that whole life cycle, you'd think, I gotta use JavaScript for this. This is where Phoenix Live View and what I work on LiveWire come into play. Basically, it stores the state of your backend code essentially. And if you hit like add comment, it'll send an AJAX request to your backend to essentially do any backend work you need to do, re-render the backend template, get the backend template to the front end, do a diff of the the two HTML, the one that just got back from the server and the one that exists on the page, and it'll pass the things that have changed. So it's a way to achieve interactivity in the front end without actually writing JavaScript at all and generating still using your backend templates. Like a simpler example would be a drop down but purely written with the backend. This would be silly because you'd make a whole AJAX request just to toggle a drop down. But you could store that state in the backend and your the toggle that shows and hides a drop down could literally be backend code like a backend if statement. Yeah. So tough thing to just like kind of throw at you and we don't have to go down that path. But this is a huge reason why these tools are coming out for every like every environment is coming out with their own version. This turbo is a very similar like I don't know if you're into the Rails community, but their whole hot wire thing, whatever. It's a whole other. Okay. It's a whole it's all in this ecosystem of tools that uses Ajax requests and backend templates rather than fetching JSON when you want to do something you fetch the already rendered HTML from the back end. So all your templating is done in the back end and then front end technology swap in the HTML intelligently. 


Are you ready for core web vitals? Fortunately, Raygun can help. These modern performance metrics play an important role in determining the health of your website, which is why Raygun has baked them directly into their real user monitoring tools. Now you can see your core web vital scores are trending across your entire website in real time and drill into individual pages to focus your efforts on the biggest performance gains. Unlike traditional tools, Raygun surfaces real user data, not synthetic, giving you greater insights and control. Filter your score by time frame, browser, device, geolocation, whatever matters to you most. And what makes Raygun truly unique is the level of detail it provides so you can take action. Quickly identify and resolve front end performance issues with full waterfall breakdowns, user session data, instance level diagnostics of every page request, and a whole lot more visit raygun.com today and take control of your core web vitals. Plan start from as little as $8 per month. That's raygun.com for your free 14 day trial. 


AJ_O’NEAL: So what's old is new again. We should just stuck with jquery.ajax. 

CALEB_PORZIO: What's old is new again. Exactly. These are old patterns, but they're coming back around because they're singing of the virtues and that's been my own journey. It's like going, you know, start doing this, going up the hill and then coming back down and going. Yeah, you know, I was maintaining two applications when I had my SBA. Coming back down and being like, what if I went back to having one application, my productivity would... 

AJ_O’NEAL: So one of the things that I thought was great when we started moving towards JSON was that you could write your API and just use your API and you could know your API was working because if something was wrong in your API, then it would be wrong in your regular app. And then you only have to write one application. You don't have to write two completely entirely separate applications. And then have to refactoring is just impossible because you have to maintain all of these, you know, if you want to update something about the controller and then you have to make sure it works with the API and that it works with the front end. Yeah, 

CALEB_PORZIO: absolutely. Yeah. So, I mean, that, that is a virtue. If you can work in an environment where you can pull that off, then that is a great advantage to you. But in my experience, I've never been able to pull that off. I've never in the actual trenches of maintaining an actual application that's used in the real world that becomes, it becomes a pipe dream that I've never seen realized for lots of reasons. Like 

AJ_O’NEAL: to use the API on the front end. 

CALEB_PORZIO: Yeah. To use your own public API and consume it for your own application. 

AJ_O’NEAL: That is the only thing that I've ever done. Well, I mean, in the very, very early days when that wasn't really yet possible, but now I'm interested. Yeah. 

CALEB_PORZIO: You have to, to make any meaningful change, you would have to version your public API and version the whole API, like bump the whole version, right? Because you have to, you have to prevent breaking changes for your public API. So you have to version it just like an open source package. 

AJ_O’NEAL: Well, typically, well, typically adding something does not cause it to change. 

CALEB_PORZIO: For sure. 

AJ_O’NEAL: You can add something, you can't remove something or change the type of something. 

CALEB_PORZIO: Exactly. You can't change the schema and you can't remove something. 

AJ_O’NEAL: But you can also add, if you need the shape of something to be quite different you can also just add another route for that shape. 

CALEB_PORZIO: Absolutely. So now you're in the realm of like, well, why did you, now you've lost that benefit of reuse. You know what I mean? Like you've just lost that benefit right there. And how many, how many features and pages change? Like there's in my experience, marrying your apps front end and back end and just forgetting about that story of perfect reuse of a public API. Because what you're basically doing is making a crucial interface for your internal application public and then subject to version constraints, which is like crazy. And then what you have to do, like anytime you want to make some big sweeping change internally, you have to wait for a full new API version and document it and maintain those two versions and have an upgrade guide. And then you're taxing the people consuming your API, you're making their lives harder. And then you're going to end up creating your own little escape patches everywhere anyway. And there's so much work that's just not normal API work. Lots of things on your app, a search, some, I don't know. There's so many things where even it's advantageous to grab the data in a different format or in a cached format or access sensitive data or system level data, stuff like that, that you just would never put in a public API. So anyway, everybody has an experience. In my experience, I'm back in that zone of maintaining two things when I should be maintaining one. 

AJ_O’NEAL: Yeah, I guess, because granted, I'm typically working with smaller clients doing things that are kind of more what I'm developing on the front end is is the demo. If I'm developing anything on the front end, and I'm documenting the API, like typically my work is the public API that would be used potentially with partners. Well, there is one big app that I worked on that was built this way to actually those huge for one of the largest names, you know, but everything was kind of designed to be able to be used internally or through the API. But we did have a lot of flexibility because there's kind of like, there's partner contracts. And then once you, once you have a partner that's important, you just run that version of the backend for them and you never give them a different version of the backend, you know, 


AJ_O’NEAL: And, and that's, that's that. So if you're like, Oh, actually we should make the shape of this different for us. Well, then you, your own instance and your partner instance will use the same database, which by that point, your data is pretty well set that. If you use .name and you've got your partner, where you're just sticking with name and you're not switching it over to given name, or if you have to split it to first name or given name and family name, then you just add those on there and you've got duplicate data or something. But anyway, I see what you're saying though. 

CALEB_PORZIO: Anytime you add a contract or a seam or an edge, whatever you wanna call it, you know, in your code base, you've now added a whole layer of complexity. And that's my my issue with microservices architecture, I've worked on a few apps that are pretty big companies, microservice architecture and anything that make one feature different in some way, you have a slice that has to cut across multiple services and all those services are contractually like bound to each other. So it becomes this huge mess that's like, this is like the DHH all hail the monolith kind of thing, like long live the backend monolith. And that's definitely the camp that I'm in like really suffering from it. 

AJ_O’NEAL: I'm gonna channel Ethan Garofalo, who is the microservices consultant dude, at least here locally, and say that is not a microservice architecture, that is a distributed monolith architecture. He's got some great talks I'll link to in the show notes, but if you find Ethan Garofalo on YouTube and watch his stuff, he does a pretty good job of getting the point of cross of what you need to do is pass messages between systems. And if you have those type of interdependencies where things are really contract bound, then you're not doing it right. But also he admits that you do have to sit down, you don't just go code some microservices, you sit down and you think, okay, what are the things that need to happen? What do they really relate to? And write it down and make a bulleted list and say, okay, this stuff actually does belong in this service. And this stuff actually does belong in that service. Cause if you're just like, Oh, we're going to have a login service, but it's also going to handle the user data and the profile data and the book marks. Well, now you no longer have a login service. 

CALEB_PORZIO: Yeah. All of that. And that upfront planning, you know, the nature of software does not lend itself well to upfront planning. So 

AJ_O’NEAL: tomato potato, I, some, some level of upfront planning is good, but yes, you have to have emergent design. You have to let it speak to you. What it is as you build it. 

CALEB_PORZIO: Exactly. And what more freeform way is there than to not worry about API requests and having to conform to a schema? And having a test suite that runs through your entire application with ease and doesn't have to make, isn't stubbing out all of the, you can have all sorts of false positives, whatever. I could go on and on. I have some pretty strong opinions on microservices. I've been a bit pretty bad. 

AJ_O’NEAL: Well, I actually love to have you on again. Maybe we could get you and Ethan to both come on. 

CALEB_PORZIO: That would be interesting. 

AJ_O’NEAL: Or something like that. I'm all I'm there with you, you know, like realistically, everything has a plus and minus there's good, there's bad. 

CALEB_PORZIO: Yeah, absolutely. 

AJ_O’NEAL: You know, like my point is try to like draw out the strong opinions and like go from straw man to steel man and all that. Which I probably do a terrible job of. Anyway, I do, I had a couple other questions before we wrap up, cause we're coming up against time here. But I wanna go in a completely different direction if we can, feel free to take us back if you remember something, but. 

CALEB_PORZIO: All good. 

AJ_O’NEAL: You are living the dream. You are one of like 10 open source developers that actually get paid for your work. And I think they're only front end developers. I don't think there's any backend developers that get paid for their work in the open source world. 

CALEB_PORZIO: All the paid stuff for me is for backend work, for LiveWare. Alpine has no monetization at all. 

AJ_O’NEAL: Oh really? Yeah. Okay, so that's- 

CALEB_PORZIO: But there's zero Alpine sponsors. 

AJ_O’NEAL: Oh, okay. All right. Well, anyway, so you're living the dream and you're living the hard part of the dream. Because I've only really heard about front end projects that actually get sponsorship. Because look, it's pretty. But tell me about that. Do you have what's the pit of despair? What's the pinnacle of success? Should anyone try to pursue it or just let it fall upon you naturally, if the gods will it? 

CALEB_PORZIO: Right. I mean, so it is funny hearing the living the dream is like. It rings in your ears because I actually I do feel that I am living the dream, but maintaining open source projects is there's a lot of not fun involved, as you know. 

AJ_O’NEAL: Yes, 

CALEB_PORZIO: like there's a lot of that. So anyway, yeah, what would I say? I would say that I'll say that the dream currently doesn't exist where like the reality is that software is extremely lucrative right now and developers, I won't say overpaid. But you know what I mean, there's there's money all over the floor. Like as far as industries go, there's like, you don't have to get a degree, whatever, you just come in here. We just need warm bodies, writing code. You can get hired as a software developer. And so because these companies, because software is so lucrative. And so I've worked for agencies and product companies and whatnot. And these agencies and if you stop and think for a second, how many open source, how much of the work that you produce is built on open source work? And the answer is most of it. You're working with, uh, lakes and mountains of abstractions that are completely open source. So an agency. 

AJ_O’NEAL: This is kind of the bitter pill though. It's like you're building your own prison. Any open successful open source is used to create a service that takes your data and your money away from you. 

CALEB_PORZIO: Right. But so like what I'm talking about is like, let's say Git gets open source. You use Git all the time. Right. 

AJ_O’NEAL: And did anybody make any money off of it? Are they still eating pizza? And meanwhile, the GitHub people are... 

CALEB_PORZIO: I don't think Linus is rolling. 

AJ_O’NEAL: But GitHub did. 

CALEB_PORZIO: But GitHub did, right. And that's a separate thing. But all right, so GitHub, okay. So GitHub is a great example, a very profitable company that fundamentally is built off of free open source code that people donated to. We have C, we have all of these things that are... Rails. P is open source. Rails is open source, totally open source. Ruby's open source, Rails on top of that's open source. Everything on top of that's open source. So when I, when I find working at an agency, they're selling competency and view react Laravel, like the agencies that I worked at and, and they're getting paid, you know, a good amount of money and they're pocketing some of that and they're paying forward to their developers who generated that whatever. But the people who created all the code that they're marketing themselves with and moving really fast with get $0 or maybe they get a table at a, maybe they throw them a bone. They have bought a table at a conference. Maybe they have their logo on the sponsor section of the website and they kick whatever between one and 10 grand a year. But what I'm trying to say is that currently, the environment is not set up that open source code is rewarded. And I'm not saying that it needs to be, but I'm just saying that that's why this dream is currently impossible. I have I'm a fake. I am not just somebody who produces valuable open source code and people go, man, your code helps me so much. I'm going to pay you money. That is not the reality of the world. 

AJ_O’NEAL: And just one example, the biggest example of this, Express.js, an abandoned project that was never finished. How is the most popular framework in the entire world? How did it not get sponsorship to be completed? 

CALEB_PORZIO: Right, yeah, I mean, this hapless is a constant thing. There's like, what was the most recent example? The guy who did Babel and now he's doing something, ah, maybe it wasn't Babel. Oh, yeah, it was Babel. Anyway, whatever, this is a constant thing. It's like for to employ one developer full time is like this has happened, what like three times somebody some project gets enough money on open collective to fund a full time developer, let alone a few and then they inevitably lose funding. And these developers are paid like low salaries for this really you know, high level work like you know, you go work at a fan company at a high level and you're making between 500 and whatever million dollars a year like that happens. But open source developers they get paid 80, 100 maybe. Like that's not so anyway. 

AJ_O’NEAL: So I was thinking the 80 to a hundred were the 10 that I was talking about that were successful. 

CALEB_PORZIO: They are. Yeah, exactly. And that's what I'm saying is working at like a Google or Facebook or something, you make so much more money and you're still doing very high level meaningful things. And so whatever I realized I started out by just asking people for money. People telling me I've quit my job and I just started working on live wear. Then I just did it for free for a long time and made zero money for most of that year. And people were like, Hey, man, you should create a Patreon. We'll support you. And I kept thinking like, Yeah, I know. But if you buy me coffee, if 30 people buy me coffee once a month kind of deal, that's not going to contribute to my financial life meaningfully. And more than that, it doesn't even seem worth it to me. I'd rather have the goodwill that you just then have the $300 a month or something. So what I did was I basically monetized adjacent products screencasts and source code, like example code for my project. So I still document my projects. I do lots of training for the projects. But if you go to LiveWare's documentation, there's some free screencasts that walk you through the basics. And then there's me walking through an entire application build with LiveWare and giving you all the screencasts and access to the repository. And it's 14 bucks a month. And that's how I make my living. I've realized that you have to provide value. You have to provide value to people and there's a lot of goodwill involved. I'd like to think that I'm more than just a tutorial. I actually make money on open source because presumably the people are using the project and they're going, yeah, I should kick some of this back to... It's on GitHub sponsors. So they're directly sponsoring my contributions to the framework. But I've realized that, yeah, you can't make money purely on open source right now. It is almost impossible. You have to make money on adjacent products or offerings. I did consulting for a while, but that's not fun.

AJ_O’NEAL: Well, that's, and that's also something where it's not scalable. Whereas creating course material is scalable. 

CALEB_PORZIO: Yeah, exactly. 

AJ_O’NEAL: It's you could get to that half million dollars a year with course material. You could get to that with consulting. 


AJ_O’NEAL: Unless you're really good looking and smooth talking. 

CALEB_PORZIO: Yep. It would be pretty tough. And so I mean, I frame it as sponsorship. So like when you get to those screencasts that are private, it just says, you have to be a GitHub sponsor to view these. And then there's other perks sort of rolled into that. I've released private repositories before that are private until I reach a certain number of sponsors, then those repositories become public. So people are sort of, you know, funding the project that way. And that's worked pretty well. I called that sponsorware and did a bunch of write-ups about it, but that's how I've made my money in open source is basically that's the reason it's sustainable. If I didn't have those, those triggers to offer people value, I would not be making money. And the other observation is that the money I make is generally from independent or individual developers, even at companies, which to me is a shame that the companies are not the ones carrying the burden of open source funding. It is the individual developers giving me $14 a month, which I hope changes someday. I don't know how to change it, but GitHub is working on it. Trying to 

AJ_O’NEAL: scares me a little bit. That one, 

CALEB_PORZIO: what? Git Hub.

AJ_O’NEAL: Well, just mega corporations because it always tends one way and it's never with a corporate. There's a very, that's a different topic for a different day. But I'm just, for example, I think the idea of co-pilot is cool. I don't think that co-pilot is going to get rid of senior developers, but I think that co-pilot is going to make the divide between junior developers and senior developers much greater. And I think it may make it so that fewer people can find a path between the two. 

CALEB_PORZIO: Interesting. I've been using Copilot and I love it, but to me it's, it is useful. It's not just a novelty, but it's hard for me to see how it could really impact a career in development. 

AJ_O’NEAL: Well, so think about it this, like for junior developers, and I could be wrong, but I imagine it's a huge boon to junior developers because you're struggling to get code that compiles period versus you get code that will work that maybe isn't the best code, but it will work at all. And that is the most important step. So if you can describe what you want to do and hit tab, 


AJ_O’NEAL: and have it fill out your loop according to the variables that are in scope. 

CALEB_PORZIO: Yep. That's pretty powerful.

AJ_O’NEAL: Right. I use tab nine for a little bit. And it was cool. The novelty it's, it's similar, but they have not reached the point of multi line statements. 


AJ_O’NEAL: So copilot was a big jump from tab nine and kite, which have been the leaders in the space. 


AJ_O’NEAL: At least as far as I'm aware, do you know of other leaders in the space? 

CALEB_PORZIO: No. This is kind of new to me.

AJ_O’NEAL: But Copilot just kind of leapfrogged. And what kind of stinks is they stole Kite's branding. So they basically got the SEO of Kite on the first day because Kite's slogan is a copilot for your code. 

CALEB_PORZIO: Oh really? 

AJ_O’NEAL: Yeah. So like on day one, they basically stole all the SEO of the top competitor. And if somebody feel free to troll me or not troll me, but correct me or troll me, whatever. If I'm misrepresenting that, but if you Google Kite, it says a copilot for your code. And I don't think that it could be the opposite way around, but I'm pretty sure Kite's slogan was that already. Anyway, but yeah, copilot, because Microsoft owns GPT, more or less they're like an exclusive sponsor with exclusive rights to certain parts of the API or something like that. So like started as an open collective, but now it is owned by Microsoft or some such. 

CALEB_PORZIO: Yeah, there's, I mean, I think like all the infrastructure for like open AI is on Microsoft Azure. I'm sure there's like, you can see Microsoft's logo on their page. 

AJ_O’NEAL: Yeah. So anyway, it's just a huge leapfrog to actually construct multiple lines of code at a time. Cause I don't, I don't, I wasn't using kite. So I can't say for that one. I know that tab nine had that on their nearest term roadmap, but with co-pilot releasing, it may just destroy those two products. We'll, we'll have to wait and see because it's just, it's leapfrogging. And I think it's really cool that it can generate the code. But what I found in tab nine, at least I haven't tried copilot because I don't think their VIM plugin is released yet. I think it's only VS code right now. But it did help me to code faster. Like maybe it may be 10 or 20% faster at coding. But it wasn't, it wasn't sticky enough for me. And there were times where like I'd want to use the tab key. And then it would just fill out code that I didn't want. And that was really annoying. 

CALEB_PORZIO: Yeah. That's a lot of the co-pilot experience. I really do like co-pilot, but there's a lot of hit tab or a lot of trying to not hit tab, but still, there's a lot of that. And then there's also a lot of like removing semi-colons as a JavaScript developer who doesn't use semi-colons. It's like, 

AJ_O’NEAL: why aren't you using prettier? 

CALEB_PORZIO: Yeah, I don't know. I've I've used it. I just don't use it. 

AJ_O’NEAL: Well, I love prettier because you put the pretty RC in your project and now there's no debate or question. I just, I love that it eliminates and even in projects that aren't JavaScript projects, like I will, I've made PRs to add a pretty RC to go projects so that the markdown is correctly formatted and, and that, you know, I just love the idea that anybody can use their editor of choice and they can edit any code on any project. And if there's a pretty RC, the pretty RC will make sure that your PR isn't adding extra spaces or removing them or, you know, doing things that the author is going to nitpick about or that you're going to be like, Oh crap. I shouldn't have hit the auto. I shouldn't have let it auto save. I should have, you know, 

CALEB_PORZIO: Yeah, I have a weird, there's a few decisions in prettier that I don't love. So that's probably, that's like the actual reason 

AJ_O’NEAL: I agree. I, I, there's some things that I hate about prettier, but yeah, the alternative deal, especially with teams 

CALEB_PORZIO: being in a team. I wouldn't, if I, any product I've worked on in a team, I would use some sort of whatever, I can't think of the fricking word for what prettier is a linger, but there's some, I have this weird like thing, this romantic thing where it doesn't, it feels like not as handmade to me. The code I write, like I want there to be like, if I was making pottery, like you could take machine made pottery and it's just not as beautiful as handmade pottery. Cause you can see the finger lines. Like, 

AJ_O’NEAL: so I, again, I really, really strong opinions on that, which are very the opposite direction. Cause I just so much crap in the coding community is because people are like, my code is my art. And my argument is no, your art is what other people are able to accomplish with your code. Your code should not be your art. 

CALEB_PORZIO: I disagree. 

AJ_O’NEAL: Obviously, obviously, but I just see, I just see 100% it's problematic and I see it's 0% helpful to treat the white space and the lines of the code. But again, we can have different opinions on that. And at least if we work together, you'd agree to use prettier so we could get along just fine.

CALEB_PORZIO: Yep. We'll do it. 

AJ_O’NEAL: And I'd agree to use something else as well. I, you know, I just prettier. I don't like all of his choices, but it's popular. I hated that stupid standard JS. Well, that, that made my blood boil because it's one of those tricky marketing things. Like he stole the word standard, you know, like he re-appropriated. When people re-appropriate things into that. 

CALEB_PORZIO: Yeah. Well, he wasn't, 

AJ_O’NEAL: I don't think he was a newcomer. 

CALEB_PORZIO: I think, no, I mean a newcomer in a JavaScript scene, some seeing an offering like that would be fooled into thinking that it's standard.

AJ_O’NEAL: Like I, part of me admires it because it's like, hmm, you just like the, the strength and sharpness and power of what you did and the impact you have. I admire that you were able to do it, but I feel that reappropriation is a dirty trick that morally I don't agree with. 


AJ_O’NEAL: But, but anyway, I mean, I, I, I'm pretty sure I've done it myself once or twice. So I've got a little bit of self-loathing on that, but anyway, we are. You're getting off into other topics, which I think is just fine, but we are running up against time and I think we talked about Alpine. We talked about microservices. We talked about coding tools. This has been an awesome episode. Uh, is there anything else that you think we should hit on before we wrap things up? 

CALEB_PORZIO: I'm good. 

AJ_O’NEAL: All right. Well, Caleb, uh, it's been great to have you on the show. Yeah. I've enjoyed that conversation. Uh, Amy, I know that there were a couple of times where you had something you wanted to ask or say, did. Do you still have any of that? 

AIMEE_KNIGHT: I don't. I mean, really you answered my question about the web components. And I am also a fan of the vanilla JavaScript and listening to this episode after doing dev op stuff for like pushing a year now and realizing how much I am out of the loop of the back and forth and everything that's happening. So you answered my question. 


AJ_O’NEAL: All right, well, Caleb, how do people find you and Twitter? 

CALEB_PORZIO: Twitter. Find me on Twitter. That's all you need. 

AJ_O’NEAL: What are you on Twitter? 

CALEB_PORZIO: Caleb Porzio. Yep. 


CALEB_PORZIO: Nailed it. 

AJ_O’NEAL: For those listening and what I can read it. I'm reading it off the zoom, but, and we will, we will make sure to put that in the show notes along with what I said. I said I was going to get the Ethan Garofalo link in there. All right. Well with that, let's go ahead and do picks. 


I remember working my tail off to become a senior developer. I read every book I could get my hands on. I went to any conference I could and watched the videos about the things that I thought I needed to learn. And eventually I got that senior developer job. And then I realized that the rest of my career looked just like where I was now. I mean, where was the rush I got from learning? What was I supposed to do to keep growing? And then I found it. I got the chance to mentor some developers. I started a podcast and helped many more developers. I did screencasts and helped even more developers. I kind of became a dev hero and now I want to help you become one too. And if you're looking forward to something more than doing the same thing at a different job three years from now, then join the dev heroes accelerator. I'll walk you through the process of building and growing a following and finding people that you can uniquely help as you build the next stage of your career, you can learn more at dev heroes, accelerator.com. 


AJ_O’NEAL: Were you made aware of our picking system? 

CALEB_PORZIO: No, not at all.

AJ_O’NEAL: So basically, you can be anything. You can pick stuff that you've made or that you wanna plug. You can pick stuff that you use, that you love. On occasion, it's okay to do an anti-pick. And then you can just pick anything in general, a book, a movie, a poem. It's your opportunity to express you what you think the world deserves to know more about. So we're the only three of us. Normally we let the guests go last so that you have some time to think. But if you've got something on the tip of your tongue. Go ahead. 

CALEB_PORZIO: The first thing that popped into my head, YouTube channel called 3Blue1Brown. That's like a guy who used to be a Khan Academy instructor. He just does an incredible job explaining high level math, but also things like AI, neural networks and blockchain and stuff like that. He just explains really high level things visually and his visuals are incredible. Just one of those things you see like primitive technology drop another YouTube channel. I guess the equivalent of a primitive technology type of dedication too to their craft and so I've been sucking those down the past few days. So that's what comes to mind. That's my pick. 

AJ_O’NEAL: All right, cool. And Amy, do you have anything? 

AIMEE_KNIGHT: I do. This looks like a fun repo I saw a couple weeks ago. And it's since we're talking about tooling and stuff. It's a list of isn't an awesome thing. It is. I'm seeing GitHub awesome repos, but it's JS tooling not in JavaScript. So I thought it was kind of fun based on what we're talking about. And I like your comment about the anti-pick. I'm going to anti-pick the IRS because I'm really frustrated because I've been waiting over four months for a substantial refund that I could have invested earning much more interest on what... Because I guess my accountant said that you do earn some interest once it reaches a certain amount of days over, but I'm sure that I could be earning more interest. And I'm just very frustrated because I go to the website every single day and it says I don't have an update and I'm paid for an accountant to file my taxes and there are no mistakes. So I don't know what's taking so long and I'm very frustrated. So that's my anti-pick. 

AJ_O’NEAL: So I know somebody what she does is she fills out some form to delay paying her taxes, put it in, puts it in investments, and then withdraws it at the next year to pay the taxes. So she's earning and she's pretty smart. So I think she's earning over seven percent, like she's she's well versed in financial markets. So I think she earns over seven percent on her taxes over the course of the year. 

AIMEE_KNIGHT: I'm extremely frustrated right now. 

CALEB_PORZIO: Every if you just as soon as you do that once, you only get that benefit once. Cause then every other year you're back to just doing your offset. 

AIMEE_KNIGHT: Oh yeah. I think I have heard that. Maybe she's got some other loophole. 

AJ_O’NEAL: I don't know. But. 

AIMEE_KNIGHT: So I don't know what's going on, but they owe me money. I understand why this is my money. They owe me. I want it back. I want to have it invested in my fidelity account. 

AJ_O’NEAL: They have to print it first Amy. 

AIMEE_KNIGHT: I want it earning 14% interest like the rest of my investments. Very frustrating. 

AJ_O’NEAL: Well, dang, you got to tell me about your.