Holla! This week we’re playing Story of the Week and Today I Learned before turning our focus to Vest – a very cool validations framework created by Evyatar Alush.
Featuring
Sponsors
GatsbyConf 2022 – (March 2nd and 3rd) this conference is totally free and totally virtual so everyone can join. Day 1 is talks and day 2 is workshops —hear from Gatsby co-founders and leadership on speed improvements to the build system, incremental architecture, the latest on Gatsby Cloud, announcements and more. Chris Coyier kicks off day 1 with the Keynote. Register at gatsbyconf.com
Sentry – Working code means happy customers. That’s exactly why teams choose Sentry. From error tracking to performance monitoring, Sentry helps teams see what actually matters, resolve problems quicker, and learn continuously about their applications - from the frontend to the backend. Use the code CHANGELOG
and get the team plan free for three months.
Changelog++ – You love our content and you want to take it to the next level by showing your support. We’ll take you closer to the metal with no ads, extended episodes, outtakes, bonus content, a deep discount in our merch store (soon), and more to come. Let’s do this!
Fastly – Our bandwidth partner. Fastly powers fast, secure, and scalable digital experiences. Move beyond your content delivery network to their powerful edge cloud platform. Learn more at fastly.com
Notes & Links
Holla!
Story of the Week
Ali
KBall
- Gergely Orosz tweet about remote hiring
- The Trimodal Nature of Software Engineering Salaries in the Netherlands and Europe
Amelia
- Serving fonts from Google Fonts CDN violates GDPR
- AlphaCode is in the top 54% in programming competitions
Jerod
Today I Learned
Ali
Amelia
- CSS Cascade Layers: Article by Bramus Van Damme
- Feature Rollout
Jerod
KBall
Project Focus
Transcript
Play the audio to listen along while you enjoy the transcript. 🎧
Oh yes, friend, you know the sound of those Breakmaster Cylinder beats means it’s time once again for JS Party. I’m Jerod, I am your friend, and I have three of my internet friends here with me. Amelia is here… What is up, Amelia?
Hey! Not much.
You ready to rock?
Oh, yeah. I’m ready.
Are you ready to sing?
Absolutely not.
Okay.
[laughs]
Kball’s here… Always ready to dance.
You know it. I heard the BMC going and I was rocking out over here. I’ve missed that.
Are you still rocking multiple cups of coffee every morning? Are you in your coffee kick, or…?
Of course. I think I had four today, maybe…
Four?! That’s excessive, Kball.
No. We do two pots of a French press between my wife and I.
Wow… That’s impressive.
And that voice that you hear is Ali Spittel. What’s up, Ali?
Pretty good, pretty good. I have not had coffee today, so… I should get on that.
How do you survive…?
How do you survive?
[laughs] I try to do it maybe three days a week, so that I don’t have the impact of it too much.
Okay…
Still effective.
So do you find that when you drink it less than when you do drink it it has more of an impact?
Totally. Totally.
Because Kball just hooks up an IV right into his arm and then he doesn’t even feel anything. It’s just part of his bloodstream at this point.
Well, I wake up at 5, right? So I wake up at 5 and I have my first cup of coffee and kind of get going… But I’m usually done with coffee by like 9 o’clock in the morning, and I don’t have – the latest I ever have coffee is like lunch time, and then I’m done.
Right. Well waking up at 5 you’d probably not have any problem sleeping at night though…
None. I’m like out by nine o’clock.
So that’s awesome. Same with me. 9:30, if we’re getting crazy; if it’s party time we maybe make it to 10 PM maybe… Just in case…
Oh, wow.
Well, nothing good happens after midnight, and then I just take a couple hours off just in case. I wanna live dangerously.
That’s why in the before times I loved to go to the East Coast, because then I could actually pretend I’m a normal adult for a little while and stay up past 9 o’clock… [laughter]
[04:04] Well, your 9 o’clock is much later than our 9 o’clock. By the time you go to bed, that’s 11 PM my time, and probably midnight Amelia’s time.
Yup.
Oh, no. Four hours, right? I can’t remember. Where do you live again? [laughs] Amelia is in DC.
DC, yeah.
Right. Let’s do some segments, huh? And our brand new segment, my creation - I thought of this all myself; there’s no way I stole the idea from Go time. It was completely and all me… It’s called Holla. [Can I holla? Can I holla at you? Holla-holla-holla-holla-holla-holla-atcha!]
So for holla, which is where we holla at various community meetups, events, things going on, if you host a meetup or a conference that’s upcoming and you’d like to have us holla at you, holla at us at @jspartyfm. Today we want to bring to your attention Ember.js Europe. So the Ember.js Europe meetup brings together the Ember community from all of Europe once every quarter, except the EmberFest quarter. I’m not sure which quarter that one is, but don’t go to Ember Europe meetup that quarter; they won’t be there. Every other quarter they will be. It’s organized as a hybrid event hosted from a different city each time, with the option for people to join remotely as well… And they have an upcoming event Thursday, March 31st; their very first Ember Europe meetup. Already 15 attendees. That will be both IRL and online. So check that out, we’ll link it up in the show notes. It’s on meetup.com/ember-europe. This has been your holla of the day.
Holla!
[laughs]
Jerod, I wanna hear you do that.
Can I holla? Can I holla?! Can I holla-holla-holla-holla? Holla-holla-hollahalalhala…! Are you sure you wanted to hear me do it?
I don’t know, but it got me thinking - what are other plays we can do on holla… What’s the friendliest type of bread? Challah… [laughter]
I don’t know that kind of bread. Is that a West Coast bread?
No, it’s like a Jewish traditional bread. You have it on Shabbat.
Oh, I thought maybe it was like a proper noun kind of a thing, like a manufacturer.
No, it’s traditional… It’s delicious. It’s slightly sweet, kind of eggy bread. So good.
Really tasty.
You are missing out, my friend. Maybe they just don’t have that in Nebraska…
Is anybody – Ali and Amelia, are you aware of this?
Oh, yeah.
Yeah.
You’ve never had challah?
No, I’ve never heard of it, until right now.
Find a good Jewish deli that does challah French toast… And you will thank me for the rest of your life.
Okay. I’m looking forward to that. I’m gonna actually do that. Challah French toast. That reminds me… What’s the hilly seaside neighborhood within the city of San Diego, California? Well, it’s La Jolla, which is spelled the same as Holla, but unfortunately uses an aya. Anywhoo… [laughter] Today we’re doing story of the week. Let’s get it kicking.
Story of the week is our segment where we take turns sharing what we believe is the most important, or the biggest, or maybe just the most interesting to us story of the week, or the recent times; since we don’t do this weekly, you can go back a little further than merely a week. Let’s start off with Ali, because I’m looking at the notes and I think she drilled it with the biggest story of recent times. Ali, what is it?
fetch( ) is coming to Node, which I am so excited about.
Woo-hoo!
This is something that I have been annoyed by at varying points of using Node, so I’m very excited about it.
And it’s top-level, and it’s just gonna be there, it’s just right there for you to use, there’s no imports, there’s no extra name-spacing, you don’t have to do anything. You just type fetch( ).
It’s amazing.
[08:04] Is that right?
Yeah.
Now, I know there were some challenges in getting that to happen, right? Do you know anything about what made it hard? Why was this such a long time coming?
I have no idea. That’s a great question.
Where is our Node.js experts, Chris or Nick? They’re not here. They’re not on the show today. I do know it’s been a long time coming, I do know that I looked at the thread on GitHub, on the – not the issue, but the PR that was merged, and it was very long. But I don’t know what took so long; I assume it’s like backwards-compatibility, or maybe there’s some… I mean, it’s a top-level keyword fetch( ), so probably not backwards-compatibility, now that I think about that. It probably was implementation details, I don’t know. Who cares, it’s here now! Wooh! [laughter]
Yeah. It’s exciting.
So what Node version do you need to get fetch( )?
You need 17.5.
So it’s landed in 17.5. Is it behind an experimental flag, or is it just like you have 17.5 and you’re good to go?
I think that’s when it lands. You can use the experimental fetch( ) flag – I don’t know, this article is not very clear. [laughs] I was just trying to skim it.
Well, it’s JS Party, it’s not a JS research assignment, so… We only go so far, people.
Yeah. It’s hard to research too because the Node Fetch npm package is what comes up for everything.
So the pull request that was merged, the add fetch pull request does say this adds a –experimental fetch flag…
I see.
…that installs fetch( ), request-response and headers as globals. So I do believe 17.5 is when it lands, but it still might be a thing that you have to opt into until they’re ready to consider it final and put it in for everybody. But who’s not gonna opt into this? Like, come on, give me the fetch( ).
It’s so handy. Yeah, experimental fetch right now, and then eventually it’ll just be global.
Yeah. I’m looking – there’s this big Hacker News thread about like why was this hard, or why was this… It’s like meandering all over the place, so it’s hard to read on the fly, but we can include a link to that. Some of the authors are involved in that, as to kind of why was this such a problem. I think it is that backwards-compatibility, new APIs…
Well, just here we see that it’s not just the fetch( ) keyword, it’s actually four top-level keywords. So maybe there was some more backwards-compatibility with response, request and headers.
Here’s the challenges - so it’s tightly integrated into the caching model of browsers; a large chunk of the spec is about caching, which is incompatible with the caching model of Node. Part of the spec is about the security model, which may not make sense in Node. Spec deals with the browser connection pool, which is different from how it might be handled in Node. It’s global, which is also a challenge.
Sure.
It uses WhatWG streams, which were at least at that point not supported in Node. I don’t know if that has been added or not.
So implementation details. Anytime you’re bringing a browser API into the server-side, there’s gonna be miscompatibilities, things that just don’t make sense in that different context, so decisions must be made, and code must be written, it sounds like. But regardless, I think this will be a boon for developer productivity all around the world, especially when it lands globally without a flag… Because anytime you can just learn an API once and use it everywhere, that’s a win, right? Half as much work.
Yeah. No more need to polyfill it.
Exactly.
I don’t know, I have definitely used Node fetch( ) before.
Alright, so that as a big news - probably gonna win, if this was a contest… No offense to y’all, I’ve seen the other entries. But let’s move on anyways and see what Kball has to offer. Kball, what’s your story of the week?
Yeah, so I saw something float by by a guy named Gergely Orosz. I’m probably mispronouncing his name.
Gergely.
[12:07] Gergely. Okay. The guy who is behind the Pragmatic Engineer, which has kind of blown up recently… And it was sort of a quick mention that oh, Meta is now hiring engineering managers remote always, not just engineers. At least in the U.K. And I think it’s like a hint to a larger story, which is around the continued ripple effects of the move to remote work; how more and more companies, even these large companies, are having to say “You know what - this is not just a during the pandemic thing. The world has changed. We’re gonna hire folks all over, we’re gonna have an ongoing remote plan.” And I think there are some really interesting ripple effects in terms of how it levels salaries across the country and across the world.
I’ve heard from folks who are hiring contractors in Eastern Europe and the Philippines and things like that… Folks who have been in places where salaries were much lower to do software development - they’ve seen 50%, 70%, 100% increases in how much you can earn as a software developer… And I just think it’s fascinating. There’s so many different ripples. One, that’s a lot more money; it basically makes software development even more of an export industry; you can use that to bring money into wherever the heck you are. I think it potentially – like, they’re making this money going to U.S.-based mostly, and some European-based multinational companies, which then means local software development shops are gonna be starved for talent, or having trouble competing, which means - yes, there’s more money flowing in, but there’s also less development for local-facing things. So the world is changing in a way that I find absolutely fascinating, and I’d be curious to hear y’alls take on it.
Yeah, for me it’s the biggest silver lining of the pandemic, if the pandemic had any good points… I’ve had to move to not tech hubs, because my husband’s in Academia, and I’ve been kind of following him around, which is hilarious, because we’re about to move to San Francisco in a few weeks now that it’s not cool anymore… [laughter]
It’s still cool…!
Yeah, but if you live there long enough, it’ll become cool again, and then you can say “I lived here before it was cool.”
[laughs] Yeah, that’s my plan.
That’s your plan?
Yeah. It’s the long game. But moving to non-tech hubs from a tech hub originally - it’s like a totally different tech scene… Which is great. I’ve learned a lot living in – I lived in Upstate New York for a while, and the tech scene there is pretty different, but I learned a lot from the people there who were doing these different kinds of projects. But you don’t really have access to startups or the big companies. So it would have been awesome, when I was moving there, to have the option to pretty much work at any of these larger tech companies… And I can imagine the same in other countries. Although I’ve heard that most remote jobs - I don’t know if this is true - are mostly remote in U.S. and Canada. And I don’t know if that usually applies to other countries.
So I know a lot of – like, we’re only hiring U.S, for example, though we’re all over. So a lot of U.S.-based companies are. But I also – like, one, Gergely has been publishing stuff on the impact of Eastern Europe. I don’t know if those are folks coming from other parts, like Western Europe hiring into Eastern Europe, but there’s been huge changes there.
The other thing that I’ve heard as I was talking with someone who’s a startup co-founder working mostly with contract developers at the moments… And the rates of hiring contract developers overseas has skyrocketed. So that may not be the same type of like you’re hiring full-time employees, but it’s still demand for remote work and remote development in a way that is totally changing the landscape.
[15:53] Yeah. I know it’s difficult to hire full-time employees in other countries just for like legal and tax reasons a lot of times for companies… But also from a team perspective, it can be hard for timezones, too. I manage a team that is globally distributed right now; it’s mostly U.S.-based, but there are some folks from not in the United States, and it’s awesome that we have that opportunity now for sure… But that’s one thing that I’ve noticed though, is those first couple hours of the day are packed with meetings, because they’re the time that everybody is online… Then the afternoon becomes a little bit less packed, and I’m sure it’s the inverse for a lot of other teams.
I think that’s a really interesting piece of it, too - in some roles, they’re really, really good at being remote-first and asynchronous-first… And I wonder how that’s also going to change the nature of work. It’s gonna make it probably less social than it is now. And I’ve noticed that just moving remote myself - you used to go out with colleagues and get drinks or whatever after work, or you used to just have the watercooler chats… And you can kind of mimic that remote, but it isn’t exactly the same. Maybe it’ll make it so that people are more reliant on their hobbies and things for social groups instead of their jobs. So… Another interesting piece of it.
Yeah, I lost the drinking with folks after work when I had kids… Which was before the remote problem. [laughter]
Alright… I’ve always been remote, so I never had any of those cool things… Like, I would hang out with people at conferences, and that was my opportunity to see people. Because out here in Nebraska (hey, Kball) it’s not for everyone, but it’s for the cool ones, as we say…
I don’t even have to troll you, you’ll troll yourself.
I just preemptively know that you’re gonna troll me. But you know, there’s a very small scene, and there was more of a scene before; there really isn’t one now. And if there is - you know, I’m getting old and kind of aging out of social scenes anyways. But for me, what’s changed – first of all, I love the access to opportunity for more people… Like, how cool is that? But from my vantage point what’s changed mostly is people are way more comfortable with online/remote communications; it’s made podcasting way easier, sounding better… People are used to being on Zoom all day, or they’ve invested in their setups, and that’s been a cool side effect of this from a podcasting perspective. It’s like, “Wow, we can have much better, higher-quality conversations with more people, because they’re prepared for it.” Whereas it used to be a lot of hand-holding, a lot of technical issues… And there’s some people that their setup just couldn’t – we were just never gonna have them on a podcast. And it’s just because of circumstantial things. And of course, access to high-quality internet is now more important than ever, and we’re starting to see municipalities and other government entities investing into those things and providing those as utilities, or as a way of drawing people to your area… I think that’s really cool, too. Just a lot of like trickle-down effects of this change. Alright, that’s you, Kball. Amelia - it’s your turn. Story of the week.
Oh, man… Okay, so I couldn’t choose one good one, so I chose two semi-okay ones.
[laughs] Well, if you add them together…
Yeah… It’s two semi-okay ones. So this first one I thought was a little bit terrifying, honestly… Some German state court found a website violating GDPR because they were serving fonts from Google Fonts… Which tons of websites do. I do it on side projects because it’s just easy, and I guess the extra step of hosting my own fonts is prohibitive… But I thought that was pretty intense. And it’s because you’re sending Google – well, you’re not sending it, but Google’s getting the IP of your users.
[19:58] Right. Yeah, so related to that – maybe it’s related; maybe somebody knows this more than I do, but… There’s been a back and forth between Meta/Facebook and the European Union as of recent… And I’ve only caught the headlines. So if this is misinfo, correct me, fact-check me and stuff. But what I’ve read is, the gist of it is the European Union said if Facebook and Instagram are gonna operate in Europe, they must store the data for the European users in European countries… Which we know is a difficult thing to get done just technically. It’s doable, they have lots of money, they can get it done, but it’s like a huge investment to get that done. Facebook/Meta goes back to the European Union and says “Well, we’re just gonna pull out of Europe then.” Which is a pretty big move for Instagram and for Facebook to do that. And then the European Union just says “Cool. Go for it.”
Instant 5% productivity boost across Europe.
Exactly. [laughs] They said something like “We think life would be better if you guys were gone”, or something like that. It was very saucy what they said.
Exactly. Well, that was my reaction when I saw the headline, too. I was like “Oh yeah, sometimes I like seeing Instagram, but for the most part, I think life might be better without these.” I don’t think it’s a huge loss.
Right. I think it’s like a game of chicken at this point, like “Who’s actually gonna do something?” I don’t know… These are global politics versus corporations, but… It’s similar, because I don’t know if it’s a GDPR concern, but it seems like it kind of is, because it’s like “Well, it has to be stored on European servers if you’re gonna operate in these countries.”
It is related to GDPR. We work with enterprises in Europe and have to deal with GDPR and all these other things, and Germany is the worst, by the way, of all of them. But the flowing of data between EU and US is like - there have been agreements, but they aren’t well-grounded legally. There has not been something that actually is considered to be good. And I’m not a lawyer; this is what I’ve learned from our lawyers about this…
Sure.
…but there’s a bunch of precedents that are sort of used and applied, but are not considered to be super-strong. And we can get away with a lot of it because we’re basically working with enterprises, not individuals. So we have a contract with the enterprise and we say “This is the grounding that we’re putting on this” and they either say yes or no. But once they’ve said that, it’s in the contract, there’s an agreement. When you’re doing like a user agreement with individual users, I imagine it gets even much more complicated.
Yeah. I know that’s a big thing with choosing a cloud provider too, the different regions; it matters for legal reasons as well.
Cool. Amelia, do you want to give your second one?
Yeah, I’m just glad I don’t normally have to think about these things. Alright… The second one is also a little bit terrifying. Basically, there was this headline from DeepMind recently that showed they have this (I think) model named AlphaCode, and they had it respond to these leet code computer - the interview questions where there’s a prompt and you have to write code that does a certain thing… And it basically did better than 46% of the human participants in the competition.
So this isn’t just like Copilot, which is assisting humans to write code. This is reading a prompt, which is all English, and then writing code that does a certain thing. So even if those competition questions aren’t necessarily the hardest, this is just like the beginning of something that’s gonna be computers writing code from specs… Which is cool, and scary.
So are the people that lost - are they programmers? Or they’re just regular people.
I don’t think it actually did a live competition, but I think they have stats of past competitions, and then they saw how it did compared to those people.
The hiring manager in me who’s seen submissions to requested competitions or whatever does not find this at all surprising… [laughter]
Haah!
[24:08] You would be shocked how many people who call themselves developers cannot solve these problems.
Right. Why do you think that is? Is it they’re just trying to get some work, or is it delusions of grandeur? Sometimes you have to trick yourself into thinking you can do a thing, and then eventually you can do it… But what do you think about that? Because if it was me, I just wouldn’t apply.
It’s a good question. But this is why the FizzBUzz interview question is a thing… Because there’s a bunch of people who will apply to programming jobs and literally cannot program. And I don’t know what’s going on there. Maybe they’ve only ever operated where they’re like copying and pasting code that exists, and trial and error to see if they can get it right, and they just have not developed the mental models at all… I really don’t know.
Yeah. Maybe the opportunity is just so great they’re like “Well, I might as well go for it.” Because when we’re talking about the salaries, it’s a great living, and it’s only getting better. And then meanwhile, other career choices are getting less attractive because of global macro economics and things… I don’t know, it’s definitely confusing.
Yeah. A piece of me, on the other hand, that was really excited about this idea that we don’t have to write the boring stuff anymore… Because that’s one of the most annoying parts of being a developer, is writing a form and form submission logic over and over again… So if that can be abstracted away or done for a developer, that’s a huge boon to everybody’s productivity, because then you can focus on the hard stuff. And that’s why we’re all programmers in the first place; it’s not because we wanna do the same repetitive stuff over and over again, it’s because we wanna solve the new problems, and build the cool stuff… And maybe this will leave us more opportunity to do that. So that’s something that I’m a little bit excited about.
Totally.
Yeah, that is cool. I mean, if you think about what I’ve just said earlier in the show - I’ve coded for many, many years; I took some time off, and then it’s like “I’ve gotta go look up the syntax for a for loop.” And it’s like, I just wanna loop over the things, I don’t care about the details; I’ve written these loops in multiple languages, and it’s like, I don’t wanna do the repetitive – I mean, actually, I technically do wanna do a repetitive thing… But you know what I’m saying. [laughs] I just wanna do it seven times, and then stop.
But that’s more along the lines of what we’re currently seeing from tools like GitHub Copilot and Tabnine. This is like “Hey, write a spec, and it does the coding.” That’s a whole other level of abstraction. In fact, we had the CEO and founder of Tabnine on the Changelog - they have a code assistant - and I asked him about that. I’m like “Is the end game where I can write a spec and the program just does it?” He’s like, “No. The end game is you’re better at programming because you don’t have to do the repetitive things.”
There you go.
…in the medium term end game. He’s like “Well, on an infinite timeline, of course”, but what they’re aiming for is super-powers for people; more people can program, do super-powers… Whereas this is more operating on like the “Hey, take the human out of it” kind of a thing.
It reminds me of the no-code tools. No-code has continually gotten better over time, and what it continues to do is move up the bar of how much can be done without bringing in a programmer, but always within the bounds of like – you can only solve solved problems, right? If you wanna make a marketing website, a no-code tool is phenomenal, because that’s a well-solved problem; there’s not much innovative, there’s not much new going on there. And for many cases, that’s what you need. But any time you’re pushing the edge or trying to do something differently, it can handle it. And I suspect this will be the same for any sort of AI-trained tool, because it’s gonna be trained on the bulk of things, which are usually not the unique cases. If it’s pattern-matching, it’s not gonna be able to solve anything novel necessarily.
Yeah. In the medium term I’m really excited about those hyper-developer productivity tools, like Copilot, or these kind of low-code, but developer-first low-code solutions that just automate the boring stuff for you, and then you can focus on those things.
[28:11] For sure. Ultimately, I think the value that we provide is synthesizing ideas into working systems… And that doesn’t change, regardless of what level you’re operating at. So you just move higher up the stack, you synthesize more complex ideas or more ideas per capita than you did before, and you’re just more productive. So I think it’s gonna be a win for all of us.
Well, I will say, Ali did steal my story of the week… So I submit this one knowing that it’s not as good, but it’s alright, it’s all friendly competition around here; we’re not actually trying to win. There is a post from Dr. Axel Rauschmayer; I feel like he’s been on the show before, or agreed to… I can’t remember if we’ve actually had him on the show, but you probably know him as a prolific author and writer in the JavaScript space. A very good teacher. He has a post from the end of January about the pipe operator coming to JavaScript. He has introduction and use cases.
So we’ve talked about the pipe operator before; it’s been in development for many years, I think going all the way back to 2015 is when it first was introduced conceptually as what might be a cool, new piece of JavaScript. It’s now in stage two, which if you’re familiar with the stages of TC39, there’s like four of them, I believe… Stage two is pretty far down the road, but obviously not in your browser yet. But the pipe operator is a very cool conceptual thing, and one that I’ve enjoyed in the Elixir land. It’s also – I think F#, some other languages also have pipe operators, and the idea is to bring this to JavaScript. He has a really, really well-written layout of what it is, why it’s important, how to use it, what it currently looks like… Asking questions like “Do we really need one of these?” and then other ways it could have been implemented…
I’m excited that this is continuing to make progress, and I just submit this article that’s a really nice rundown of what it is and where it stands. What do y’all think? Pipe operator - is it something that you want? You wanted fetch( ), and got it. How about pipes?
I personally lean away from it, just because I think that there’s such a high learning curve for those functional programming languages, because they’re so symbol-based. And I see pros and cons to that. I think it’s a pro for making programming languages more universal globally, because I think that’s a huge learning curve for programming as is, that you pretty much have to program in English… So the more operator-based we make these languages, the more globally useful they are. But on the other hand, I do think that it looks a little bit more intimidating at first glance to a new developer, and that’s something that I feel a little bit split on, personally.
I totally hear that.
Fair. I should say, for the listeners, that the actual operator is a combination of a pipe, which is like the straight line, vertical line, and the greater-than sign, which forms kind of a rightward-facing triangle.
Yeah, I think that is a real concern. And we’ve had that problem in JavaScript generally over the last few years…
Yeah, arrow functions.
…where it’s become much more intimidating to start in JavaScript. I mean, personally, I would love this operator to exist, because I love a functional programming style, and doing it in JavaScript right now feels very awkward and verbose. I think it would be very personally useful, but I am concerned about the learning curve and the increasing barrier to entry we’re putting on JavaScript.
Yeah… I used to teach JavaScript as my full-time job, and teaching people the difference between different types of functions in JavaScript was just kind of a nightmare as is… And the arrow functions specifically, it was like “Why would I ever use this? Where does the arrow go? Where do all the things go?” So that’s what scares me a little bit about this as well, somebody new to JavaScript seeing it and being like all wigged out by it, or something like that.
[32:16] Yes. I think the arrow function specifically had a bunch of extra baggage around it, around optionality, and the fact that it’s not syntax sugar, it’s actually changing variable scopes…
Yeah.
…versus the function keyword is very confusing… And there was just too much like “Hey, if you don’t need this, take it out, and it still works. And I’m like, as somebody who casually uses those, I still have to remember, where’s the actual perameters here, what’s the function, what’s it returning? There’s still just too many ways you can use it, in my opinion. I think the pipeline operator is simpler, conceptually. I like that it promotes functional practices, maybe without even knowing it. It’s kind of like chaining; it’s promoting you to send data through a pipeline, and I think that’s cool. But I agree - just adding one more operator to a language that’s already difficult to wrap your mind around, especially at the beginning, could be raising that learning curve.
Yeah… Especially because it doesn’t add new functionality, it’s just adding another way to do a thing that you can already do.
I totally agree that it’s more syntax to learn, but I will play devil’s advocate, which - I think it can clean up code. So it’s a new concept that it’s one more thing to learn, but once you do learn it, maybe it crosses the threshold to being useful enough to – once you know it, you can look at code and it’s a little bit faster to read each time… But I’m not sure.
Has anybody written D3 before?
Once or twice…
The level of cheating on that
Amelia probably had a lot more, yeah…
I have a book on it… [laughs]
That’s like its own little DSL, you know?
That was my thought. It was like, “Okay, it actually might make D3 cleaner [laughter]
That’s the thing, we actually love chaining APIs. The chaining API that you get with jQuery, and things like that.
Sure.
But right now, in JavaScript, that requires specially setting up your API to return objects that understand the API.
Exactly.
So it’s a particular architectural constraint.
Yeah.
Whereas this enables you to do that type of chaining with bare functions.
Yeah, I think that’s pretty cool. This feature is in Elixir; I write a lot of Elixir, and I use it non-stop. I would use it non-stop in JavaScript myself personally… And so that makes me excited about it. And the fact that – you just said it right there, Kball… We’ve all seen the value of it in jQuery. But jQuery jumps through very specific hoops in order to make that available, whereas this makes it available to pretty much any function, as long as you’re passing the right thing in to the first argument.
Anyways, if you’re confused about the pipe operator, wanna check it out, not sure what we’re talking about, definitely check out his post, which is in our show notes. And if you’re excited about it, let us know; if you think it’s a terrible idea, also let us know. We wanna hear from you, @jspartyfm, or any of our individual handles as well. You can also email jsparty@changelog.com. If you have long things to say, we do read all of our emails.
Before we close the segment, I just saw - tied to one of our previous stories - the court in France declared the use of Google Analytics violates GDPR.
Oh, wow.
There’s a gathering storm here going on, and the implications are gonna be – it’ll be fascinating to watch how this all shakes out.
Yeah. Basically, any third-party server that you hit. It’s scary. Cool, but scary.
Alright, we are back, and it is time to play a little game we like to call “Today I learned.”
Is that another Mat Ryer hit?
It is…
That’s good.
That man is amazing.
So this is where we share things that we’ve learned “today”, with air quotes around today, because you know, it’s still early… So recently. But these could be bigger things or small things… It’s kind of like pro tips, but more pointed and technical. Maybe it’s a new API, maybe it’s a browser quirk. Maybe it’s something you can do with Git. Whatever it is, we share it with you all so you can benefit. Ali, we’ll go to you first.
Okay, so mine’s not technical, I’m sorry, but I’ve been listening to a lot of the Huberman Lab Podcast, which is amazing; it’s like all neuroscience. So for years I’ve been teaching students “You’re supposed to fail when you’re learning, at certain times. You’re not supposed to have this happy path all the time, where you just start learning and there’s this linear trajectory and then magically you know the skill at the end. Instead, there’s a bunch of peaks and valleys, and that failure actually helps you learn.” But I learned that there’s actually a number for this. So 85% of the time when you’re learning you should be succeeding, and that makes it so that you feel confident, and you’re not going to just completely drop off and quit. But 15% of the time you should be failing when you’re learning that thing, and that failure state actually makes it so that you are more able to learn in the future… And it’s meaning that you’re actually challenging yourself as well.
So if you’re learning, make sure that you’re actually struggling at points, and don’t just take the really, really easy path; make sure that you are challenging yourself. And then the inverse, too - if you are struggling, that’s okay, you’re supposed to be struggling when you’re learning something new. But if you’re struggling like 50% of the time or 75% of the time, maybe scale it back a little bit and challenge yourself a little bit less, because it could become really demotivating and it could be less than optimal for learning.
That is super-interesting. I assume it’s data-backed.
Yes.
Do you know how much individual variation there was? Like, is it pretty tightly around 15% for everyone, or is it like a wide range, like some people could be failing much more and be optimal, and others much higher?
That’s a good question. I think it’s just a zone that’s generally the best for the most amount of people. It’s obviously impossible to measure exactly 15% of the time I’m failing, 85% of the time I’m succeeding, but it’s just that general ballpark, I think. It was a study at Princeton University, and I’ll link it in the show notes.
So have you been able to put this into practice? And do you count your fails? Because I try to ignore mine, if at all possible. [laughter]
You don’t obsess over them?
[40:14] It’s not something that I put into an Excel sheet, or anything like that… But I do try to keep that in mind when I’m learning something, is that I’m not gonna be good at it right away. Right now – okay, so I’ve found out that there was a curling open house. Do you know like curling in the Olympics?
Yeah.
…right near where I live… And then I went and did that, and now I’m in a curling league for beginners, which is hysterical, I think… [laughs]
Cool!
But I think that, as somebody who teaches people, it’s really important that I put myself in the beginner’s mindset, for different things. And it’s usually not code-related anymore, but - doing something that puts me outside of my comfort zone and that I’m gonna suck at at first. I fell over so many times when I was trying to push this thing on ice… So yes, I’m definitely failing, probably more than 15% right now, at curling… [laughs] But it is something where if I am failing more than that 15% of the time, maybe I need to just repeat that same thing over and over again, instead of progressing to the next step.
Yeah.
I felt phantom pain in my lower-back/butt when you said curling, because of the one time I tried, and I fell so much…
I’ve never tried it. I’ve done a lot of shuffleboard, which is basically curling on easy mode, because you’re not on ice, and – I mean, that pretty much makes it easier right there, right? [laughter]
It’s really fun. I would highly recommend.
Are there like curling ice plex? Do you do it the same place you go ice skating? Or where would you actually go curling?
So at least around here there are different curling centers. So you can just look it up, your city and then curling center… And then they do lessons very regularly, but then they also have different leagues for people at different levels.
That’s cool.
I don’t think I’ve ever seen curling. Is it like longer than a normal ice skating rink, so you have to have a special –
It actually was pretty close to the length of a normal ice rink. In fact, it might actually be the same length… But the thing that you’re curling, the – I forget what it’s called; the thing that you’re pushing weighs like 40 pounds.
Oh, man…
So it skates on the ice, but then it actually stops at some point, too.
Are they called a stone, I think?
Yeah, rocker stone. There you go.
I was googling “curling ball. what do you push?” [laughter]
I’ve been curling exactly once. It was like a team bonding thing, and it is burned in my memory because I collided with someone, fell on my ass, and just – it hurt…
So I’ll stick to shuffleboard, because it’s more like a 95% success rate, which is more my comfort zone, than 85%… [laughter] Alright, that’s a very good one; I like that one, even though it’s non-technical. It still counts.
It’s data-backed. That’s technical.
That’s true.
Yeah, there you go.
Plus, who cares what the actual segments are called. You know, just say what you want. Amelia, your turn.
What did I wanna talk about…? Oh! CSS Cascade Layers. Super-exciting. They actually came out in Firefox two days ago, so they’re in the current version of Firefox 97. So for the CSS Cascade there’s all these layers where it decides which styles to apply. If you say body background blue, and also body background red, is it gonna be blue or is it gonna be red? And that depends - like, did you use a tag for the selector? Did you use a class? Did you use an ID? And I think a lot of trouble that people run into with CSS has to do with this, because they’ll add a style and then it won’t work, and then they won’t understand why… And then they’ll learn that if you add another part to the selector, it will override another selector… So it’s really frustrating, and I think we’ve all been there.
[43:54] For the cascade layers, you can basically create different layers. You can have like a utility layer, a core styles layer, an element-specific layer… And then the order in which you declare those layers – I think if it’s declared earlier, it wins. No, I think if it’s declared later it wins. I don’t know; one or the other. But it’ll make it easier to basically handle CSS styles and make it really explicit which one actually wins if there’s two colliding ones with the same specificity.
Interesting. I feel like this is the type of thing we used to do by very carefully crafting the order of when you CSS things. And you’d have these frameworks that would have the layers of like “Here’s the base layer, here’s the graphical layer, and here’s your overriders”, and all of that… But they do it by very careful ordering and specificity numbers and what have you.
So this is basically letting you just say that in code. It’s the same thing we did for JavaScript with modules, of like getting rid of the careful ordering of layers.
Yeah, exactly.
That’s nice.
I’ve also used BEM a lot, which is like basically you only do one class for every single style… Which gets really verbose. So I’m super-excited about this.
Our current site is done in BEM, and I’m ready for somebody to redo it… That’s not gonna be me… Because I would just do it in BEM again… [laughs] I don’t know how to do it any better.
You’re not gonna Tailwind it up?
I thought about it… No, I’m not going to. But I thought about it. But that’s what I do, I think about things. Every time something new comes out, I’m like “Oh, this looks cool”, I think about it, and then I just leave it alone. It’s just kind of my MO. I will go next, because Kball needs time to think…
Did you know there’s no longer a caching benefit to loading scripts from a shared CDN, such as UNPKG? We used to load everything off of a jQuery CDN, or these CDNs that were there… And there was this cool side effect where if we’re all using the exact same version, or if you’re cool enough with writing with like a generic version, without version numbers, you had the side effect of everybody who already went to somebody else’s website and loaded that JavaScript file, as long as it’s the same CDN, it’s cached in their browser already. So it’s like this cool benefit… And that doesn’t exist anymore, I’ve learned that recently. I actually learned it from a tweet from Laurie Voss, who also learned it recently… Which led to a post by Stefan Judis, “Say goodbye to resource-caching across sites and domains.”
It’s not actually new… I think it changed back in October. Maybe even October 2020. So it might be like I’m late to this party. Kball is nodding along, so I think he’s known this for a while…
I remember hearing this quite a while ago… But also, everything since March 2020 is like one month over and over and over again, so really, who cares…?
Well, that’s why it’s cool. It’s like, TIL, today I learned. I just learned this. It’s not new, but I learned it, and… Maybe it’s new to you. It was new to me. It’s not like I’m using it anyways anymore, but I just thought it was a cool thing that we could all do. It kind of felt like a community thing to do, it’s like “Hey, let’s all just load this one JavaScript file once and be done with it.” But that is now gone, and I think it’s gone for good reasons; I think it actually improves privacy and security quite a bit, and other things… And I think the caching benefits were somewhat nominal anyways.
Anyways, I’ll link up this article, “Say goodbye to resource-caching across sites and domains”, and you can read about it for yourself. But yeah, I’ve just learned that recently, and I was like, “Huh. Show what I know.” But now I know, and now you know.
Alright, Kball, I stalled long enough… I’m acting as if you’re not prepared, but you totally are; I’m just messing with you. It’s your turn, what have you got?
Yeah, so I have kind of a fun one. This is in the TypeScript, and actually, when I was trying to track this down, I consulted our TypeScript expert, Nick Nisi… So I had a bug that I had to fix the other day, where a React component was failing. And it was failing because it was getting passed a prop that it thought it could render as a React node, and the caller had changed it to be something else, that needed to be interpreted in a certain way.
[48:19] So you know, quick bug fix noticed it changed the colar to passive react node and it was fine… But then I was like, “Wait, this is typed.” The component declared it to be expecting a React Node; how did it possibly not get caught by TypeScript? We were passing something that React didn’t know how to render. And I spent a while trying to dig into this, like “Did we do something wrong? What’s going on?” It turns out – so the TypeScript definitions for React components, React node and all these things, are coming from definitely typed… And React node is defined as - it’s either a React child, a React fragment, a React portal, boolean, null or undefined. React fragment, for reasons that I don’t know, is defined as empty object or React node array… Which, basically empty object is essentially any. This is the most permissive type you could possibly have.
So if you are using types in a React app and you are typing props as a React node because you think that’s gonna save you or keep you from passing things that are gonna not be able to be rendered as React, you are not protected. React.reactnode as a type is meaningless. It does not protect you from anything. This is apparently a known issue, it’s in the GitHub repo since 2018…
Well…
…there have been discussions, there was a proposed fix, and then the discussion dropped and nobody’s fixed it. So I am looking at doing like a patch locally in our application around it, but broadly, the thing I learned today is if you’re relying on the react.reactnode type you are completely and utterly unprotected from type errors.
Oh, man… What are you using instead?
So… TBD, because I’m still trying to figure this out. In the discussion around the issue, there was a proposed different definition for React fragment, that was a little bit more well-defined. So what I’m looking at doing is there’s like a – what’s it called, like package patch, or Node patch…? So a way you can patch Node modules locally. So I’m looking at patching just the definition of React fragment, which is the one that’s opening this type up.
I took the patch from the description, put it in and ran my type checker, and it blew up with errors, so I actually don’t know if that’s gonna be a viable option yet or not.
Another thing that I was considering if that doesn’t work is actually just defining a custom type that kind of captures all the subcases that we care about, and then just doesn’t open; and it’ll probably miss one or two things that in theory would also work, but that we don’t use, and so then we don’t have to worry about it.
So yeah, the solution that I’m coming to is still in progress… But the thing that I learned is this thing is broken and it’s leaving your type system open to all sorts of errors that will only show up at runtime.
Have you tried JavaScript? I hear it’s pretty good…
Well, then I’d be unprotected everywhere. [laughter]
You wouldn’t have gone through none of this trouble, and been landing in the exact same position on these errors, you know?
Yeah.
It would have cropped up at runtime.
The whole reason to do this is so that we can eliminate these whole classes of errors from ever making it into runtime. So to discover that we were very much unprotected for… What is it – I mean, I grepped our codebase, there’s like 180 references to react.reactnode types at different places. So this is something that we are relying on quite a bit.
Yeah. It’s a false sense of security.
Exactly.
Well, hopefully you find a fix. That is interesting… So probably if you guys are using it that much, probably a lot of people are using it a lot, don’t you think? It’s pretty common.
I suspect that many people are using this and thinking they are more protected than they are.
[52:12] Well, if you can come up with a solution and fix it, you could help probably thousands of people.
Yeah, so that’s one of the things we’re looking for… It’s like, okay, if we can find the fix, then we can try to make the time to get it submitted back upstream and get it to work… Or at least post how we fixed it on there so that other folks who run into this can do it.
That’s a big thing to learn. Alright, there you have it, TIL. Now, our final segment today is gonna be a Project Focus. Normally, what we would do is we would pick a project, the four of us would check it out, we would tell you all about it and discuss. We’re gonna do it a little bit differently today. Instead, the author of the Vest framework joined me earlier this week, and he told me all about it… So we will end TIL. Say goodbye to Amelia, Kball and Ali. Thanks so much for hanging out, this has been lots of fun. And we’ll say hello to Vest right after this.
So this is our Project Focus segment. We are focusing in on Vest. Now, normally, when we do a Project Focus, it’s the regular panelists, we take a look at a deal, we talk about it… But today we have a special treat. We’re actually joined by the author of Vest, Evyatar. You actually were listening to a show where we were talking about form validation and you reached out to me and said “Hey, I’ve got a form validation thing, it’s pretty cool.” I tend to agree with you. I’ve looked at it, it looks cool to me… So first of all, welcome to JS Party, and then secondly, let’s talk about this project of yours.
Hey. Awesome to be here.
So it’s been about ten months since you first contacted me and said “Hey, form validations… A pain in the butt. I’ve got a nice solution”, and I think I was ranting a little bit about how it’s gotten harder and easier over the years, and there’s certain ones that are still tricky, especially when you’re building purely frontend things, because they require backend knowledge. If I do recall what I was talking about then, Vest is your declarative validations framework which is inspired by unit testing libraries. That’s a cool angle; I’ve never thought about doing it that way. So tell us what we mean by “inspired by unit testing libraries.”
So Vest basically takes the general syntax of unit testing libraries like Mocha or Jest that many frontend developers are now familiar with, and it tries to adopt that same syntax or a very similar syntax of validation suite for the world of form validation. Because in the world of unit testing, what we basically have is a big suite of different tests that make sure that our code, our functions match some criteria.
[56:06] And when you think about it, form validation is pretty much the same; so you have the big construct - so you don’t have a unit testing suite, but you have a form, and inside of it you have some different fields. And each field, at least in your form validation, has to match some criteria. So why not take that same unit testing structure and use it for form validation?
Yeah. And so do you run those validations as if they’re tests? Do you have some sort of a runner than then says “Yes, this executes correctly”? Or do you not have to, because you’re basically writing the test when you’re creating the validation rules; is that how it works?
Exactly. So Vest internally works exactly like a unit testing framework. Actually, it could be even a unit testing framework if it wasn’t run on the browser and if I hooked some CLI to it… But exactly as you mentioned it, you just write the validation as a series of tests.
In the beginning, I actually wrote it as an experiment, and I learned that there are very significant values and benefits that you get from it.
Hm. So what are some of those values and benefits that you get from it?
Most frontend developers have written some sort of form validation, whether it be with just plain functions that they write, or with a third-party library or a schema validation library… And most of them are very useful, but there are places where they are very rigid as well. For example, when you have multiple criteria for the form validation for a specific field, for example the username - it is required, so yeah, required; it has to match some specific length, and it has a third test, for example for “the username isn’t already taken on the server”. Now, expressing all these as a series of different tests or a series of different validations is very difficult to do with traditional validations, because you don’t really have the structure for specifying different criteria. So you either put everything in the same function for one field, or sometimes you even put them in just one big functions for all validations, for all fields. And when using a suite-like test for form validation, you get a specific test for each scenario, for each field, and you can mix and match, and everything is very orderly outside of your feature code.
So I assume the same thing applies to a lot of the built-in new(ish) HTML validations. So there are things you can do, such as required, such as – you can do format attributes in your HTML. Those are similar where like they get you so far, but then when your form gets sufficiently complex, they fail, because they just don’t have that flexibility, such as combining multiple rules, or waterfall rules…
Exactly.
…so it makes sense. What happens with Vest on your failure states? A lot of times you have to then interact with the rest of your page and say “Okay, if this field is not valid, I want to display this error message, or put a border red around it… And if everything isn’t passing, I don’t wanna submit the form.” Sometimes you have more complex constraints even than that. That stop form submissions. Sometimes you may hide or show other areas of a form. How does Vest work in that context?
Seamlessly and beautifully, I’d say…
Oh, nice.
…even though I shouldn’t say it about my own framework.
Seamlessly and beautifully. I like that answer.
Yeah… But now seriously, Vest takes its syntax from a unit testing library. And in unit testing libraries you have different tests for each scenario. And each test has its own description. For example, in the case of username, I try to do the same thing, so I say “test”, I write the function test and specify it’s for the username field, and then I have the validation message the user would get in case of a failure, just as the description for the test.
[01:00:13.05] So when writing the validation, it’s easy for you to understand what’s going on, when reading it, it’s easy for you to understand what’s going on, and the output of Vest is that test description. Now, this is the most basic scenario, that you have just the validation message. You mentioned a few more. So if you want to display the validation message in red - well, Vest is not a UI framework and it doesn’t care much about the UI, but it does give you some class name generator based on top of the validation result. So you give it back the validation result, and the name of the class names you want to display at any validation stage. So for example in case it’s valid, you want to show the success class name, and in case it’s failing, you wanna show the invalid, and in case it’s warning, then just say warning… And you get back a list of validation class names for each of the failing or passing validation fields.
Very cool. That leads me into the other aspect that I thought was a very nice way of putting it together. First of all, dependency-free, so it’s very small, but more importantly perhaps is framework-agnostic. So like you said, Vest is not a UI library, it doesn’t really care which UI library you use. So whether you’re on the React or the Svelte train, it plays well with all these circumstances, right?
Exactly, exactly… Which is a big benefit, I think, over the other frameworks that usually are UI dependent.
Yeah, that’s very cool. So back to my rant… I think I was referring to a very specific constraint, which is still hard to do, in many cases; it requires some sort of backend knowledge, which is uniqueness. So you’re on Twitter, as am I… On Twitter you are @evyataral… Did I pronounce that right?
Yeah.
So if I go to sign up today and I’m on Twitter.com trying to sign up, and I try to use your handle, Twitter is gonna do some sort of uniqueness validation and say “This username is already taken.” And they don’t load all their handles into the web page, because that would be silly. They do a backend check. So how does Vest work with specifically uniqueness constraints, but anything that requires a third-party knowledge?
So basically - and I’d say I tried to stay as close as possible to the world of unit testing frameworks… And the way you do it in unit testing frameworks like Mocha or Jest - you run an async test; inside that test, you do that async logic. The way it works inside of Jest, for example - you just pass an async function, then if it throws, then the test fails. The same works with Vest.
So if you have an async test - for example, I have a test function in which I use an async callback. It’s hard to describe, of course, over audio, but you use an async function; if that async function throws, then the validation fails.
As easy as that. So anything in that async that you need to go ahead and get done, whether that’s an API call or some fancy algorithm crunching - maybe you run an ML model - it doesn’t really matter, as long as it’s just sitting there, waiting, and when it comes back, then that one comes back. So I assume at that point the form is invalid, or the form is unable to be submitted or moved forward according to Vest’s knowledge, until that thing passes. Is that the case?
Yeah. So unlike most frameworks, and most models of thinking about form validation, in Vest fails are required by default, unless specifically defined as optional. This makes it so that as long as not all fields are filled, or as long as not all required fields are passing, then the validation is not valid to begin with, or is not valid at all. So if you get your validation suite and you try to run “is valid” on it, it will always say no, unless all the required fields are passed in.
[01:04:10.27] Very cool. So, I should say, Vest is not a new library. It looks like you’re on npm version 4.1.2, so you had some iteration on this thing… Tell us the back-story - where did you start this framework, and how long have you been working on it?
I actually started working on Vest a couple of years ago, in around 2016 or 2017. Back then it wasn’t even called Vest, it was called Passable. And I was working on it when I worked at Fiverr.com. Back then, I was just learning the first time about unit testing with Mocha, it was, I think… And as I said before, the ideas just clicked to me, because - well, you have that suite testing, and the thinking model, mental model of testing for validation was just the same for me. In the beginning I also thought about “Well, we have to do it in JavaScript, because if we do it in JavaScript, then we can run it on Node and have validations that are the same on the server and the browsers.” This is a defining criteria for Vest. And iterating over this idea - in the beginning, it was terrible. I didn’t know how to write a unit testing framework. But going again and again, I landed on the solution for Vest, which I think is pretty good.
That’s awesome. So you can run Vest just as well on the backend as you can run it on the frontend. So you can have your in-line, in-page, immediate validations that run, but in case somebody’s sneaky, disables that code or just posts directly to your backend form, you can also run those exact same rules on the backend, and it’s all hunkydory.
Exactly.
Love it. That’s cool, man. That’s like the holy grail right there. I really do dig this format; people can check it out on the website, vestjs.dev. And it is hard to say over audio, but for example you test the username is required, and you just have this one function call enforced, “data.username is not blank”, and you just call that function, and you’re basically writing your test right there.
I used to do Ruby on Rails, and they had validations built into the Ruby code, in the models, and you’d write the validations, and they’re really succinct like that… And then you’d have to go write a test that tests the same exact thing; and it always felt so redundant to me. I’d just skip the test. I was like, “You know, it’s fine. It works.” It was a very terse syntax. And of course, that would bite me one out of a thousand times, but in this case, it’s zero out of a thousand. You don’t have to rewrite the exact same rule twice, let alone a third time in your frontend code… So that’s spectacular.
Exactly.
So the website, vestjs.dev - that’s where people can check it out. Anything we need to know about this before we call it a segment?
Just try it, tell me if you find anything missing… I really enjoy working on it. And if you want to contribute to the project and help out, feel free. I’m always happy to help.
Cool. Well, Evyatar, thanks for joining me for this Project Focus, and we appreciate your open sourcing this work.
Thank you for having me.
Our transcripts are open source on GitHub. Improvements are welcome. 💚