React Native Radio

RNR 260 - TYPESCRIPT BY DEFAULT: Unpacking React Native 0.71

Episode Summary

Robin and Jamon unpack the latest changes in React Native 0.71, including TypeScript by default, developer experience improvements, and flexbox gap support!

Episode Notes

Robin and Jamon unpack the latest changes in React Native 0.71, including TypeScript by default, developer experience improvements, and flexbox gap support!

This episode is brought to you by Infinite Red! Infinite Red is a premier React Native design and development agency located in the USA. With five years of React Native experience and deep roots in the React Native community (hosts of Chain React and the React Native Newsletter), Infinite Red is the best choice for your next React Native app.

Helpful Links:

  1. RN 0.71 blog post
  2. RNR 187 - Typescript
  3. RNR 251 - React Native 0.70
  4. Our episode's sponsor: Chain React

Connect With Us!

Episode Transcription

Todd Werth:

Welcome back to React Native Radio Podcast. Brought to you by Adorable Labs. Did you know that Adorable Labs produces over 80% of the cute kitten content on the internet? Well, now you do. Episode 260, Unpacking React Native 0.71.

Jamon Holmgren:

I don't think I'm ready for this, Robin.

Robin Heinze:

What? Ready to make a podcast?

Jamon Holmgren:

Well, I'm never ready to make a podcast, but I'm really thinking about tomorrow, because my son turns 18. He's going to be an adult, which is crazy.

Robin Heinze:

What? He was a kid just yesterday.

Jamon Holmgren:

I know. Well, you joined us when... When did you join us?

Robin Heinze:

Let's see, beginning of 2017.

Jamon Holmgren:

2017. So, he would've been 12.

Robin Heinze:

12, yeah.

Jamon Holmgren:

12 or 13. Yeah, in that range.

Robin Heinze:

That's a big difference.

Jamon Holmgren:

Yeah, it is. It's mind-blowing and it's a different phase of life. I don't know. I don't know if I'm ready for it.

Robin Heinze:

I mean, my kids are almost four and one. So, I have a ways to go before I hit that phase.

Jamon Holmgren:

That's a different phase of life too. Wow. Yeah. That's like a lot of physical labor, a lot of carrying kids around, a lot of that sort of thing. I don't have to do that so much anymore.

Robin Heinze:

We were just talking about how when your kids are toddlers, you have to hold them down and physically brush their teeth for them.

Jamon Holmgren:

I know, right?

Robin Heinze:

And then when they're older it takes them 10 minutes and you can't make them do it, but it takes them 10 minutes when they do.

Jamon Holmgren:

Yes. My nine-year old just takes forever. I'm just glad she's doing it, but that means that we're... She misses the bus all the time and I'm having to drive her in. I don't know. My parents wouldn't have never stood for this.

Robin Heinze:

I get to see this every time we record because Jamon gets his kids ready for school and then comes straight to the podcast, so I always get to hear stories of how crazy his morning was.

Jamon Holmgren:

I know. Someday I'll rant about how parents drop off their kids at school. I'm not a road rage person. I'm not a person who gets mad in my car, but that's one place that is the exception that proves the rule. I get so mad in the parking lot there. Anyway, I'm not going to do it right now. We'll be here all day.

Robin Heinze:

Mark's probably already stopped listening.

Jamon Holmgren:

He's got that skip forward button ingrained in him. Well, we do have a lot to get to, so we should probably get to that. I am Jamon, your host and friendly CTO of Infinite Red. I live in the beautiful Pacific Northwest with my wife, and for now, four kids. I guess you can still call them your kids even when they're not a kid.

Robin Heinze:

Three kids and one adult.

Jamon Holmgren:

Yeah, exactly. Yeah. I play recreational hockey and I drive my tractor whenever I get an excuse to, which has not been very much lately. It's been parked, but I did move it around recently. I had a tree fall on my shed and I had to move it.

Robin Heinze:

Oh yeah. It's been super windy recently.

Jamon Holmgren:

I'm joined today by my innovative co-host, Robin. Mazen is out sick today. Robin is a Senior Software Engineer at Infinite Red. She's located west of Portland, Oregon with her husband and two little kids, who she still helps brush their teeth, and has specialized in React Native for the past five years. And I should also mention that this episode is sponsored by Chain React 2023. Chain React is back and you should come. Go to chainreactconf.com. It's a React Native conference that just is React Native. That's all there is. Just all the talks are about React Native. There are hundreds of React Native engineers there. It's a lot of fun. We haven't done it since 2019, so you need to come. We're really planning something special this year, so can't wait to see everybody there.

All right. Let's get into our topic for today. React Native 0.71 was just released, so our topic is Unpacking React Native 0.71. I'm not sure if we'll actually do the clickbaity title, but we thought about putting in all caps, TYPESCRIPT BY DEFAULT.

Robin Heinze:

That's really the headline.

Jamon Holmgren:

Yes.

Robin Heinze:

I mean, they use that headline themselves in the release blog, so.

Jamon Holmgren:

Yeah, exactly.

Robin Heinze:

It's valid.

Jamon Holmgren:

It's a huge deal.

Robin Heinze:

It is a huge deal. This release is full of huge deals.

Jamon Holmgren:

I agree, and has really good documentation, right?

Robin Heinze:

Mm-hmm. I was just reading through all the release notes and everything for this one. I kept being super impressed by how well everything was laid out and explained, like this was the problem. This is what we did to fix it. This is who it's going to affect. Very, very well done from the documentation side.

Jamon Holmgren:

I got to give a shout out to Matt Carroll from Meta, Nicola Corti from Meta, Nick Gerleman from Meta, and Lorenzo Sciandra from Microsoft who put together the release notes in the blog post. They always do such a great job, but this one I think they're really kind of hitting another gear. So let's start talking about it. Let's talk about the TypeScript by default just right off the bat. Let's get right into that.

Robin Heinze:

That's really the headliner here.

Jamon Holmgren:

It is. It's the biggest deal. And Meta has always used Flow internally, or I guess in the past, I don't know, seven, eight years to use Flow internally. And so, moving the open source library part of it to TypeScript, it feels significant to me. It feels like a big deal.

Robin Heinze:

Yeah. Oh, yeah. It's like it's an endorsement. They use the term investment, which it is. They're putting their money behind TypeScript and really putting their stamp on it.

Jamon Holmgren:

Yeah, and, I guess, what does this mean? What does that mean? Because obviously, Ignite our boilerplate, has come with TypeScript forever, so you can use TypeScript with React Native already. I think what it really means is that when you spin up a brand new React Native project, you'll get a TypeScript app by default. You'll get a tsconfig.json, your ID will recognize all of that and it'll be working. And also, the TypeScript declarations will come directly from React Native itself.

Robin Heinze:

Correct.

Jamon Holmgren:

React Native itself won't be written in TypeScript though, as far as I know.

Robin Heinze:

Is it not written in TypeScript?

Jamon Holmgren:

It's not. The actual JavaScript parts of React Native, it's JavaScript and I think it has Flow Types.

Robin Heinze:

If you're a Flow user, you can still use Flow. The biggest difference will be that the Flow configuration will not be updated with the template anymore. The reacting of repository itself will still contain the Flow config, so you just have to grab it from there and move it over manually.

Jamon Holmgren:

Yeah, that's right. I mean, the amount of people using Flow has been stagnating or dropping every year it seems like. So really, this is sort of them admitting that, at least publicly, maybe not internally at Meta, but publicly outside open source, that TypeScript has won that battle and they're going to let React Native kind of go with the Flow. Go with TypeScript in this case.

Robin Heinze:

Go with the TypeScript.

Jamon Holmgren:

Yeah, I mean from our standpoint, obviously we use Ignite anytime we can, so it comes with TypeScript by default, but I think it just sort of sends a pretty strong signal.

Robin Heinze:

Right. It's more about the effect it'll have on the community. You have people who maybe weren't making a conscious decision one way or the other about whether to use TypeScript or JavaScript, and then React Native gives you JavaScript by default, you use JavaScript. So this is going to just increase the number of people using and being familiar with TypeScript, which is only going to be a good thing in my opinion.

Jamon Holmgren:

I got to say, I would never have guessed that the JavaScript community would embrace Types back in the day when I learned it.

Robin Heinze:

They were very proud of their lack of Types.

Jamon Holmgren:

Totally.

Robin Heinze:

They're like, "We don't have Types and we like it that way."

Jamon Holmgren:

I'm a big TypeScript fan, so I'll disclaimer this before I say this, but there are times where I just miss the sort of hack it together days where you just kind of throw things together and you're not having to satisfy this overly pedantic compiler that's always telling you-

Robin Heinze:

You throw things together on a whim, you just hack it together and then you spend a whole day figuring out why your app won't load, and then you realize it's because you-

Jamon Holmgren:

I will say, the software that I built that lasted the longest was stuff that was built that way back in those days. A lot of the stuff that... Anyway, that's a whole, get off my lawn discussion, that we don't need to go into. I do love TypeScript. I think that TypeScript, everybody probably knows my opinions by now, but-

Robin Heinze:

We have a whole episode. We will link it in the show notes, but we have a whole episode about how much we love TypeScript.

Jamon Holmgren:

We do. We love it, and TypeScript is one of those things that just needs to be a help and not a hindrance. And so if you have not bought in yet on TypeScript, go listen to that episode. I think it'll give you some food for thought.

Robin Heinze:

Mazen was actually a convert from that episode.

Jamon Holmgren:

Yeah.

Robin Heinze:

He didn't work at Infinite Red at the time, but he used that episode to get his boss to agree to implement TypeScript in their app, and then he came to work for us.

Jamon Holmgren:

Send that episode. Then he came to work for us. That's what happens.

Robin Heinze:

We're creating new TypeScript evangelists.

Jamon Holmgren:

That wasn't the only thing in the release though. What else do we have that's exciting, Robin?

Robin Heinze:

Flexbox Gap, which if you're familiar with CSS Gap at all, which you probably are, if you're not CSS Gap has been around for quite a while and it's a property that lets you specify a distance between child components within a parent, rather than having to specify a margin on each one, which is a headache. But that property, which has been in CSS for a long time, I don't know how long, but a long time, is now also available in React Native Flexbox, which is amazing and has been asked for for a long time.

Jamon Holmgren:

One of the most highly requested features just because it's so useful.

Robin Heinze:

Mm-hmm. If you've ever tried to lay out a list or a grid and you're like, "Well, I need them to have margin, but then I don't want them to have margin on the outside. I only want them to have space between each other." And you have to be like, "Okay, margin right if you're on the left side, and margin left if you're on the right," and yeah, it's annoying. This is very, very welcome and will be very useful.

Jamon Holmgren:

So I was talking to a friend and at his company he handles the component library and design system and it's cross platform. So it uses the same components for React and React Native, web and mobile. And he said that on the website, of course, he just uses CSS Gap, but when he actually is implementing on the mobile side, he has to use all kinds of different views and styling and a bunch of logic to make it work the way it should. So he said when this lands, it's going to allow him to remove a lot of layers of views and styling and whatnot. So I think that's a good thing. It just gives us a very useful tool to lay out our views and all the elements and components that we need to do in the right way.

Robin Heinze:

This really falls right in line with something that the React Native core team has been trying really hard to do, which is to add better alignment between the various platforms. And this is just one more step in making the APIs between mobile and web more aligned, easier to share code. They're really focusing on that as a long-term goal and this is just one more step in that direction.

Jamon Holmgren:

Yeah, totally. Along those lines, there are some web inspired props coming in to kind of build that alignment for accessibility, styles and events, so that web compatibility is continuing to narrow. We can see that in the future there's going to be moments where you're going to have very, very aligned, very, very similar, maybe exactly the same code between React Native and React. And I think that is a goal. Also Pointer Events. I think Pointer Events is big because obviously you don't need those for touch screens or touch only screens, but Pointer Events are useful for when you're sharing code across platforms.

Robin Heinze:

Definitely. On the accessibility side they added ARIA props, which if you're a web developer, you're probably familiar with ARIA props for accessibility, but they added them basically as an alias to the existing React Native accessibility props, but the fact that you can now use the same names and the same API between them is really significant.

So sort of the same thing with some components like image and text input. They added props and changed some prop names to better align with the DOM prop names for the equivalent web components. Like on image, they have alt, tint color, cross-origin, height, refer policy, there's a few others, but just across the board trying to make web and mobile more aligned in terms of the names of things and how things are referred to. So we did an episode a little bit ago about the discussion posts that the core team put out and one of the big themes throughout that, or one of the biggest issues that they said they were going to address was this. So it's really nice to see them sort of taking that and actually making good on it. And we see that in the releases, so.

Jamon Holmgren:

So can I have a hot take on this? Am I allowed to?

Robin Heinze:

Yeah.

Jamon Holmgren:

I will acknowledge upfront that this is a lost battle and the way they're going is the right way to go as of now. But I really wish, I really wish, that React had become more like React Native, not the other way around. With that said, I acknowledge there's no way you can fight the whale that is web. I mean, web developers control the world.

Robin Heinze:

Yes.

Jamon Holmgren:

And that's an unfortunate reality.

Robin Heinze:

It's true. I mean everything, the web is what started it all. We wouldn't have React Native if we didn't have web.

Jamon Holmgren:

The whole problem, and I saw the tweet recently and this kind of put it all into clarity for me, the web really is two platforms in one. It's a document platform and it's an app platform, and it really was a document platform first. And so everything that you do is kind of built around supporting these two things.

Robin Heinze:

Somebody invented JavaScript and the world was forever changed.

Jamon Holmgren:

Yeah, thanks a lot Brendan Eich. And the problem is documents really do have different needs, like classes and cascading styles totally makes sense for documents. It's a totally great way to build websites. And honestly, there's still a lot of them. I mean, we're not talking about old-school websites way back in the day, there's still plenty of document websites. You look at something, even just going to cnn.com, that's a document website, that's not an app. There's a lot of interactivity and dynamic content and all of those things. I'm not saying it's not... They're equal, it's not below apps, but apps have different needs. When you have an app where you are spending a fair amount of time writing or interacting and using the app rather than consuming content, then the needs change a bit. And the way that the UIs work are way different, they don't flow the same way. The styles don't have to cascade the same way.

And I have this half form thought that on mobile, I would even say flutter developers and React Native developers think more alike than React and React Native developers in some ways, just because it's totally different platforms. Mobile being very much an app platform. It is not a document platform in any way. It is an app platform. And so because of that, we think in terms of what serves apps and web thinks about in terms of what serves documents and then apps. So that's where the kind of the culture clash comes in. However, we've lost this battle. Web is just way too big. You can't deal with that. So we're going to be building in document paradigms into our app platform.

Robin Heinze:

I mean we tried-

Jamon Holmgren:

That hot enough take?

Robin Heinze:

We tried pretty valiantly. That was a pretty hot take. I'm not going to lie.

Jamon Holmgren:

I don't think I'll tweet about that.

Robin Heinze:

I'll have to put that in a teaser. Get people to click on the episode.

Jamon Holmgren:

All right. We're only through what, three four of these. We should probably keep moving along. What's the next one, Robin?

Robin Heinze:

Restoring prop types, which when I read it I was like, "What? Why would you go back to bring prop types?"

Jamon Holmgren:

Why bring that back?

Robin Heinze:

"You just made TypeScript the default, which is such a better solution. Why are you bringing back prop types?" And then I realize it's basically just an undeprecation because a bunch of stuff broke when they downgraded it from deprecated to just gone, so they put it back. So it's still deprecated, but it's in there again. So stuff isn't as broken. If you're not familiar with prop types, it was their system for typing component props years ago.

Jamon Holmgren:

Yeah, it was like pre widespread adoption of typed JavaScripts, so it was very much, we need some type safety here with these props, so let's exist.

Robin Heinze:

Right. It was like adding types, but it was just components so you could specify-

Jamon Holmgren:

Yeah, just the props.

Robin Heinze:

... the props in your components were Strings or Arrays, or whatever.

Jamon Holmgren:

And it was run time.

Robin Heinze:

... or whatever. Yeah.

Jamon Holmgren:

It was run time, not build time. Compile time. So, yeah.

Robin Heinze:

Right. So you would still have to run your app to find out that you had to find your prop types wrong. Anyway, it was in the past and TypeScript is much better. But it's in there again, if you are having errors about prop types being gone.

Jamon Holmgren:

Temporarily.

Robin Heinze:

Temporarily.

Jamon Holmgren:

It's going to go away.

Robin Heinze:

It still will go away. But community just needed some more time to fix-

Jamon Holmgren:

To adjust. Yeah.

Robin Heinze:

Yeah.

Jamon Holmgren:

Let's talk about the developer experience improvements. The React Dev Tools in particular have gotten some upgrades. There's the click to inspect, allows you to click a button and then click on a component on the simulator, which is actually super useful. I like that a ton.

Robin Heinze:

Again, Making mobile more like web.

Jamon Holmgren:

It is.

Robin Heinze:

In a good way. That's a pretty good feature.

Jamon Holmgren:

That's a good one. Yeah, we need better debugging tools, which by the way, we are investing a bunch of time into Reactotron. Version four should be coming out at some point here and we are doing some planning for version five. So just a little plug for Reactotron. I know there's a lot of you users out there. The opposite of that where you hover over something in the inspector and it highlights it in the simulator is also a feature that came to React Dev Tools.

Robin Heinze:

Hey, that's really cool.

Jamon Holmgren:

So that's pretty cool.

Robin Heinze:

That's really cool.

Jamon Holmgren:

Yeah. I would love at some point to try to build in React Dev Tools in to Reactotron, that's an option. I don't think it's super farfetched. I probably shouldn't talk about this stuff publicly until we've actually had some conversations. But the cool thing about it is then you could just have Reactotron be your full experience. You don't have to have Chrome open, you don't have to try to connect through all this stuff. Reactotron just handles everything. Obviously it doesn't handle all the stuff that Flipper did, but that's a whole nother ball of wax there.

Robin Heinze:

Yeah, we won't go down that rabbit hole.

Jamon Holmgren:

We won't. So Hermes became default in 0.70 and then in 71, the one we're talking about, they are upgrading Hermes with improved source maps, better performance on JSON.pars, which is actually a really important thing because that happens a lot. You're using JSON.pars a ton. So performance optimization that improves it up to 30%, that's a pretty significant increase. And also String.at, TypedArray.at and Array.at which-

Robin Heinze:

But the .at just lets you specify an index?

Jamon Holmgren:

The .at on String or Array objects allows you, it's a lot like the square bracket notation where you would just put in square bracket zero for the first item or five. But the difference is that with normal JavaScript Arrays, if you were to put square bracket negative one, it thinks that you're looking for the index at negative one. But with .at parenthesis negative one, it will just simply go to the end of the Array. So it gives you the last one. Or if you want negative three, it'll grab the third from the last.

Robin Heinze:

I didn't know that.

Jamon Holmgren:

It just allows kind of like... Yeah, it's sort of catching over something there…

Robin Heinze:

I don't know why I thought you could do that with square bracket notation, but.

Jamon Holmgren:

Yeah, you can't. I think kind of a flaw in JavaScript and it's something that other languages do have. You can do a negative notation to count from the right hand side of the end of the Array. I mean you could write your own in like 10 seconds. A .at, but at least it's built in. Now, there are some new architecture updates as well.

Robin Heinze:

Yep. There's a whole bunch of new architecture updates. If you're using the new architecture already or thinking about it, the first thing is reduced build times. So they moved to using Maven Central, which lets them store a bunch of pre-built artifacts on Maven Central. And so you don't have to spend build time compiling those.

Jamon Holmgren:

These are things that almost never change. So there's no point in everybody rebuilding them thousands and thousands of and thousands of times across all these machines. Just build it once, download it and you're done.

Robin Heinze:

So that's a big improvement. Also, they're making a lot of changes to reduce the amount of Native code that you're exposed to or need to change or update in the template itself. So when you in it a React Native app, it comes with a bunch of Native code. They're trying to reduce the amount that there is and move whatever they can back into the framework itself so that you don't have to worry about it. You don't have to worry about changing it when upgrades come through. You don't have to worry about configuring things or potentially having things break. So they're really trying to simplify the experience. In as of this version, you do not need to add any C++ code in your app in order to enable the new architecture, which you did before. And it was error prone I think, or it introduced some errors if it wasn't done exactly right. And so this makes it a much more simple experience.

Jamon Holmgren:

Yeah. I like this a lot. It really makes the experience better. And in fact, actually Frank Calise, one of our developers here at Infinite Red, did an upgrade to Ignite as a sort of test to 0.71 and he said he was just deleting a lot of Native code. He was just deleting a lot of it, which was really cool. And that gets moved into the React Native core, which means that upgrades later should be easier because they can make those changes internally and we don't have to go into our apps and make those changes. They still leave the door open to customizing those things. So you can certainly make the customizations you used to, but by default you don't have to.

Robin Heinze:

I think based on the feedback that they've gotten a lot, which is that upgrades are painful and difficult, they're really putting effort into, okay, what do we put in the template? How do we take things out of the template that are unnecessary and really expose only what you really, really need to make your app work and click. Like the stuff that you do need to configure will expose, but then remove everything else, because if it can be updated in React Native itself, then that makes it so much simpler for us to just increase the version number and then that brings in all the changes without having to manually keep track of the diffs and make those changes ourselves. So they're really, really focusing on that developer experience.

Jamon Holmgren:

Yeah, I love that. It's great. Moving on, they're getting rid of AsyncStorage, so it's been deprecated since 0.59. So that's a long time ago.

Robin Heinze:

Really? Wow, has it been that long?

Jamon Holmgren:

That long, it's been deprecated and they're finally saying, okay, we're ripping this out. So it's gone.

Robin Heinze:

If you haven't already moved to the community AsyncStorage, you should. Or even alternative AsyncStorage libraries like MMTV.

Jamon Holmgren:

MMTV. Yeah, exactly. I predict it'll still cause issues, because there are so many libraries that-

Robin Heinze:

It'll probably be like prop types where they put it back in and say...

Jamon Holmgren:

We need more time.

Robin Heinze:

We'll see. We'll see.

Jamon Holmgren:

A few other things. Better stack frame collapsing. I like this one. So it shows your code more often rather than internal React Native frames when you get a conception.

Robin Heinze:

Love that. That's another one that was mentioned in the discussion post was error stack traces, so it's really, really nice to see direct improvements based on feedback.

Jamon Holmgren:

If you need a reason to upgrade a 71, this is a good one, in my opinion. Android template improvements, much less code there. That's kind of similar to what we talked about before. And console logs still show up in the console even if they're ignored for LogBox because those are really two different things. Like LogBox, you don't want things popping up in your UI, but who cares about the console? Let it flow out there. And they also removed MaskedViewIOS, which I don't think was... That was iOS only anyway, so they're kind of going away from any sort of platform specific components.

So general impressions, and I'll go first here. I think every release should make React Native just a bit nicer to use. I'm glad to see the focus on developer experience here and narrowing back to kind of narrowing the gap between React Web and React Native. Dev tools getting better. Prop types coming back so that the developers don't have to deal with kind of annoying problems. Faster build times is huge. Less C++ code. Less Native code in general. Better error stacks. Of course Flex Gap. TypeScript by default. In my opinion, it's moving in the right direction. This is a very good release. I think that moving to 71 as soon as we can is a worthwhile thing. What do you think Robin?

Robin Heinze:

So my overall thoughts, absolutely jam-packed release. It's been a long time since I was this excited about a release and everything it had to offer. I think there's a ton of evidence that they're really listening to the community and what the community's been asking for and acting on it, which is really, really great to see. And I think this is a must upgrade.

Jamon Holmgren:

Yeah, I think so too. Well, I think that's it for this episode. We have some really amazing episodes coming up in the future, so stay tuned, of course. Honestly, really excited about a couple of these. One that we are going to do. I'm going to do a little teaser, and it is about Maestro and we're going to have some people from the Maestro team on. This one I think is going to be a lot of fun. Maestro is a competitor to Appium and Detox, so end-to-end testing and it's sort of taking the mobile world by storm right now. We've talked with the team there at Maestro. We actually have some connections over there and they're just doing some really exciting stuff. So definitely stay tuned. Subscribe to React Native Radio. You can also join our Slack Community at community.infinite.red. We have over 2000 React Native developers there. Where can people find you on Twitter, robin?

Robin Heinze:

I'm @Robin_Heinze.

Jamon Holmgren:

You can find me @Jamon Holmgren and our show, Twitter @ReactNativeRdio. If you follow our show, Twitter there, you won't miss an episode. As always, thanks to our producer and editor, Todd Werth, our assistant editor and episode release coordinator, Jed Bartausky, our designer Justin Huskey and our guest coordinator, Derek Greenberg. Thanks to our sponsor Chain React. Check it out chainreactconf.com. Special thanks to all of you listening today. Make sure to subscribe on all of the major... I've read this, I don't know how many times, and I think I've noticed it before. Why would you... You know what? Actually, subscribe on all of the major podcasting platforms. You know, you only have to listen to it on one, but we like the numbers, right? We are React Native Radio. Robin, do you have a mom joke?

Robin Heinze:

I do. This is courtesy of Carlin. So Carlin, if you're listening, thanks for the joke. What do you call a knight who is afraid to fight?

Jamon Holmgren:

I don't know.

Robin Heinze:

Surrender.

Jamon Holmgren:

End with that, we will see you all next time.

Robin Heinze:

Time. Bye.