React Native Radio

RNR 229 - Building an Expo App for Mobile and Web with Josh Justice

Episode Summary

Jamon, Robin, and Mazen talk with former RNR host, Josh Justice, about building an Expo App for Mobile and Web. We also found out that Jamon is the only one who likes ski'ing.

Episode Notes

Jamon, Robin, and Mazen talk with former RNR host, Josh Justice, about building an Expo App for Mobile and Web. There is also some spirited conversation about skiing. 

This episode 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. Josh’s talk at ReactATL
  2. Surely
  3. Surely Github source
  4. React Native Web
  5. React Native Testing Library
  6. React Navigation for Web

Connect With Us!

Episode Transcription

Todd Werth:

Welcome back to React Native Radio podcast, brought to you by Intel. Sure the M1 chip is fast, but is it big and hot? Check and mate. Episode 229, building an app for web and mobile with Expo.

Jamon Holmgren:

Mazen or Robin. Are you two skiers? Do you go skiing winter time up on the mountains?

Robin Heinze:

Definitely not.

Jamon Holmgren:

No. Have you ever gone skiing or is that that was just like you went and you don't like it?

Robin Heinze:

I went as a kid, I guess, it was middle school, high school I went and my friend's dad taught me. And I got as far as the Green Hills and then I wiped out bad enough that my skis came off and went down the hill a little ways. And after that, I was over it and I've never really been since then. Don't really have a desire to go again. Because my joints have only gotten worse since childhood.

Jamon Holmgren:

It can be a brutal sport. What about you Mazen? Have you been skiing before?

Mazen Chami:

So I've gone twice. Bear in mind, I grew up in Africa. Didn't really get to see snow until about 18 years old when I moved to the US. When I went, I was told that all the slopes are open when I got to the top. Meanwhile, it was only the Black Diamond and whatever the one right underneath it is. So I had two horrible experiences going down. Luckily the second time I went, there was a friend of a friend that was with us and he was an NCAA skier. So I basically rode his back the whole way down. He just helped me out.

Robin Heinze:

That's a friend right there.

Mazen Chami:

Exactly. Safe to say if my kid or kids ever want to go skiing, I'll be watching them from the cabin.

Robin Heinze:

There you go. That's what I say. I was like, "If Travis, my husband wants to take my kids skiing, that's fine. I will sit and I'll watch."

Mazen Chami:

I'll go tubing. It's a lot of fun.

Robin Heinze:

Yeah, sledding is. Sledding and tubing are fun.

Jamon Holmgren:

Very, very fun. And they're a lot more accessible to everybody else. Yeah. We have this tradition. My wife and I and our family have this tradition to go up to a cabin up on Mount Hood, here near Portland and go skiing. Well, I mean, the kids don't go skiing. They tend to sit in a cabin and drink hot cocoa, which is great. I tried snowboarding once and had a horrible experience like Robin. Just fell and hit my head and I was just like, "This is stupid." But my wife, she loves skiing. So she convinced me to go and actually try this time skiing, well, two years ago, I guess. And so we did that and I loved it.

Jamon Holmgren:

And I'll tell you, here's my secret. I watched a bunch of YouTube videos before I went. There's a ton of YouTube videos about beginner skiing and I just watched an hour. My kids were like, "Are you seriously still watching skiing?" But I did that and then I didn't fall down once. Of course, I was just on the Buttercup Hill. And I think I went on the next one up once and that was scary, but I just did that snow plow my way down every time. And then this time my son, he's 17 [inaudible 00:03:33] and so we went together while [Cairo 00:03:36] went way up to the top of Black Diamond, or whatever she does. And we just snowplow our way down. I started getting to where I could carve a little bit and do some things. So it was fun and didn't fall down again. So happy about that. It was fun. I love it. It's like being up on the mountain where it's cold and silent and there aren't too many people up there.

Robin Heinze:

It is very quiet. Snow has that quality.

Jamon Holmgren:

Yeah. It has that quality and it's getting dark, but there's lights and you're up there just this peaceful snow coming down. So I am going to introduce our guest in a bit here, but I want to ask him, because I want him to be part of this conversation. Josh, have you been skiing?

Josh Justice:

I have. And it was just as bad as all of your experiences. In my twenties, went down. First time going down, did the pizza shape so long that my muscles were entirely exhausted and I couldn't learn to actually ski and I walked halfway down and never have done it again.

Robin Heinze:

Yeah.

Jamon Holmgren:

Fair enough. I feel like that's a common thing. I think if people first off, watch all those YouTube videos, just google-

Robin Heinze:

You can learn anything on YouTube.

Jamon Holmgren:

Yeah. You can learn anything on YouTube. You'll get really good... And literally, the one I watched started with, here is how you buckle your ski boots. That was how basic it was. But you know what? If you don't know how to buckle your ski boots, you might have a bad time. And that's actually like start small, go down the Bunny Hill, go down Buttercup, stay on that thing for the full first day. Don't even try the other ones, just do that. Be like Josh and just snowplow your way down and then eventually start figuring out other stuff. I don't know. It's pretty cool. But I've only been twice, so I can't be like, "Oh yeah, I'm some expert here."

Jamon Holmgren:

Anyway, let's get into this. I am Jamon Holmgren, your host, founder and CTO of Infinite Red. Clearly I am an Olympic class skier. And I am joined today by my dandy co-hosts. Dandy of course in the positive sense.

Robin Heinze:

I was going to say, I was like, "Which meaning of dandy are we talking about here?"

Jamon Holmgren:

We're digging deep into the barrel.

Robin Heinze:

No, I knew it's the positive

Jamon Holmgren:

It's the positive one. Yeah. We're digging deep into the bottom of the barrel of these positive adjectives. So you're going to have to use your imagination a little bit. Robin, of course and Mazen, and this mysterious former co-host who I will introduce in a bit here. Robin is a senior software engineer located in Portland, Oregon. Works at Infinite Red. Specializes in React Native. What's up, Robin?

Robin Heinze:

Oh, not much. Just [inaudible 00:06:15] podcast. I did get more sleep last night than I have been.

Jamon Holmgren:

That's good.

Robin Heinze:

So feeling good.

Jamon Holmgren:

Nice. Is it that Peter's getting more sleep or is Travis is taking over?

Robin Heinze:

Peter's getting more sleep.

Jamon Holmgren:

Okay. It's good to clarify. Then that's great. That's great. We're going to get peak Robin here. Mazen Chami is a senior software engineer here at Infinite Red. He Lives in Durham, North Carolina. Former pro soccer player and coach. And of course, co-host here at React Native Radio. How's it going, Mazen?

Mazen Chami:

Good. Good. Excited for spring, although it's rainy today.

Jamon Holmgren:

Yeah. Well, it's snow today. My kids are actually home for a snow day because there's a dusting of snow. Everybody in the Midwest is like, "Are you serious? A dusting of snow keeps you home?"

Mazen Chami:

It's the same here. If snow is in the forecast for next week, we'll shut down. That's fine. Grocery stores are empty.

Robin Heinze:

I'm just seeing flake starting to fall outside our house.

Jamon Holmgren:

Oh really?

Robin Heinze:

Yeah.

Jamon Holmgren:

See, we're a little bit north of you Robin. So sometimes it's a little different.

Robin Heinze:

I was listening on the radio that your schools were closed, but not ours yet.

Jamon Holmgren:

Yeah. That's another thing. People from out East or Midwest or whatever, come over here and just make fun of us. And then they go out and drive and they crash because the reality is that our snow is slippery. It's really slick. You get this hard ice everywhere. And also none of anything is set up for it. So yeah, it happens. Our guest today is Josh Justice. Josh was a former co-host of this. I actually did a few episodes with you, Josh back in the day before we acquired React Native Radio. So that's fun to have you back on the program after, what boy? It's been probably a couple years now, something like that. And Josh Justice has worked as a developer for 17 years across mobile front end and backend platforms. He currently serves as the web platform lead at Big Nerd Ranch, a web and mobile development shop in Atlanta, Georgia. He also writes, speaks and live streams about React Native testing and other software topics. It's actually fun because Josh also taught a testing workshop at Chain React. When was it? Was it 2018 or something like that? It was 2019.

Josh Justice:

I think it's 2019, because I attended in 2018 and then got that opportunity in 2019.

Robin Heinze:

The last time we had Chain. We'll have it again someday.

Jamon Holmgren:

Yeah. It's coming back sometime, but oh man. Yeah. It'll be great. And hopefully we can get you back for another workshop, Josh, because it was fantastic. I think Mazen you were in that workshop before you worked at Infinite Red, right?

Mazen Chami:

Yes, I was. I specifically went to Chain React for that workshop and I can say that I came out of it understanding a lot of React Native and how to test in React Native, which was great.

Josh Justice:

See. Thanks so much to the encouragement y'all. Yeah, I really enjoyed doing it. First workshop I've done and yeah, I would love to do it again next time Chain React is back.

Jamon Holmgren:

Yeah, that's awesome. Before we get into our topic, this episode is sponsored by Infinite Red. We are a premier React Native design and development agency located fully remote in the US and Canada. If you're looking for React Native expertise for your next React Native project, hit us up. You can learn more on our website, infinite.red/reactnative. And don't forget to mention that you heard about us through the React Native Radio podcast, but don't mention Josh because Big Nerd Ranch might be mad about that. We are hiring. We hire very rarely. We actually did just pick up a couple of new developers, which I'm very excited about, but we are still hiring a couple more. So if you're senior level React Native engineer located in the US or Canada, go to careers.infinite.red. All right, let's get into our topic for today.

Jamon Holmgren:

The topic is building an Expo app for mobile and web. And that was the title of a talk that Josh gave at React Atlanta, the meetup in December, I think it was, a few months ago anyway.

Josh Justice:

Yes.

Jamon Holmgren:

And you used Expo... What's interesting about this is not only that you built an app with Expo, obviously that's interesting, but also that you built it for mobile and web. And there were some learnings that came out of that, which are really interesting. You built an app called Surely. And the source code is available on your GitHub, and we'll link to that in the show notes here. But can you start off by explaining a bit about what was it that you built? What is Surely?

Josh Justice:

Yeah. Surely is a to-do list app. I've noticed over the years, different friends of mine, people have one type of utility app often that they're really a nerd about. I could care less about calendar apps, some people need a very specific calendar app. I could care less about email apps, some people really care. For me, it's to-dos I absolutely live out my to-do list app. And what I found was that the to-do list apps that I was using weren't quite fit for just what I wanted. I actually wanted less features. I had never read the getting things done books, but some people who have shared ideas from them talked about the idea that you don't want it to be easy to reschedule a bunch of to-dos. You don't want to be organizing to-dos, you want to be finishing them or deleting them. And so I wanted to build an app that really was targeted down just the needs that I had for to-do tracking.

Josh Justice:

And one of the nice things about just the high level of abstraction that Expo provides is I didn't need to do it as a business. I didn't need to try to make money on it. I could really make an app for myself very easily, pretty quickly, and then offer it for free because I don't need to make any money off of it. And so I'm happy to make that available, especially if there's anything interesting for folks about deploying for mobile and for web that they can glean from that source code.

Robin Heinze:

Oh, you really took the to-do list example app to the next level.

Josh Justice:

Yeah. That is the hilarious thing that it is the canonical example. And yet it's like, nope, I do really need it.

Jamon Holmgren:

The world needs another to-do list app.

Mazen Chami:

So when we're trying to decide what topic to talk about and I came across this video of yours, Josh, it was actually the time when I was evaluating other to-do list apps because I am a to-do list fanatic. If you were to come to our house, you'll see a to-do list in every room on every piece of paper on every board. And over the years, we've had four or five apps that have just to-do lists all over the place. And I actually tried Surely and Surely was really good because it was just simple to the point in that it was just really easy to follow. Most to-do apps are just convoluted. There's too many steps and hoops to jump through when all you need is just a list to get through and move on to the next thing kind of thing.

Josh Justice:

Means a lot that a to-do list nerd would overlap that way. And other to-do list nerds, they might want something slightly different and that's okay as well. I mean, that's another thing about... I've been thinking about this idea of personal software, creating software for yourself. And when you work in our industry and if and when you have the free time and interest in it, we have that opportunity. And because I can make an app that's really targeted at my use case and I don't need to go broader and broader for a feature set that appeals to everybody, I can reach a point where it's done. I would say that Surely is feature complete. And if Mazen or others have ideas of requests or peers they want to put in, that's fine as well. But it's really great to be at a point where it's like I don't have this big backlog that I feel like I always have more to do on it.

Robin Heinze:

Yeah, that's awesome. And it's nice that Expo makes it so easy to build something just on your own for yourself.

Josh Justice:

For sure.

Jamon Holmgren:

So could you describe the stack you used? Because that's obviously one of the more interesting things to our audience here. What did you use to build it?

Robin Heinze:

Obviously Expo.

Josh Justice:

Yes, obviously Expo, although that was part of the evaluation. I was trying to think, and actually this is a rewrite of the front end from another JavaScript technology. But the reason I ended up with React Native and Expo is this. I found that I needed the web case because on a desktop computer, I needed to pull up the to-dos on there. And I was using it on the web on my phone, but I found that I'm in there so much. I really just live out of my to-do list app that the niceties, the experience of a mobile app really was going to add a lot of benefit to me. And so that's what got me interested in looking into React Native for Web. So that's the general library that allows you to write React Native code and deploy it to the web environment. I wanted to see how it was doing. It's been around for a few years now. And then I saw that Expo was actually the recommended way that they have.

Josh Justice:

If you don't have an existing app and you want to build with React Native for Web, Expo is the recommended way to do it and gave it a try. It ran really well. So other things in the stack, I really wanted to go for a high level of abstraction. I'm not a designer. I have made the worst design sense and so I really wanted to use a component library and I've heard great things about React Native Paper. And they said they had great web support and it's absolutely worked out well that way. React Navigation, pretty much the standard, has worked out great, worked out great on web as well, including handling URLs. So as you navigate around on the web, the URL changes. If you reload the page or copy and paste the link and you're logged into your to-do account, those will come up just fine.

Josh Justice:

There was some few tricks there. Just figuring out exactly how to do the configuration, but it worked really well. And as a Expo app, all the normal data layer options you would want were available. I've ended up going with A REST API using a JS API format, but in Expo for web, GraphQL would work just as well or any other kind of data layer you might want.

Mazen Chami:

You mentioned React Native Paper. Did you evaluate others? And if not, when choosing React Native Paper, you went with it I'm guessing because you had mentioned, it was really easy to plug in with React Navigation. Now, did you have to do any specific customization to it?

Josh Justice:

So over the years on personal and professional React Native projects, React Native Paper and React Native Elements were two that have been around and really well established for a long time. And so I've looked at those over the years. React Native Paper was really appealing to me because of just how comprehensive Google's Material Design system is. And I actually saw with React Navigation that there was documentation on how to integrate that with React Native Paper so that you're using the elements from React Native Paper that work well with the look and feel, and it just feels very natural together. And that works really great. So I think I've been leaning towards Material Design across different frameworks and apps that I use, because it's so popular that there's a Material Design library for everything and it just plain CSS if you need it. And so that's just some of the factors that led me towards React Native Paper, but elements or other libraries might work just as well for deploying to the web and mobile. But this high level of abstraction was the perfect fit for my use case.

Mazen Chami:

I have heard Google is either revamping or changing up Material Design. So there's some new things coming to Material Design. I forget, I think they're trying to line it better with some iOS related items. So there's some convergence happening there between Android and iOS. So when you went with React Native Paper, did you have to do anything really custom or is it very easy to just essentially pull it out of the box and use it that way? Use it as is and maybe add in your styling or theming.

Josh Justice:

Almost everything I needed was available out of the box with React Native Paper. There were some places that I used bare React Native Views for layout flex box. And there's a few cases where there was something else that I needed where I found a third party component. There's a date picker that I use, a React Native date picker, or I built my own out of paper pieces. For example, I wanted a dropdown and a real literal dropdown was going to be a really good fit. And so I used a React Native Paper button and a menu together and that worked really well.

Jamon Holmgren:

Awesome.

Robin Heinze:

How often did you have to just straight up build something from scratch? Not even using React Native Paper components, if ever. Did you even have to do that?

Josh Justice:

Just about the only thing I had to build from scratch was just setting up responsive design layout of things. When I think about the style sheet stuff that I used, it was all about layout. Even things as simple as text and titles, React Native Paper has elements there that are styled with the fonts and the sizes that align with Material Design. So it is a funny contrast actually, because at the same time I was working on a professional project that was based on Material Design, the designer we work with was designing off of Material Design, we started out with React Native Paper, but it turns out we weren't able to use very much of it at all.

Josh Justice:

By the time we took that library out, it was literally just the divider, which is a one pixel line just because... I mean, it was adhering to the spec as far as I could tell, drop shadows, elevations and everything like that, but they were just going for the tappable things. Buttons was just not quite like the high level of abstraction that React Native Paper provides. But for me, as not a designer who wants out of the box components just to drop in, for that personal project, it works great. And I definitely recommend it for projects where you don't have a designer. You just want it to look and work well together.

Robin Heinze:

We have had pretty much an identical experience where we were trying to use, it wasn't React Native Paper, it was UI Kitten, but trying to use a UI component library like that, but also with a design team. And they kept designing things that were just different enough that you couldn't make the-

Mazen Chami:

Not our design team [crosstalk 00:19:34]-

Robin Heinze:

Right. No, sorry. It wasn't our design team, it was our client's design team. But it was just different enough that we couldn't really force the component library components to work. And so we didn't end up using it as much as we could have, but those libraries are absolutely fantastic when you're trying to do it all and you just need stuff that's already designed and works well.

Mazen Chami:

In the video, you mentioned that you didn't release this for Android because you ran into a dependency bug. So this is actually a very good example of when some platforms might not work well with specific React Native libraries. We might think some of them are just pure JavaScript, but it sounds like this one might not have been. Can you go into what that was, what the dependency was?

Josh Justice:

Yeah. It comes out of taking this approach of trying to assemble these high level things together. There can be cases where there's a mismatch. In this case, the React Native Paper dates library. It gives me full screen date picker, calendars, all the complexity like that. Works really, really great. It's made to look great with React Native Paper, even down to dark mode and everything like that. Handles it perfectly. But it intentionally says in there, hey, we use the dates date.intl APIs. They're available on iOS. They're available on Android in React Native 66 with Hermes. And Expo as of today is still on 64. And so there were some workarounds with some polyfills and I could have looked into those or tried to get those working, but it was at the point where it's like, I am going to be using this on iOS and on the web, not directly on Android. I'm not marketing this. I don't have users banging down my door. My contact info is there. So if any of y'all are Surely users, please let me know.

Robin Heinze:

Poll requests are open.

Josh Justice:

Yeah. Yeah. And so it was like, oh I could always pull this in anytime, try these polyfills. I did a quick try to see, oh, maybe I don't need to use that library for the dates, maybe some other kind of date picker. So I gave it a quick try with a different one and it was looking complex and it was enough where it's like, hey, you know what? We're very close. We could get there, but it's just not something that I want to prioritize right now. So for a professional project, it would not present an obstacle. You could get it configured or you could take another approach to dates. I mean, if you are working with this high level components, you're going to probably want to be flexible and say, okay, yep, the date picker is going to look different on Android because we need to be on Expo.

Josh Justice:

You choose what you're going to pick. Do we want to have an off the shelf date picker? Or do we want to have Expo and all the high level niceties that it provides? Or do we want to not be on Android? And depending on your business, your side project, you're going to choose a different option amongst those. But other than that, as I've walked through it, running on the emulator, I was developing just about the whole time on the Android emulator, running it side by side with the web browser and with iOS, seeing things working. And that was the only thing that I found that came up with Android. Everything else was working perfectly for all those libraries together.

Robin Heinze:

It's a pretty magical experience when you can just change a line of code and see it update on three platforms.

Josh Justice:

Absolutely.

Robin Heinze:

I want to talk a bit about what's under the hood that makes all of this work. So Expo Web uses React Native Web, is that correct?

Josh Justice:

Right. Yeah. The name of the MPM dependency is React Native Web with dashes. On the title on their page they say React Native for Web, which makes it even harder for me to talk about [crosstalk 00:22:55] would be clear as I can.

Robin Heinze:

I know how it is hard to talk about. It's also hard to google.

Mazen Chami:

Yeah, no kidding.

Robin Heinze:

So React Native Paper also supports React Native Web. Is that how their components work for both platforms?

Josh Justice:

Right. Yeah. They officially support Web and I haven't pulled up to see exactly how they do describe it. But basically if you have a React Native for Web and you're using React Native Paper in it, then those components just work. Running in development mode or building out the web assets, those React Native Paper components will look well and be styled properly in a browser.

Robin Heinze:

We've talked about React Native Web on the show before, but for our listeners who might not know, can you just really briefly explain the concept behind React Native Web and how it works?

Josh Justice:

Absolutely. I struggled with that for a long time, but I think I've got it quick and the listeners can decide if they agree or not. So when you think about React, you're building components and you're writing the actual HTML tags, the DOM elements in JSX, Div, anchor, whatever. React Native, we're deploying to mobile, which is different, but also we're not putting in tags for exactly what is happening on iOS or on Android. If you've ever done native development, see the names of those UI elements on there. There's an abstraction. And so React Native's View and React Native's Text and those other things are an abstraction over those lower level implementations.

Josh Justice:

And so what React Native for Web does is it makes the Web another abstraction you could target with the same things. So your app built with React Native Texts and Views and Flat Lists or other components built on top of them deploys out and turns into DOM elements under the hood, just like it turns into Android specific UI elements or iOS specific UI elements. So it's an additional level of abstraction away from what's really happening in the web browser to put it on parallel with exactly what's already happening on iOS and on Android and on many other platforms that React Native has been applied to. So that one step away from the HTML is probably the simplest way to think about how React Native for Web works.

Robin Heinze:

Yeah. That's a great explanation. That's my understanding as well, but we're taking the abstraction that React Native gives you and just applying it to one more place, which is, I mean, that's what React Native is all about once run anywhere.

Jamon Holmgren:

Exactly. I've joked about this before on the podcast, but React Native Web is what React JS should have been, where you have that layer of abstraction and then you hit the platforms rather than putting divs and spans and platform-specific elements right into framework itself.

Robin Heinze:

It's almost a shame they happened in the order that they did. Because if React Native had come first-

Jamon Holmgren:

I don't actually feel like maybe React Native Web would've made it though. React JS Web made sense because people are like, "Well, you just write HTML in it."

Robin Heinze:

Even though it's not HTML.

Jamon Holmgren:

Not HTML.

Mazen Chami:

So ane question, and I think you highlighted it in the video, React Native Web is not very accessible. And I think you mentioned when translating it to web components, it usually just does a div with a role. So those of us that know accessibility, that's something that's very important. And having a div with a role of button, or we know we would be looking for an anchor tag to help us know that this is a link, accessibility won't necessarily work that great using this translation. What can a user do to help work with the same stack to make their development experience easy and simple to deliver the product, but also make it accessible for all users out there?

Josh Justice:

Yeah. Thanks for going there. Amazing. When Jamon was talking about the upsides of Reactive Native for Web, that's the main trade off that I had in mind that I wanted to get to. And it is important for listeners to keep in mind, I've worked on React Native for Web at a hobby. And so that's the amount of effort that I put into it. In a professional context, there may be workarounds. There may be ways to make all that work to get just the right HTML elements you want and would love to have some future guests fill us in more about that or blog about it. That would be great to hear. But out of the box in the basic and the most straightforward use case where you're using those abstractions from React Native View, Text, et cetera, you are going to get DOM elements that are maybe not what you expect.

Josh Justice:

Another example would be if you want to use those HTML 5 sections like header and footer and main and nav, which I never really used until I started getting into accessibility tooling and it was explaining to me and pointing me to those WCAG points about how those sections helped screen readers and others, that's when I learned about those things and have been trying to apply those, and yet those don't automatically come out of the box with React Native for Web. And it wasn't clear to me upon initially looking how to get them in there. Even if there is a way, it's still not going to be the default in the same way as when you're writing DOM related, HTML tag related JSX. And so this is an interesting distinction.

Josh Justice:

On the flip side on the accessibility, one thing that does work great in Surely based on all these libraries is screen reader labels. So I've actually been experiencing some risk strain for the last few years. And one of the things that I've been reaching for is a macOS and iOS feature called Voice Control. It uses the accessibility labels on elements. Kind of the opposite of a screen reader, it lets me speak what I want to tap on that I see using that accessibility label, and then it interacts with it. And that actually works great with React Native Web and even React Native Paper. I've been able to do that. I made a poll request to that React Native Paper dates to make a small tweak, to make that work out well. And happy to be someone who represents, hey, I have a use case for accessibility labels, let's make this different. And then folks that use screen readers are going to benefit from that as well.

Josh Justice:

So that side of accessibility does work really well, but if you are on the web and you really want to make sure you're in compliance as possible, some things might not be achievable. Some things might be a poll request to React Native for Web and you need to get down into the guts to it. I know one particular thing, I was surprised to see that Pressables in React Native are divs with a role of button. It's like, well, we got button tags. Why can't we use a button tag? Well, I found the GitHub issue, where they track that in a certain browser, in certain scenarios, there's display issues with buttons and limitations of what could be displayed in them. And so now, hey, you're writing the HTML yourself, use a button unless you have that edge case, but for an abstraction like this, they have to code something that's not get a break in those cases.

Robin Heinze:

So that's one of those things about the web is that it represents itself as a single platform, but it's really not because each browser is its own platform.

Mazen Chami:

What do you mean? You don't use IE?

Robin Heinze:

No. I enjoy my life.

Josh Justice:

Going back. Big picture to how this relates to preferring React Native for Web. I feel like really talking to people about whether you should reach for this architecture, the main question that comes to mind for me that I ask them is, do you want the same app on web, on mobile? Or is it a different app for the same business or service? If all the screens are the same, if all the features are the same, I mean, there's going to be responsive design for tablets as well as for web browsers, but if all the functionality generally 90% or more is the same, great. As a contrast, the client project I was on recently, they had a preexisting React Web app and they were building a React Native app. And it was the same service, same needs and uses, but intentionally, I mean, the layout was different, different screens. They were okay with the fact that some features were on one and not on the other.

Josh Justice:

And so if there's going to be a lot of differences or maybe it's different audiences, the mobile app is for your customers and the web app is for your customer support reps, where there's going to be a lot of differences there and not a lot of shared screens and UI elements, the cost of that layer of abstraction is going to get in your way. And so if they're fairly different, anyway, I think probably building a separate React Native app, even an Expo app and a React Web app can still be a benefit. I mean, it's so easy to hire for React for Web. There's so many folks that are directly experienced with it and are going to be able to target web browser, DOM element stuff directly. And there's still options for code sharing like shared libraries for your data layer for your JavaScript layer.

Jamon Holmgren:

Yeah. Yeah. That makes sense to me. And this is a lot of times people will say, should I use React Native Web? And it's very much it depends situation. We have been in situations though where... Robin actually worked on a project where we did share components, but we didn't share necessarily the [crosstalk 00:31:24]-

Robin Heinze:

Right. It wasn't the same application. It was two applications that used a lot of shared components and code, and that was made possible by React Native Web because we were building React Native components that we could then use on the web.

Jamon Holmgren:

We'd literally sprinkle them in as needed.

Robin Heinze:

Right, but they were really, at their core two separate applications with different screens and different layouts.

Jamon Holmgren:

And we could of course share a lot of the business logic and things like that, which was helpful, data modeling and backend communication and that sort of thing. But you're not going to get away from that unless you're literally building the same app in web and iOS and Android. It's interesting, one of the things that came to mind as you were talking about this, Josh was what if Android was not very similar to iOS or vice versa, however you want to look at it, what if they weren't just totally competing platforms and instead most people had this alternate universe, most people had an Android tablet that was usually landscape and an iPhone, the iPad had never been invented or something and instead of targeting iOS and Android phones in a portrait setup here, you had to do iOS there and Android is a tablet and then you had web, which was different as well.

Jamon Holmgren:

That illustrates that we take for granted that an iPhone, the audience can't see this, but I have an iPhone and an Android in my hand, both of them, and they look similar. If I were to just swipe it through the screen, you'd be like, okay, "Which one was which?" Because at first glance, they're similar, but it's an interesting thought experiment. What would happen there?

Robin Heinze:

I've never actually thought about that before. I will say thank you to Google and Apple for competing with each other because it makes my job easier.

Jamon Holmgren:

And stealing ideas from each other and all that. It does make our lives easier.

Mazen Chami:

So I think as we're talking about how similar or not so similar in some pitfalls with accessibility, you highlight React Native's platform API, and how that is the platform.os which returns iOS Android Web and I think it was macOS and Windows or something like that. And I think you actually use it very well with the storage setup using acing storage versus local storage. People can watch the video and hear the asterisks about that comment. Is there anything you want to highlight about how the platform API makes it either easy or actually probably harder to develop using this single repo for web and mobile?

Josh Justice:

Yeah. For my case, the platform API works really well because my app is so far on the extreme towards it is the same app on iOS, Android, and Web. And so there's very few conditionals in there. The Web has a link to the App Store button, we don't need the App Store button in the iOS app. Some APIs that are available on, I think on iOS, we can pop up the App Store review whereas on the Web, we just link you somewhere to put in a review. And then you mentioned the storage setup, where Expo storage provides mobile options, not for the Web. So I wrapped it and figured out an option for storage on the Web. So yeah, just with just a few conditionals for that, it worked out really well.

Josh Justice:

It's another thing to think about though, as far as evaluating your app, the more platform checks you have to make things very different on the Web, the more you want to think about it. And I love the architecture that Robin mentioned. That's a nice, best of both worlds that I haven't run across before. And it seems really great, but you just want to think about, is there very few differences or are there going to be half and half? Is it mostly differences on all the different platforms? At a certain point, if there's conditional spread all throughout your app, at some point maybe you have different screens at the outer level rather than conditionals. But yeah, my app was so far towards the extreme that those very few platform conditionals worked out really well.

Robin Heinze:

Yeah. It sounds like if you want that level of sharing for them to basically be the same app, you have to intentionally design it that way from scratch, which is what you got to do because you built it from scratch.

Josh Justice:

Yeah. I'm glad you said that Robin, because that makes me think about client project that I was on recently, we had separate design made for iOS and for Android. And so the designers were coming in with slightly different visions that match those different platforms. And so that could proliferate into conditionals around the size of margins and things like that. And that could go all over the place. And I'm sure there are conditionals inside of React Native Paper that are handling some of those differences as well to get things to look up just right, whether they need to show identically on the two platforms and on the web or they're supposed to look differently.

Mazen Chami:

I've worked on a project before. Very similar to that where my component was just a conditional platform OS is iOS return this component.

Robin Heinze:

Otherwise, render this one.

Mazen Chami:

Exactly. And the sole reason was the styling and the look and feel that it didn't make sense to have that platform.os throughout a one component when instead two components were just smaller files, easier to maintain.

Robin Heinze:

Yeah. Well, it's funny because, I mean, since React Native came on the scene, that's one of the biggest criticisms of it, is that Android and iOS are different and you should be developing different applications for each of those. But I think as it's been around longer, people are starting to value the efficiency of building for both at the same time over whatever different UX traditions there are for these two [inaudible 00:37:17]. Those traditions start to seem a little bit more arbitrary when you could say, well, why would you make them different if you could make them the same?

Mazen Chami:

So one topic I want to talk about, and mainly because I attended your testing workshop is based around testing. I see you integrated a lot of tests in your app. And I love when the video, you ran a test and you just see everything flying through the screen and passing. That's such a good feeling. Can you just talk about what you used for testing? I know you mentioned Cypress, I believe it was for your end to end testing. And I remember from the workshop, there was stuff like Detox and Appian or other resources out there. So do you mind just talking about testing in general for this experience with a web and mobile app?

Josh Justice:

Love to talk about testing. It's one of my favorite things to talk about. So in general, I love to have tests at different levels of abstraction. So low level unit tests, if you just have standalone functions with logic, test those. Testing components that higher or lower levels of granularity and then end to end tests. So on React Native, Detox is a great option for end to end testing. It actually doesn't officially support Expo as of the last time I checked. And so I've leaned away from it for Expo projects. And even on React Native CLI projects, I was having more and more trouble over the time for my little side projects and personal training stuff, getting the build set up working. Getting things to build through iOS and Android is complicated. It's hard when you're using the CLI and at those native layers. So I don't begrudge them that, but that was challenging.

Josh Justice:

But it clicked for me, because I have the same app going to mobile and to web, and Cypress works great for end to end testing on the web, I could test this with Cypress and that gives me a high level of confidence for things that do work the same across the platforms. So if all those tools are working well, then if the Cypress tests pass on the web, I have a pretty high degree of confidence that things work on mobile as well. Now, one of the biggest things I use these tests for, because Surely is now feature complete, is to cover dependency updates. When Dependabot opens a PR for a new dependency update and for something like load dash or date functions, test pass, I click accept. For something that's updating React Navigation, no, I want to run that locally to see it working because I want to see it actually work on iOS as well because there's native code going on there that Cypress isn't going to be exercising.

Josh Justice:

Interestingly, just in the last month or so, a Cypress update started erroring out for me and I was digging into what was going on here. So if we would've done this a month ago, I would've been like, "Cypress React Native for web testing. Perfect. Go for it." I got a little dose of reality. What was going on to the degree I could figure it out is Cypress is checking some things about the way the navigation works in the browser and React Navigation running on web is doing some things about the navigation of the browser that work fine for end users, but conflicts with what Cypress is looking for. But on both sides, it's not obviously googling the error, neither of them it's not clear to me what's going on. So in a sense, there's implementation details onto the hood of those two that are conflicting.

Josh Justice:

And so I decided that I could work through it if I really wanted to put a lot of effort into it, but I decided I think I'm going to scale back to React Native Testing Library, which is the component testing library for React Native. Because I realize, and this is a technique from that client project as well, we wanted to use React Native Testing Library to test each screen by itself because React Navigation, there's native code involved and stuff like that. But if you take one of your screens that React Navigation renders for you, all underneath there that's all React Native code you control and you could step out the native stuff like usual.

Josh Justice:

So I've been taking my screens one at a time, starting with the ones that were erroring out and converting them over. So now instead of confirming that I've successfully navigated to another page with this URL, I step out React Navigation, I confirm that the right link to, or the right navigate function is called past the right arguments. So now whenever you think about testing styles like this, you think about what are you gaining? What are you're losing? I'm gaining in that I'm not coupled to those implementation details of React Navigation and Cypress anymore. What I'm losing is a bit of realism. I don't know that when I make that call to React Navigation, I know React Navigation works well, but have I set it up such a way that that's going to succeed on web and on mobile and that I'm using the same string name for the route that it's actually configured as.

Josh Justice:

So I'm a bit more reliant on manual testing. And because my app is small, it's like yeah, I'm going to go through the screens, that's going to be fine. For a professional environment, even if you are using Cypress for a lot of your screens or React Native Testing Library for a lot of your screens, I'd recommend automating one Detox or one Appian test or a few just as a smoke test, just to confirm that the iOS, the Android can build, basic screens come up, maybe one very important flow. So you can get a lot of complimentary help by getting assurance from just having one or a few Appian test passing, but more Cypress tests and even more than that React Native tests in library and lower level tests.

Jamon Holmgren:

That's awesome. Thanks for that explanation. Perfect. Well, we are, unfortunately out of time, Josh, I would love to chat more about this, but in the meantime, people can go check out your talk, which we will link to. And it's fantastic. I highly recommend watching it. Even if you've listened to this episode, I think it's good to watch the talk. It's on YouTube. You can go check out Surely, surelytodo.com. And also there is GitHub source, which we'll link to. Josh, in your bio you say you do live streaming. Where do you do that?

Josh Justice:

Yeah, I live stream on Twitch. And so I'll give you the link for this new Twitch series that I've got starting up, but folks can also go to codingitwrong.com is my main homepage and you can hear about anything that I'm working on on there. But I've been off and on in Twitch streaming, but yeah, starting a Twitch series to convert another app over to Expo with React Native for Web. So if anyone's interested in this, it's great to follow along step by step and see me putting it into place. I would be happy to have anyone join.

Robin Heinze:

You guys need to collaborate.

Jamon Holmgren:

I was thinking the same thing. I've been Twitch streaming as well @rn.live that just because my Twitch stream. And we need to do a collab, Josh. It'd be a lot of fun. The world needs more React Native content, especially if you're doing any of that React Native stuff, I'd love to have you on or go on yours.

Josh Justice:

Absolutely.

Jamon Holmgren:

We are at the end of the program, unfortunately. Where can people find you, Robin, online?

Robin Heinze:

I'm on Twitter @Robin_Heinze, with an E at the end.

Jamon Holmgren:

Mazen?

Mazen Chami:

Mazen Chami.

Jamon Holmgren:

And I'm @JamonHolmgren. Josh, I don't think you're using Twitter anymore. You decided to take a break from it, right?

Josh Justice:

Yeah. I was heavy on Twitter and then I was off Twitter. So codingitwrong.com.

Robin Heinze:

I don't blame you.

Josh Justice:

Yeah.

Jamon Holmgren:

I don't blame you and also we're all worse off for not having you on there, but I get it, I totally get it. But certainly codingitwrong.com is a good place to find you. You can find React Native Radio @ReactNativeRdio. You can also join our community, community.infinite.red. We have over 2000 React Native developers in there. It's very active. People ask questions and answer questions in there. It's fantastic. Thanks Josh for coming on. As always, thanks to our producer and editor, Todd Werth, our assistant editor and episode release coordinator, Jed Bartausky, our social media coordinator, Missy Warren, our designer, Justin Huskey, and our guest coordinator, Derek Greenberg.

Jamon Holmgren:

Thanks to our sponsor, Infinite Red. Check us out at infinite.red/reactnative. Special thanks to obviously all of you for listening today. We all really appreciate it. We also appreciate it when you hit us up on Twitter. It's been happening more often lately where people are like, "Hey, I love React Native Radio." And it's always really nice to see that we're not shouting into the void, which sometimes it feels like, that you're all hanging out with us and we can feel your presence now. So really appreciate it. Reminder, we are hiring React Native engineers. If you're senior level React Native engineer located in the US or Canada and you want to work for, plug your ears, Josh, the best React Native agency in the world, go to careers.infinite.red. We'll see all next time.