567: Full Stack Dev, Load Bearing Developer, and Being Zod Curious
What do you do if your computer dies? Chris applies to work at Luro, Dave applies at CodePen, Dave's Zod curious, TypeScript, sorting out a 10MB blog post, and how much do you miss jQuery?
Guests
Chris Coyier and Dave Rupert
Time Jump Links
- 00:37 What do you do when your computer goes down?
- 09:39 How does one avoid the general pressure to become a "full stack" dev?
- 25:39 The load bearing developer
- 27:04 On a scale of 1 to 10 how much do you miss jQuery?
- 32:59 How Zod curious are you?
- 43:13 Do you have any resources or tips for learning TypeScript?
- 50:35 Design system in layers
- 57:33 The 10MB blog post
Transcript
[Banjo music]
MANTRA: Just Build Websites!
Dave Rupert: Hey there, Shop-o-maniacs. You're listening to another... Chad:
Chris Enns's prerecord of the post. [Laughter] Anyway, Chris is going on a trip, and we love Chris. Love to support our podcast editor.
Hey! But I go the other Chris, Chris Coyier here in the studio.
Chris Coyier: Yeah.
Dave: How are you, Chris?
Chris: I'm all right. Pretty good. Pretty good. Pretty good.
This will come out days after this has actually happened to me, so I hope (for my own future self's sake) that this is resolved. But at work here, I have a Mac Studio. You know what I mean?
Dave: Hmm... Mm-hmm.
Chris: It's a little gray box.
Dave: A cool one, yeah. Yeah.
Chris: Yeah. Yeah. I just thought I would try it out. This is - I don't know - at least a year ago I decided to get it, probably shortly after it was released, thinking, "I'm just going to have a work machine that's just always here. It's always on. It's always plugged in. It's always ready to go. It's beefy, powerful."
Dave: Mm-hmm. Most powerful.
Chris: This is going to be the new me.
Dave: Yeah.
Chris: Don't really regret it. It's been really great. Retrospective. I love all the ports on it. There are a zillion ports on it. It doesn't need any extra thing. It really is a powerful machine. It looks good. I don't know. No real regrets there.
Dave: I've got questions about the laptop.
Chris: Yeah.
Dave: When you do work on a laptop, is it just like, "Where are my file?!" Or do you feel like you're mostly--?
Chris: Well, the thing is I work on... I'm like 50/50.
Dave: Okay.
Chris: Straight up, so the machines are really in sync.
Dave: Okay.
Chris: The dev environment works on both of them just fine. Everything is fine. I Dropbox files, but I'm not that heavy on using files.
Dave: Mm-hmm.
Chris: It gives me good Git hygiene because I'm always making sure everything is Gitt'd up so I can pull and make sure both machines are fine.
Dave: Yeah.
Chris: And I use Arc, which keeps all my tabs the same, so it's like nothing ever changed in my browser. It keeps everything in sync nicely there.
Dave: Mm-hmm. Mm-hmm.
Chris: Yeah.
Dave: Pretty seamless. That's nice.
Chris: It's pretty seamless. Although, I get to work, and I was doing something. I was just about to hop into this Riverside FM room to do a show with you, and I noticed my monitor was blank.
Dave: Mm-hmm.
Chris: I'm like, "Oh, that's weird," so I hit the keys. I clicked the mouse a little bit to try to get back on. And it's just off. The computer is just off.
Dave: Hmm...
Chris: I'm like, "Wow, that's not good." [Laughter]
Dave: Yeah. [Laughter]
Chris: So, I go click the button to turn it back on. It doesn't turn on. And I'm like, "Oh, that's weird." I unplugged the whole power strip. Everything in the room goes dark. I'm like, "Oh, I guess I've got a lot of stuff plugged into that.
[Laughter]
Chris: I plug it back in. It should be good to go. Press the button and it won't. it's just off. The computer will not turn on.
Dave: Uh-oh!
Chris: I was like, "Oh, my God!" Of course, I have all this cable management. We went on that bender.
Dave: Yeah, yeah, yeah.
Chris: It's probably 80% as good as it was at its best. It's still in pretty good shape, so I had to go underneath the desk and un-Velcro stuff, so I just extract the Mac Studio from the office and try another plug. I'm like, "Ah, maybe it doesn't have enough juice or something." I don't know
Dave: Yeah.
Chris: It would make a little blip. There's a little light on the front of it. Doop.
And then one time I got it to chime, and I was like, "Ah. Phew. It's back. Good."
Went back to the desk, plugged it all in. Nothing. It won't go. I'm like, "Gosh, is it the desk?" I go try another outlet. It's behaving badly, but I do get it to chime once. I was like, "Okay."
Go back to the desk, and it won't go. Is it the desk? I kind of don't think it is.
Dave: Yeah.
Chris: Then at the desk, I got it to chime, and then I get everything plugged into it, run around to the front, "Ah! It's off again!" So, it just likes shutting off. It won't even get halfway through a chime sometimes. It just shuts off.
Dave: Wow. Man.
Chris: All right, so here's the thing. That's just the computer thing. Boring computer story. Nobody cares. I'm sure I'll resolve it somehow.
Let's say I can't resolve it. Things have got to go back to Apple. It happens all the time to people, right?
What do people do? I am solved. I have another computer. I even have a booth computer here.
Dave: Yeah.
Chris: I have options, man, but I have options because of privilege and history and choice-making in my life. Most people, I would think, have one computer. That seems like the right number of computers to have for a person.
Dave: Yeah. Yeah.
Chris: But I am curious. If you live in New York City, maybe you can just run over to the Cube and they've got a million people and they'll fix it for you. I don't know.
If I have to send this thing in, which is seeming really likely, we're talking two weeks. If I'm a freelancer, I'm screwed.
Dave: Yeah. That's a lot of time to be down.
Chris: Screwed.
Dave: Yeah.
Chris: I don't understand. I just want to understand the logistics. What do actual people do? Do they just go on vacation? Do they open up their phone and email their clients and be like, "Oh, sorry. My computer is having trouble. I'm going to be a little out of pocket for a while until I get my computer back," and their clients just understand? Is that--?
Dave: I know one guy. He used to just buy a computer on a credit card and return it.
Chris: [Laughter] Hey, that's a real--
Dave: Yeah.
Chris: That's the logistics of what we're talking about.
Dave: Then when yours is fixed, you just return the one you "borrowed."
Chris: Yeah.
Dave: That might be an option.
Chris: If you work for Dropbox or something, maybe you just tell your IT department and they just give you another one or something. It makes it their problem.
Dave: No, but that even seems like, yeah, you tell the IT. Do you just not work for a few days? [Laughter] I can't imagine that's like, "Oh, where's Dave? Oh, he just said his computer doesn't work, so he hasn't checked in for like five days." [Laughter] You know?
Chris: Mm-hmm.
Dave: What do you do there? How do you get a computer if your computer broke? I guess your phone, Slack, and stuff. But then... yeah.
What if you get fired or suddenly laid off, which has been happening? And that computer was your--
Chris: Was the company's?
Dave: The company's and now they want it back.
Chris: Yeah.
Dave: What do you do? I've never really been in that situation. I've always used my own hardware. I guess I've used other people's hardware, but that was always like a second computer kind of thing.
Chris: Yeah. It's funny how often that was. I don't have as much job experience as a lot of people do. I only worked at a handful of tech companies that they were small enough or understanding enough or something that when I started there I was like, "I use my own hardware," and they were just like, "Okay."
Dave: Mm-hmm. Yeah.
Chris: I, for some reasons, just didn't want a second machine. I don't know. It bugs me for some reason. I know I run two machines now, but they're both mine. I do whatever I want with them. Whatever. Usually, in the past, I've just had one laptop.
But I remember. I think I was -- this is ages ago -- at Estelle Wilde's house, which she does a lot of contract work, and she had a just stack of MacBooks.
Dave: Macs, yeah. Yeah, yeah.
Chris: Just a stack of them, like this one is for that company, this one is for that company, and maybe she wanted it that way. It probably seems like it. But she may not have had a choice. Like if you roll into Salesforce - or whatever - and say, "I'm going to do some contract work with you," they give you that machine.
Dave: Yeah. Yeah. I think Brad Frost is going through the same thing. I've seen his decks. He almost needs a Drobo, that hard drive thing where you slot in different hard drives. He needs that but for computers because there are just so many client computers.
I appreciate that idea because it's just like, "All the security is there. Don't worry about it." But man, it is a lot of work. It's a lot to juggle. But, hey.
Chris: Yeah. A lot of juggling. Anyway--
Dave: I guess you get paid. Make sure they're paying you for that trouble. [Laughter]
Chris: We'll see what happens when I send this big ol' beast back to Apple. A little extra pain, too, for us that live out in the country or whatever. Not near a major metropolitan area.
Dave: You can't just walk up. I don't think you're super put out. If I would try to make a reservation at an Apple store in my town that has two Apple stores, it's like days out.
Chris: Oh...
Dave: You know.
Chris: Yeah.
Dave: There's no such thing as quick anymore.
Chris: Because Austin is just popping with people. Yeah, I wonder if I almost have it better. If I had to go to an Apple store, I could drive there, and the fact that it's not Austin means that I could get in earlier. Yeah, maybe.
Dave: Yeah, and there may be a guy two towns over, "Terry's Mac Computers," you know, and Terry knows how to fix it. Terry just has a weird... He got an Apple license, reseller, whatever, license in the '80s and has just hung onto it. There might be somebody like that.
Chris: We should do some questions from some people here.
Dave: Questions and answers for your question and answer podcast. I had one come through. Let me see if I can find it.
"Hey. I recently visited your website and noticed it could benefit from some SEO backlinks to improve visibility of your show."
Chris: [Laughter]
Dave: Hey. Thank you so much, Martha. We are not interested in your spam crap. Oh, my gosh.
Chris: A lot of that. We're at 50% spam, I'd say, on the incoming form there. What are you going to do? What are you going to do? At least it's protected by some kind of... I mean it's in an iframe, people. So, somebody probably had to fill that out.
Here's a classic one from Ryan F. "How does one avoid the general pressure to become a full stack dev? I'm perfectly happy doing front-end work and don't want to learn any back-end dev in any deep way. I'd rather spend that time polishing skills like performance, accessibility, browser APIs, and then pick up huge new back-end skills. However, I'm not in the industry or the longer I'm in the industry, the more I feel like I get pushed into doing these things."
Yeah, we've heard this kind of stuff before. Right? Although, I think, Ryan, you have something going for you in that what you're trying to avoid is specifically back-end stuff. But it doesn't sound like you're trying to avoid anything else.
You might be kind of good here if you're saying learning performance is on the table for me. Learning browser APIs (meaning probably deep JavaScript work) is on the table for you. Learning accessibility is on the table for you.
If you knew all that stuff and all your classics, that makes you pretty darn employable still. So, I think this pressure that you're feeling to become a full stack dev, meaning learn Ruby, Python, Go, and stuff, eh. I don't know. Call yourself a React dev.
Dave: Yeah. Just pretend full stack like everybody else. [Laughter] That's a great thing.
I think, for me, it is more about demonstrating that you can deliver an entire feature. Does that make sense? Maybe you don't need an entire feature. Maybe that's asking a lot. But just like, "Hey, if I'm going to ask you to roll out a comment system," this is kind of my classic example, a comment system, "do you know how to do that? What pieces need to happen? Then do you know where your knowledge stops?"
I'm giving away the Luro interview questionnaire. But it's like, "Do you know where your knowledge stops?" The tricky thing about comments--
Chris: That's fun! I like it!
Dave: Oh, here. I'll interview you. Hey, Chris.
Chris: Yeah.
Dave: Welcome to Luro.
Chris: Yeah.
Dave: We're a billion dollar company.
Chris: Uh-huh.
Dave: And we love to hire great talent.
Chris: Yep.
Dave: And looking to see... make sure your solutions--
Chris: So excited.
Dave: --fit our problems. Sorry, I was late. My Tesla was... [Laughter]
Chris: Hmm...
Dave: Yeah, my electric Lamborghini. Anyway... [Laughter] Let's just walk through.
Chris: Do you have any questions for me? I'd love to, you know, have you feel out my rough edges here. What do you need to know?
Dave: Yeah. Yeah, so let's hypothetical. We're building a comment system. What comes to your mind? What are we going to do?
Chris: Comment system?
Dave: Yeah, we're adding comments to the app. What kind of stuff are you thinking about? What would we need to do? How would you approach that?
Chris: Man, a lot of stuff comes to mind. A lot of stuff comes to mind because I think of... you know I tend to be a product-driven person, so I'd want to think where are these going on the existing site. Where does this comment section live? And then what is the ideal experience like? If we could start this from a user experience perspective, what's the perfect thing to happen?
I'd like to have that in mind, and then I would think about, like, okay, then what. Now what? What steps need to happen to make that thing a reality?
Then along the way, we'd be having frank conversations (hopefully) about the most important aspects of this. Let's say our dream system is actually a dream. What are the nice-to-haves? What are the must-haves kind of thing?
I think of stuff, for example, like at some point somebody needs to type some stuff into a text area. Hopefully, we can make that a nice experience for them. But is it a rich text area or is it just a text area? Is Markdown supported or not? Do they have to type in their email address and approve the comment or is it social auth or not? That kind of thing.
We have our list of what we want the ideal experience to be like, and then maybe we'd shop it around a little too, because there's always build versus buy.
Dave: Mm-hmm. Mm-hmm.
Chris: There's always, is there something out there that solves this problem which you just cut a check for? Then what's the culture of the company now? Are you kind of a build or buy company? Do you already have an existing philosophy on that kind of thing?
I think we should probably move forward from here from a build perspective because if there's a buy, then you buy it, you integrate it, and hopefully, that's pretty straightforward.
Dave: Yeah. Yeah.
Chris: But if you're going to build it, I can help with some of it, maybe a lot of it, but probably not all of it. I could help with the design of it and the UX of it and the testing of it. I could probably help out with the implementation of it from an HTML and CSS perspective. I could probably help out from a JavaScript perspective of validating the content if it needs to be in some way, and the user experience around that. I could send off the data to a server.
But I'm not hugely a database guy. I would hope that you would have somebody smarter than me at data storage because that person, I think, is going to think about what kind of database does this belong in, what are the security implications of it, how does it interface with the data that we already store?
It's just not my forte. I could participate in those conversations and bring the expertise that has happened in the past for me. But I'm probably not the guy you want to hire to implement the data storage of your comment system.
Dave: Yeah. Pretty good answer. Pretty good answer. I feel like we've talked before. But hey, so... no. Sorry. Breaking the fourth wall.
Chris: Got any crypto?
Dave: That was a great answer. I think that's exactly what I would hope somebody would say, like, "This has all these things, like the product stuff I can do. The HTML, I can assist in all that, to that part, and I can send it off to an API. But at that point, we could get there. I could theoretically do that, but it's better if somebody else is knowledgeable who really wants to own that and picks that up." But I think that's a really great answer.
For me, comment systems are easy. It's a crud app. Add a comment. Boom. Blam. It's a text area, and then you save that to a database, and then you show the text area related to some model.
Where comments get tricky for me is, okay, I'm going to @mention somebody now. Okay.
Chris: Ooh...
Dave: Then they get a notification that fires when that @mention happens.
Chris: Mm-hmm.
Dave: Oh, now we have notifications. Now we have a whole permission system we have to build. For me, a comment system is pretty easy. But a good comment system is pretty hard. You know?
Chris: Yeah, with upvoting and downvoting. What about that? What about - I don't know.
Dave: Reaction emojis or whatever.
Chris: What's really difficult is content moderation with the comments. You'd like to think you could stop spam a little bit, but bad human behavior is tricky. Social login might help a little bit with that but probably not enough. Every comment needs to get looked at.
There are still some technical difficulties, too, like are you doing nested comments, because then you need to deal with parent-child relationships and such. Then you have to think about edge cases like what happens when the parent gets deleted. What happens to the children? There's all kinds of stuff.
A comment system is about as complicated as any other app is.
Dave: For me, it's the perfect feature question just because it is this line between it could be simple or it could be stupid complex, and you get to see how people think. But anyway, I liked your answer, Chris. I think you are just very honest.
Chris: I missed the content moderation. I really wish I mentioned that during the initial one because that's a huge one. People are just like, "Let's add chat," and you're like, "Are you going to?"
I always remember that book Designing for Community, and that was one of the great chapters in it. It was like, "Yeah, you're going to have somebody watch that chatroom 24 hours a day, 365 days a year. No? Well, then you're not having a chatroom." [Laughter]
Dave: Yeah. Yeah, like, "Let's put forums." Brother, have you ever been on...?
[Laughter]
Chris: My brother in Christ, have you ever been on a forum?
Dave: My brother in Christ, have you been to reddit.com?
Chris: Yeah.
Dave: It is simultaneously awesome and possibly illegal...
[Laughter]
Chris: No doubt.
Dave: Yeah. Back to this question. Ryan, you don't need to be full stack. I think you could even start that with, like, I hesitate to call myself a full stack developer or something like that, but I would probably also lean into I'm able to identify the problem, build requirements so I can assist in all that.
For me, it's more like, "Tell me where your knowledge stops and then what needs to be done after your knowledge stops so I can either hand that off to somebody else, do that myself," or if it's an offshore company situation, hand those requirements to offshore, and you're happy managing that part of it. That would be a load off my shoulders.
Chris: Hmm...
Dave: I would apply for the full stack jobs, but I think I would also just be transparent about when your skills plateau or you're not specialized in that area or something. I do think there needs to be an awakening. Not everyone knows.
It's increasingly harder to know this full-stack thing. There's a lot going on in every website.
Again, what is our new mantra? Ruthlessly eliminate nuance.
Chris: Yeah.
[Laughter]
Dave: There's a lot to know, so the idea that you could just be prolific in everything, probably not. If I interviewed for CodePen or whatever, I don't know Go, so I would have to be very transparent about I don't know Go. I don't actually use React, so I'd like to have a job at CodePen here, but those are two things I don't do, and that seems like a big, important piece of your stack. I'm willing to learn, but I don't know if y'all want to pay for somebody to learn that.
Chris: I don't know either. Although, we hired a guy. This is a little while back, but I'm just seeing this week. I'm like, "Wow, we made your whole job Go. Sorry about that." [Laughter]
But just all of a sudden. The first two, three projects weren't.
Dave: Yeah. Yeah.
Chris: But then we were like, "We need you on this." But the thing is, you're in the same category as this guy. You've been around a while, Dave. You're smart. You've learned a bunch of languages. It's just a language. And if you get dropped--
Not only is it just a language, but if you get dropped into a codebase where it's already all spun up and working and doing all the stuff that it needs to do, you're not really writing it from scratch. You're like, "Oh, I see what's happening here. I'll just open that file in VS Code because I've searched in project and found the relevant file that's happening. I'm just going to alter it and then do whatever the console.log of it is, which, in our codebase, is our own little bespoke logging function. I'm just going to call that a bunch.
Dave: Mm-hmm.
Chris: And output the stuff and see how it works. Oh, I need to make a Web request. I'll just Google it quick. Oh, it's not Fetch anymore. It's http.post. But it's not that different.
Dave: Mm-hmm. Yeah.
Chris: I just need the....
Dave: Yeah.
Chris: You don't know Go, Dave, but you kind of do. It's really not that hard.
Dave: Yeah, right. I do personally get tripped up on syntax and idioms in the language.
Chris: Yeah.
Dave: Like, "What's the Go way? What's the Rails way?"
Chris: Mm-hmm. But if there's a whole code base around it already--
Dave: Yeah, then I can copy-paste my way through the problems. [Laughter]
Chris: Yeah, maybe. But yeah, maybe your brain doesn't want to do that.
Dave: Yeah, but I think I could because that's the thing. For me, in back-end specific stuff, the problem... the code, the language is not the problem. It is suddenly, mistakenly (even through a code review) finding yourself in an ON-squared problem, or something, which I don't even know big O notation, but I just know when I made an uh-oh and now my for loop inside of a for loop inside of a for loop is now spitting out logs.
Chris: Yeah.
Dave: We wrote three million records to the database in a week on an app with not that many customers. [Laughter]
Chris: Hmm...
Dave: We just had a cron job that just notified the database, like, "Hey, I did it." But then it was running times five or something like that per user or something like that.
Chris: Oops.
Dave: Yeah, and this sailed through code review. We knew it might land a little rough and that's fine. We reviewed it, and we had talked about, even. We were like, "This may be a thing we don't want to do. It might create a bunch of noise." But yeah, I know where it was like, "We're going to write three million records in a day or two days. Was that on my list?"
Chris: Yeah. Now all of a sudden, you're responsible for that. It's not so much can I do these basic things I need to do. It's kind of expected that you're a little bit more proficient of a programmer that even if you caused that problem, that you could solve it too.
Dave: Right. That's kind of the hope is you can identify why and how. I can't say I did a really great job, but I think we figured it out. It was actually a PR branch was causing some errors to the tune of like 4,500 errors a day - or something like that. So, our century was filling up. Our Logtail logging application was filling up. Then they're rejecting calls, breaking the app because stuff has fallen.
Chris: Mm-hmm.
Dave: I just was like... It was just kind of a full turducken of surprises. All this to say I don't think the language mattered. [Laughter] I could have been writing Go. I could have been writing JavaScript and had the same problem.
The thing about whatever applications, full-stack to me is really more about getting a sense of what can go wrong. Back to my comments, example. A comment form is not the problem. But a comment form hooked up to a notification system is a problem. That's hard, in my mind.
Chris: Very interesting stuff, Dave. I also think a little bit that you're so used to being the load-bearing developer, which is good and important.
Dave: Is this therapy right now? Are we going through therapy? [Laughter]
Chris: Well, maybe, or perspective alignment or something. A lot of people are, and those are the most important, powerful developers there are. But I think, in the end, there are so many developers out there that aren't.
Dave: Yeah.
Chris: They're just on the team, and it doesn't mean they're not as good, necessarily. But they get into trouble that they can get out of trouble, that 100% of the buck doesn't necessarily stop with them. It totally does with you.
Dave: Yeah, that's sort of job title situation for me. But yeah, I think people can skate and get help. I think that's okay. Just in terms of somebody marketing themselves, just be like, "Hey, I can do this, and then my skills sort of stop here." I think that's very helpful to somebody who is hiring.
Chris: Indeed. We've got one here. It's a good one from our friend Russell Heimlich.
Dave: A longtime listener. Hey, Russell.
Chris: Russell: "On a scale of one to ten, how much do you miss jQuery?"
Dave: Ooh...
Chris: Hmm... I read this today and, this morning, I wrote a little jQuery, ironically.
Dave: [Laughter] Ironic jQuery?
Chris: Yeah, well, I don't know if irony is the right word. I mis-used it like a plebe there, but I think Andrew (in the Discord) had a thing where he's got an auto-width element. And not auto like a div where it fills the area, in which case I think this would be an easier problem because auto ends up behaving a lot like 100% does, and then it gets easier.
But let's say it's a button element, which you don't know how wide it is because it's an inline element or an inline-block, or whatever the default for a button is. It depends on the size of the text that's in there.
He's like, "Okay, it's inline, but I know that I want to grow it 15% on either side," so 30% bigger it needs to grow.
Dave: Mm-hmm.
Chris: But do it in CSS. You're like, "I don't think you can." I don't think you can say, "Make this thing 30% bigger, essentially," when it starts out as auto.
Dave: Yeah. Yeah.
Chris: If you knew the width of it, it's easy.
Dave: Right.
Chris: But it's just hard to do. Scale X could do it, but he cut that off at the pass and said, "Can't do scale X." For one thing, it's text, so the text will warp. That's not good. Maybe you could do it with the parent of the thing and not a span inside of it or have a counteracting thing inside.
I'm not saying there's no way to do this. It's just definitely not very straightforward. But he said not even that because it has a very specific border radius on the button and the scale X will warp the border-radius, so that was out.
I think you had an idea.
Dave: I think I kind of misunderstood because if it's 231 pixels, it needs to grow 15%. Let's just do 10% because of math.
Chris: Yeah.
Dave: But it needs to grow exactly 23.1 pixels - or whatever. My thought was before or after pseudo-elements that added 5% or 7.5% padding - or whatever. But I don't know if that would be the width of the element itself or the parent, so that's kind of--
Chris: Yeah. That might work. Uh... I don't know. That's something to think about.
It's width only and not height. If it could do height too, then you could just use regular scale and it would leave the border-radius alone. But what do you want the behavior to be? Is it okay to overlap the text around it or is that not okay? If it is okay, you'd think those pseudo elements are extra easy because they could just be absolutely positioned. Then they just grow in size and it's fine.
Hence Russell's question was about jQuery. I was like, "Uh... jQuery has got this! I used to do crap like this all the time in jQuery."
Grab a reference to the element. Then use .outer-width on it, so you've recorded now. You know what the width is now because you just measured it. It started off as auto, and it still is auto in CSS, but JavaScript knows exactly how wide it is. 321 pixels, like Dave said.
Dave: Mm-hmm.
Chris: Now because you have the number, you can animate it to that number plus 30%. Easy. Then that's on hover or on mouse enter or mouse... Mouse. [Laughter] What are the two?
Dave: Leave or--
Chris: Mouse enter and mouse in or something. There are always two that always confuse me.
Dave: Mouse off.
Chris: Mouse on?
Dave: Mouse off.
Chris: [Laughter] I can never. I would fail that interview question. What's the difference between mouse off and mouse leave? There is one.
Dave: [Laughter]
Chris: But I can't remember what it is.
Dave: Well, there's mouse up and mouse--
Chris: Mouse down.
Dave: Enter. Mouse leave.
Chris: But there's two for a mouse leaving.
Dave: Mouse up. Mouse down. Mouse...
Chris: It's not mouse off. Although, that would be an awesome... Mouse off.
Dave: Oh, yeah. Oh, yeah. You love JavaScript. Name every mouse event. [Laughter] Yeah, okay.
Chris: I thought there was a different leave. Maybe I'm wrong. Okay. I'm overthinking it.
Anyway, I wrote it up in jQuery because I was like, "Oh, I could write this in vanilla JavaScript," but it's almost more funny in jQuery using all those jQuery-specific isms.
For example, I started the Pen with $() and then immediately put a function inside the parentheses.
Dave: Ooh, yeah. Nice.
Chris: That was that old school DOM-ready shortcut.
Dave: Yeah, immediately invoked... yeah, a function.
Chris: Yeah, but it's not quite because it's the jQuery version of an immediately evoked function expression.
Dave: Yeah.
Chris: I don't know why they ever made that work, but that was cool. Then it kind of saves a reference to the button that it selects.
Dave: Mm-hmm.
Chris: Then uses the outer width function and not width, which matters because width didn't take into account padding or something. You had to kind of know to use the right one.
Dave: Oh, this is so good. Chaining your on mouse enter, on mouse leave.
Chris: Yeah, which I forgot to use.
Dave: Miss chaining. I miss chaining. I liked that, how everything was chained. You know?
Chris: Yeah.
Dave: Some stuff in JavaScript, like array methods, you can chain. Only sometimes because some don't return.
Chris: Mm-hmm.
Dave: Some return a clone and some modify the thing.
Chris: Chaining has held on, I think, as a cool API. It just turned out we didn't need it for jQuery. But twice I've used it recently in the API that made sense. One was--
It's generally used in puppeteerish things, like Cypress. Cypress's API is very--
Dave: Mm-hmm.
Chris: Testing is chaining. That element is not - whatever.
Dave: Yeah.
Chris: There's a bunch ... chain that. Then I was using Zod.
Dave: Ooh... Yeah.
Chris: Did you see that? Did you see the Zod?
Dave: I know Zod, yeah.
Chris: Oh, man.
Dave: I'm Zod curious, I'd say, right now. Yeah.
Chris: [Laughter]
Dave: I can go further into that statement later.
Chris: It's client-side data validation, which is, I think, a way to think about it so that you can craft some code, call a Zod function, and then be told if it passed validation or not. If you're ever in that moment where you're like, "I'm writing custom validation functions," know that there's a very small library that kind of standardizes how you might write that data validation.
But then this is how I think of it. I'm sure the Zod people probably think differently. You get this side benefit where the little validator interfaces that you build can be exported as TypeScript types so that you just get that little benefit.
You can just export that and then you didn't have to... You don't have to then also write a TypeScript type. That thing can be used elsewhere.
Dave: Yeah. It's a validator or they say, "Parse, don't validate," or something like that. Maybe it's the opposite.
Chris: I don't know. It definitely doesn't replace TypeScript, though, because it's not like that. It's like you have to write Zod.
Dave: Well, yeah. You have to write the Zod. TypeScript types should compile out.
Chris: Yeah.
Dave: But I do like it as kind of a type replacement because sometimes you're just like, "Hey, before send this to the database, is this an animal?"
Chris: [Laughter]
Dave: Is this an animal? Does it have all the attributes an animal should have? Is it missing something? Send.
That's kind of what I want it for because there's actually an integration with Prisma, my ORM that I like.
Chris: Mm-hmm.
Dave: Where I can export those Prisma classes as Zod classes or transpile it or whatever, generate my Zods, and so then I could be like, "Cool. Is this a post? Does this have anything out of the ordinary for a post?" Like, "Oh, I'm sending errant data into my posts, and that's going to mess me up." That's awesome.
We have a couple of JSON fields. It would be cool to be like, "Hey, this JSON kind of has this structure." TypeScript actually would be kind of ideal for that.
Chris: Oh, yeah. Right.
Dave: But create a pseudo interface, like, "Hey, this is what I expect in here, and this one is optional, and this one is optional, but this one is kind of required," if it's a certain type of component or something like that.
Anyway, that was kind of a... I'm Zod curious right now.
Chris: Yeah. Yeah. I don't know. It's early days for us, too. We're just about to land a couple of PRs, I think, that put it in there. But you know.
It was a healthy discussion to have because we already have TypeScript, so you're already getting some kind of validation from that.
Dave: Yeah.
Chris: I realize they're philosophically different - in a way. And React, so there are some prop-type stuff checking data in that aspect of the code. That doesn't help all over the place, but it helps at the component level.
It's always obnoxious to me to know that you have to have a TSX component in React. Then you have to do both. It has to be TypeScript and it has to have prop types on it. I'm like, "Oh, suck it. I hate this." You know?
Dave: Yeah. Yeah.
Chris: And we've had lots of talks about JSON validation, JSON-specific validation. So, we have done work using JSON schemas (the official way to validate that), and we are using some of that, too. We're like, "Is this a fourth fricken' thing for validation?" [Laughter]
Dave: Nice, dude. Yeah.
Chris: But what you've lost is TypeScript is better than prop types. I would love to just rip all the prop types out of our entire app. But prop types are runtime, and TypeScript is not.
Dave: Hmm...
Chris: You know what I mean?
Dave: Mm-hmm.
Chris: Runtime data matters when stuff comes in from the server, user-generated content, whatever. That matters, but Zod saves that (in a way) is that if we got rid of the prop types entirely and were zodding more things. Zod is client-side. It's runtime.
Dave: Zod is client-side.
Chris: [Grunting]
Dave: Yeah. There's some benefit. Here's an example, back to the comment thing.
Let's say you're making a Twitter clone (like everyone is doing).
Chris: Yeah.
Dave: If I type @chris, that's a DM or something like that.
Chris: Sure.
Dave: TypeScript is not going to be able to be like, "If message starts with the at symbol."
Chris: No. No.
Dave: TypeScript can't do that.
Chris: As far I know, it cannot do that.
Dave: To my knowledge, yeah, so that's a place where you need this third validator or validator setup sort of thing.
Chris: Right because you could even talk string length and stuff. I don't think you can do that in TypeScript.
Dave: Totally. To comment on this website, you need to write the word "fart." And if it doesn't have the word "fart," I reject it. That would be a case, which I'm sure the Zod team is happy I'm promoting this use case above all things.
Chris: Yeah.
Dave: That would be a case where Zod would work perfectly. Comment must have comment.message-body. Must have word "fart butt," otherwise reject.
Chris: It would, and I don't know what the TypeScript type would look like that you would export from that, but it would try. You know what I mean? It would at least be string. [Laughter]
Dave: Yeah. Yeah.
Chris: You know?
Dave: TypeScript would be like, "That's a string. That looks great. I'm going to put it in the app."
Chris: Yeah. That's not empty.
Dave: Yeah, and it's not empty. It got required. Anyway, that's all to say Zod curious.
Chris: [Laughter] Yeah.
Dave: I don't know if it's powered by Zig.
Chris: [Laughter] No.
Dave: Is Zod powered by Zig?
Chris: It's a very funny name. I don't know. I think it got some good press when Astro said they're really all in on zodding it up.
Dave: That's their validator? Well, I kind of went into that world, and there's kind of Zod for everything, right? Every flavor that you're doing, somebody has converted it to Zod. And so, that's kind of cool.
Chris: Yeah. Right. That was definitely one of our questions, though. How server-side cool is it? If you have a Node app, it's probably fine because it's JavaScript. Everything is JavaScript.
Dave: Yeah.
Chris: But if you're like, "Our backend is in Python," or in Ruby or something.
Dave: Hmm...
Chris: And you definitely need to validate the data there, too.
Dave: How reusable is that? Yeah.
Chris: Yeah. None reusable.
Dave: None.
Chris: That's the answer.
Dave: Right and now you're maintaining rules in two places.
Chris: Right, so the question was, you know what is reusable? JSON schemas. JSON schemas are. JSON is so universal.
Dave: Yeah.
Chris: There is a JSON schema validator in every language that you want it to be in, so why don't you just write JSON schemas for your validation? Well, the answer is not everything is JSON.
Dave: Moving away from XML was a mistake, xml.net 3.5 framework. We've drifted far.
Chris: [Laughter] I know. That's why it's funny to see a question like Russell's, which is so great, about jQuery. You're like, man, those days were--
Dave: Can I use jQuery...? [Laughter]
Chris: Yeah. We just answered none of those questions. But it wasn't for those questions. But it makes you nostalgic for a time when you just didn't worry about stuff like that. You got the string value of a dang thing, and you just sent it right along.
Dave: What I miss, too, there are a few things, like for loops. I could do $post or each. Wasn't it each was the method?
We have for each in JavaScript now, which is cool. But I guess there was something. I felt like we didn't have that for a while, and you had to do posts of posts - or whatever.
Chris: Yeah.
Dave: I don't know. What am I getting at? But one other thing I'm missing was if I do $post.add or...
Chris: As a setter or a getter?
Dave: Yeah, like a setter-getter. I'm saying let's set an attribute: data-foo=bar. Right?
Chris: Mm-hmm.
Dave: In JavaScript, that's a for loop, so I have to say document query selector all post for each. Go do this, and then if attribute exists, set the attribute.
Chris: Yeah. In vanilla JavaScript, it's messy. In jQuery, it was a one-liner, right?
Dave: Right. That's where I miss. As good as the DOM APIs are, now I miss some of those very sweet conveniences where it was just like, "Hey, I'm just modifying the whole page. And if it doesn't work out, that's fine."
jQuery had good bailing strategies. If it got confused, it would just be like, "Cool. I'm not going to do that one. I'm going to the next one."
Whereas, as we all know, regular JavaScript is like, "If it chokes, it just dies on the whole page." That's what I miss.
Chris: Mm-hmm. Yeah, dude. Yeah. Russell, yes, missable.
We've got one. Do we have time to do one more? I'm sure we do here.
Dave: Yeah, I can do one more. Felix writes in.
Chris: Mm-hmm.
Dave: "Like you guys, I've been skeptical of the benefits versus costs of learning TypeScript. But also like you guys, seem to be begrudgingly reaching to the acceptance stage where I'm considering learning it. Do you have any resources or tips you've found helpful?"
Chris: I guess we just did this one, kind of, huh?
Dave: Sort of.
Chris: It's one of the things in your toolbox of stuff.
Dave: Yeah.
Chris: Yeah, it does seem like... I don't know. I guess I need to sit down and write because that's the only way my brain works, usually. But it's definitely a little good, a little bad, still, in TypeScript land. But it really depends on a million things, and there are so many things.
There are so many different kinds of projects that there's never going to be an answer to yes. Am I looking to add it to my WordPress websites? I am not. But I'm sure some people would answer otherwise that they just are so used to the syntax that, of course, they would set it up for any JavaScript they write.
Dave: Yeah. I'm going to ruthlessly eliminate nuance and say, "Get it out of the fucking stack. This is a piece of shit."
Chris: [Laughter]
Dave: It's way too many farts in the engine. Get it out of here.
Chris: Get it out of here.
Dave: I'm just kidding, but it's fine. There are benefits. But I think what's getting me is more code is showing up in TypeScript. And so, when I read something, it's like, "Oh, man."
It's just like when, all of a sudden, everything is in Sass. You're like, "Oh, man. Why is there a for loop inside my CSS file?" Now you're trying to figure that out.
I feel like the grammar, like Vue just added this generics type, so you say, "Script setup generic equals T." I'm just like, "We're out of control, everybody."
[Laughter]
Dave: We're modifying the script tag with a TypeScript attribute, a generic type attribute. Why do generic types even exist? I'm sure that there's a reason, obviously.
Chris: User generated content, Dave.
Dave: Yeah, well, but hey... Anyway.
Chris: Yeah, there are all kinds of reasons. Anyway... [loud exhale] Yes.
Here's the thing that I think the reason it gets steam now, I'm finding, living in this codebase that's partially TypeScript, which I think probably a lot of people are.
Dave: Mm-hmm. Yeah.
Chris: And having some experience with typed languages now, me, through Go and all that, is that you get used to your VS Code experience, you being able to hover over anything and have it just be like, "Oh, here is a lot of information about what is happening right here."
Then sometimes you hover over something and you don't get anything. You're like, "That sucks. I hovered over you because I wanted to know something, please." You're like, "Oh, yeah. The thing is that thing that it's calling hasn't been converted to TypeScript yet in our codebase." There's a strong temptation to be like, "I'm going to go update it because then when I hover over it, it's going to tell me what's going on."
Whether or not there's any real value to that or not, I think that can snowball in codebases where you just get really used to the idea that there's more internal intelligence of your app when you've done the conversion. It's very tempting to convert stuff.
Dave: Yeah.
Chris: The secondary question from Felix is, "Do you have any resources for learning it?" I will tell you one story there. I only ever learn things by just having to do them professionally or because I'm building something that I want to build - ever. That's the only way I've ever learned something.
When I learned TypeScript, I'm like, I'm going to switch that on its head. I'm going to do the courses.
Dave: Mm-hmm.
Chris: Because there's value. It's not like I never do courses, but I usually only do it when it's in conjunction with doing something for real. But I did TypeScript kind of ahead of time, and I went to this program or this website called Execute Program.
There was no video. It was only you learn through these examples of this ever-growing page that's like, "Here's some code. Answer a question about it. Now you write some code that fixes this problem, and then we're going to teach you."
You just were constantly hitting next, next, next, next, next. Writing code, having it checked and stuff. It was a very interactive learning experience, and I did the entire beginner course and the entire intermediate course. Then I started the advanced course, I think.
But it took a long time because the way that they schedule these things is you can't work ahead. You have to stop at some point. It's like, "Nope. That's good for now. Come back tomorrow." I'd be like, "Okay, I will."
I did it, and now it's not... It's just my brain. I'm not trying to dunk on them or anything. I've retained nothing.
Dave: Hmm...
Chris: It's like I did that for German or something. I still have to... If I go convert stuff, I have to be like, "Oh, how do you do a function again? Oh, how do you do props? Oh, yeah. That's weird."
I just feel like I had that in my brain for like five minutes while I was doing the thing.
Dave: Yeah.
Chris: For me, it just has to be part of the thing that you're building, and you have no choice but to do it because that decision has been made and that's the language we're using and we're using it to accomplish real things.
Dave: I would agree. Syntax for fun probably is not going to stick. Right?
Chris: Yeah.
Dave: Speaking of syntax, I think Wes Bos is working on a TypeScript course. I'm actually excited for that to drop.
I think what I need, which I haven't seen, is a TypeScript for babies, like, if you do these three things, this will improve your whole codebase, and it's worth the cost of adding this whole thing to your build process and all this junk.
Interfaces are the main thing I want, you know, like that idea. But I don't know. I'm also like, "Could I just do JS Doc and get what I need? Maybe," and so I just need to do that. Maybe I need a post. Somebody can write this, but a post like, "Here's why you should just do JS Doc," so I don't know.
We have some services in our app. It's a turbo repo thing. They're fine as JavaScript. But it might be worth us migrating one or two to TypeScript just to see what we get. I think that's kind of on our roadmap.
Chris: Yeah. Mm-hmm.
Dave: Just to introduce it in some isolated places, not across the board, so that we can get some exposure and see if we like it or it's helpful at all. It might be something I'd do here. I don't know. I could do it this summer. I've got a project in there that needs to be done.
Chris: Heck yeah.
Dave: Who knows? And it's like when you're dealing with data. That's also a good place to do it.
Chris: Heck yeah, dude. A little ways in. Do you have any other things you're thinking about as far as the Web platform is concerned? [Laughter]
Dave: No. I mean we can make this another show about view transitions, only if we want. [Laughter] Colors, view transitions, and passkeys: that's this podcast for the rest of time here.
Chris: Yeah.
Dave: I had been thinking a lot about Dion Almaer, formerly Google, formerly Shopify, had a really good post. Did you see it? Did you read it? "Building a Modern Design System in Layers." Did you read that?
Chris: I did not read that.
Dave: Here. Let me give you a--
Chris: I didn't know he was a design systems guy. I don't know him that well.
Dave: Well, I think he was doing... I think he was part of the remix acquisition at Shopify.
Chris: Oh, really?!
Dave: And then got kind of mixed up in the whole layoff situation. But anyway, we're building Hydrogen at Shopify, I believe. I'm hopefully not misrepresenting.
He is talking about these layers of a design system. You have HTML and CSS as the foundation. That's your design tokens, like how you're structuring things.
Chris: Okay.
Dave: Accessibility built into that, right?
Chris: That's the lowest layer or something?
Dave: That's the lowest. That's the base layer. Then on top of that layer is custom elements, which is like the minimal interactivity that can't be done with HTML and CSS.
Chris: Okay.
Dave: You're talking about modals, toggles, et cetera. Then on top of that is the framework layer, and he has React, Svelte, Solid, Vue.
Chris: Hmm... I feel like Brad Frost would agree with this, too, that there's overlap.
Dave: I think so, too. In my brain, if I was a framework author right now, I would be pushing Web components because, hey, it has the whole lifecycle built into the browser. Just use that. We offer very little in addition to that, so just use that. But what we offer is actually kind of orchestrating that whole DOM.
We've called it the DOM manager in the past. But this whole idea of, like, if I click a button and I go fetch some data, and I come back and I have to change the props and attributes on like 10,000 children, Dave Rupert doesn't want to write that for loop by hand. I just want a framework to just be like, "Yeah, dude. I go fetch the JSON or whatever, and I can spit out 20 custom elements or 10,000 custom elements with all this new data. No problem. That's what I do. That's my bread and butter."
It wouldn't be too hard for Dave Rupert to write, but when I'm talking about writing it over 70 templates in an application (or something like that). I want a predictable interface framework that helps me do that in a responsible way and has very common patterns, authentication, security, image loading, et cetera.
Chris: Yeah.
Dave: Stuff like that.
Chris: Hmm... I’m trying to wrap my mind around some of that stuff so much because I have some of it wrong in my head and some of it seems rightfully confusing.
Let's say you have this button component, which would be classic in any framework. You would not write it in React - or whatever. You would only write it as a custom element because that's a medium-layered component and it kind of deserves not being in a framework because the job is more appropriate at that middle layer. Fine. Right?
But it's very reasonable that I need to attach an on-click custom click handler. What happens when I click that button, and how do I give the Web component that function from the framework above it is just confusing to me, and I can't picture it exactly.
Dave: I mean you could still use the framework to add. The framework doesn't care if it's a button or whatever. You're adding a click handler to a div, basically.
You could have the framework add the click handler, or you could have some kind of... Maybe that click is a prop or something.
Chris: It's a prop. Right. Yeah.
Dave: It emits something that the framework understands. I think there are a few ways to go about it.
All this to say, I think, with view transitions and this stuff, or just Web components being somewhat mature and in every browser, I think there's a really--we've said it for years--good time to rethink the Web on what our sites can be or should be or how we can ruthlessly eliminate nuance and make our codebases 10x slimmer.
Luro is a pretty simple application, but we have a lot of code. And I would love it if that got cut in half. That would make my day.
Chris: Mm-hmm.
Dave: How does that happen? How do we make that get cut in half? I don't know if there's an instant way, but what moves the needle?
I feel like using the platform, HTML forward stuff, I think that's a big deal, and I think it opens the opportunity. Maybe your DOM manager, your DOM orchestrator, isn't something like React. Maybe it's Astro. Maybe that's actually doing the DOM lifting. Maybe you don't... That fetches all the posts and renders the loop. Maybe you don't need a big, bad JavaScript framework to loop through stuff on a button click.
Chris: Especially, yeah, if it's... Still, I think of Astro mostly--and this is my fault--as, like, "Oh, but that's just during build only." But they're like, "No."
Dave: No. No.
Chris: It could be a cloud deal.
Dave: Yeah. Yeah, I think there are apps, like Ruby on Rails. I know y'all are trying to squeeze out of it, but that's another example. Maybe Ruby on Rails is great. [Laughter] Maybe Ruby on Rails plus view transitions is awesome. Maybe that gets us all the way there.
Then maybe your button that needs to turn on private-public that you have in CodePen, maybe that's the Web component. Just those little, tiny interactivity bits are rendered dynamically.
Chris: Yeah.
Dave: You didn't have to load a whole React just to see that.
Dave: I found out... This is totally tangential. I know we've got to wrap up. We had a bad performance score. I was using Luro for Luro.
Chris: Yeah.
Dave: I had a bad performance score on a blog post. I was like, "What's going on? Why is this ten megabytes?" [Laughter] Why is this blog post ten megabytes?
I open up Web Inspector. It had four Mastodon toots in it. Every Mastodon toot loads React. It loads Font Awesome. It loads two versions of Roboto. And it self-hosts all those, so they all come from their own domain. Right?
Chris: Mm-hmm.
Dave: Then if those toots are from a different server, there's a service worker in there to cache it, which is awesome. But if those toots come from the same domain or from different domains (like mastodon.social, mastodoon.social, queer.party, whatever), if those come from different places, now you get repeated versions of it, and something like two megs per toot comes through.
Chris: Yeah.
Dave: We had a ten megabyte blog post.
Chris: Embeds are the worst, man.
Dave: There are better ways, man. There's just better architectures out there. [Laughter]
Chris: Yeah.
Dave: We can do better, right?
Chris: We're so responsible with our embeds. We keep them all real tight. No libraries. No fonts. Real fast. But even then I don't necessarily blame somebody.
I think that Twitter has had some problems with their embeds lately, and it's just been like, "Dude, I think you're way better off with a JPEG anyway."
Dave: Yeah.
Chris: Just JPEG it.
Dave: Yeah. For sure.
Chris: PNG that sucker.
Dave: I try to be responsible because I want some text or actual text.
Chris: Alt.
Dave: Screen readers just skip over the embedded tweets. It's so ridiculous. Anyway, that's where Web components would be better because it would be part of the DOM. Hey!
Chris: Yeah. Yeah. Yeah, yeah. I did verify that. At one point, they did actually ship a Web component version of embedded tweets, but it was very short-lived. I don't know why. I think just technical debt and teams. It was probably a people issue more than a technology issue. You'd like to think that those things are technology issues and they never are.
Dave: No. 900% of the time, it's because one kid, one intern did something, and then they decided to not. You know? [Laughter] Like one intern did a thing and then they decided that intern doesn't work here anymore. We can't support this.
Chris: All right, Mr. Dave. We learned a lot today.
[Laughter]
Dave: Yeah. This has been good. We've talked about a lot.
Thank you, dear listener, for sending in your questions. We could always take more. We love those. Thank you for downloading this in your podcatcher of choice. Be sure to star, heart, favorite it up. That's how people find out about the show.
Join us in the D-d-d-d-discord. That's where the party is. Patreon.com/shoptalkshow.
Chris, do you got anything else you'd like to say?
Chris: [Tongue roll] Just ShopTalkShow.com.