Good morning everybody, I hope you had coffee before you got here because the coffee thing isn't quite ready yet, but it should be ready soon, hopefully before morning tea break. My name is Tink and I'll be floating around today on stage doing stuff in the hall along with the rest of my team, Noor, Todd, and we'll see Harshal later today. There are boffs you'll see me around asking you to come upstairs for the boffs. I want to remind you that there is no food or drink allowed in the hall, so please eat your food or drink in the food court. The food court takes tokens and pay T.M. but not cash, so put your cash away and get your pay T.M. out if you want to buy extra food today. And oh, do you all have the Wi-Fi password? Okay, good, because it should be written out there a million times. And if you did forget it, it's in the inside of your tag, along with some other kind and gentle rules about conduct and feedback, oh, feedback, Zainab, do we have feedback forms today? I might sing you a feedback song tonight. And please don't drop trash where it doesn't belong. The morning announcements, I'd like to start the conference by bringing Zainab to the stage to introduce the conference. Thank you, Tink. And welcome, everybody, to React Fu. I suppose it's a Saturday morning and our favorite souvenir in Bangalore is called traffic, so I suppose people will be taking their own time to come here. I'm Zainab Bawa. I run Hasgeek and you will see a lot of us from Hasgeek and the team today, the crew and volunteers. Many of us are wearing the yellow-colored Hasgeek lanyard. If you would like to know more about Hasgeek, please go look us up, ask us at the help desk. We're also running a kiosk here called Hasjob. It's a bit of an echo here. Anyway, there's a kiosk that we're running called the Hasjob kiosk. You will find me hanging around over there. Please do feel free to share your feedback about the conference at any time with us at the help desk. Or if you have any questions or concerns, please look out for some of us wearing this yellow tag over here. I'd just like to introduce the conference, but rather I'd actually like to call React Fu more of a community right now. We launched React Fu in 2017 and the idea of launching React Fu at that time was that there's this new framework that allows you to suddenly do UI engineering in a way that one could just never imagine. And React has taken off not just worldwide, but in India as well, there has been quite an uptake of React. We launched the conference in 2017 in September and have been running various editions of the conference in Pune, in Hyderabad, in Bombay, in Delhi and now back again in Bangalore. And I was just noting this morning that in the last one and a half years, including today's conference, we've had a turnout of over 1,125 participants. So I'd really like to thank the community for showing up and for the kind of interest that has been there in React. What has also happened in the process of running React Fu between 2017 and right now is we've seen a bunch of interesting trends and I would encourage you to take note of this and do the same. We've had participants in various editions who've then gone on to become speakers not only at React Fu but also at GS Fu. So if you're interested in speaking, check hasgeek.com and apply for CFPs. We've had speakers from the conference who've become reviewers and they've also become co-producers of conferences in the sense of helping program. And I'd especially like to thank a bunch of people including Priti Badwani, Ankita Goyal, Kiran Aburi, Aziz Khambati, Ritesh Kumar, Ankith Muchada, Vinci Rufus, Jagdish Kasi, Rahul Raut, some of whom you will see here today and some of who you probably see at other editions of the conference. We've also had our sponsors who've become our collaborators in the past few years of running this series. We especially would like to thank Hasura for their contribution, not only in terms of sponsoring the conference but also in terms of contributing to the content and helping us grow the community.  Mintra and many among others. And this is the cycle that actually makes, react for more than a conference, it makes it a community. There is obviously, the community is not perfect. We still have very few participation from women, from persons of non-binary gender and we would encourage you, especially the women in the audience today, that if you had a good experience at this conference, do come up to speak, do tell your colleagues and your friends, because we'd like to see more and more diversity at our conferences. Last but not the least, talks will be held in the auditorium today from morning to evening. We have a Birds of Feather session track that starts after Parshuram's keynote today. We'll have volunteers and ushers and as Sting mentioned, herself and Pranav will be there to help you. And then we have another track of Birds of Feather sessions, which we'll start in the afternoon post-lunch. If you are new to the Birds of Feather sessions, I would encourage you to join one and be part of the conversation. It is really a lot of fun and the resource person and facilitators really know what they're doing. Finally, actually there's not much to say. I think the conference is just about ready to start and I've taken less time. So we hope you start the conference and in the conference on time. And again, if you have questions, if you have suggestions, if you have concerns, please look us up at the help desk or look for people wearing the yellow tag and just catch us and ask us. Thank you. Have a good conference. Before we get started, I want to give you guys an opportunity to be part of the conference. We'll have flash talks today from 305 to 325. That means four talks of five minutes each. If you're interested in giving a flash talk and you're not planning to try to hire someone, but want to talk about an interesting project you're working on, something in open source, a new tool you're developing, or perhaps the hardships of being a react developer, please do write down your talk on a slip of paper, hand it to me or Noor or Todd or anybody who looks like they're in charge and we will get you on the schedule. Flash talks are a lot of fun. You get to be up here with the microphone and all. So please do consider participating in that. Also, I want to remind you that if anybody is wearing a red lanyard, it means that they do not want to be photographed. So please do not share on social media anybody who's wearing a red lanyard. We do have a hashtag, which is of course React Foo. So if you're sharing things on Instagram or Facebook or wherever you're sharing today, please do use the hashtag. And that's kind of it, I guess. Siddharth, are you ready? All right, we're going to start, like, I think, two minutes early today. I hope nobody's waiting out there in the hall. Hey, people in the hall, if you want to hear the talk, now's your chance. You got here early. Don't miss out. So our first talk this morning is by Siddharth, who's spoken at Congress's people. Am I back on? I'm back on. All right. While he's now quietly getting his mic on, Siddharth is a super high-energy speaker, which is why he needs that mic that won't fall off of him. He's going to be talking today about writing good components in React. Components are everything.  You ready, Sid? All right, cool. All right, thanks for the introduction. Just to be clear, the computerized voice is not this. It's going to come from the mic. It's super good to be early. I didn't actually expect so many people to wake up early and come, so thanks for being here early. That's amazing. I'm going to talk about good components. Let me just put a timer on. All right. So first of all, let me introduce myself. I'm Siddharth because you can never spell Siddharth in one single way, so I just go by Sid. I'm an independent developer. I don't know what that means because my past job at Auth0 was yesterday, so I'm independent from today, and it's a weekend, so that's awesome. So yeah, I'm figuring what that means. If you have tips on what that means, reach out to me, please. You can follow me on Twitter or you can find out more about me on this website. Cool, let's talk about the good component, right? Or as I guess now we're supposed to call it, the Sadharan component or the Adarsh component, I don't know, translation project is on its way. So at the core of using React is writing components, right? I remember when React came out, there was a lot of buzz that this is the new fast framework, right? This is the performance framework.  How is it fast and all of that? And the whole story was around how the DOM reconciliation and manipulation is super smart. But then the community kind of got over that point and let's be honest, most of us don't really need performance applications every day, but what kind of stuck around was this idea of thinking about your UI in terms of small components that get together and make big components. So we kind of started blocking them down, which was really the biggest takeaway and it was kind of the coolest thing that happened. So I've spent a lot of time thinking about what is a good component? How do you write a good component? And I came up with this bunch of tips that kind of encapsulate the concept. And I'm gonna get into those tips, but there is this theory that I have, which is if you're writing good components, you don't need a lot of libraries, like you probably don't need a state management library, you don't need like a fancy state tree and all of those things. Translation is gonna be easier, composition is gonna be easier. So the key idea is that if you write good components, your app will scale till a longer point until it basically gets out of hand and then you want to bring in external libraries. So that's this talk. So let's start with the first example. I have this simple button, right? You can't really see, but it's like a gray button. It's like the, what do you say, the slightest of grays that the designer could do in Sketch. So that's what this is, as design usually goes. And as it goes with buttons, you usually end up with a bunch of them, right? You have a normal default button, you have a primary button, you have a destructive button or a danger button and this is how I like to call them in React, right? You say button and then you say, give it the primary prop and it will be blue and stuff. So if you would take out the prop tables for this, this is what it would look like. You have a primary destructive and then there's like a bunch more secondary link. I think in Cosmos, the design system I was building until now we had like six variants of buttons and that's just how buttons are usually. And then like, this is the first time that somebody asked this question that what would happen if I did a primary destructive, right? Like which one wins or do they merge and what, right? And my first response was why would anyone do that, right?  And that was kind of my very developer response to it. No, it's the fault is in the user, not in the code. But since then I've kind of come around to the concept that we even put up a warning. So we had a prop type validation where you did something like this and it gave you a warning on the console saying you can't use primary and destructive at the same time. Make up your mind, like pick one. And I was very proud of that, like custom prop type validation and it's awesome. But since then I've kind of come around that a good component should not have conflicting props. The whole idea with writing components and like creating an API or writing props is that you want the developer who uses this, right? I'm going to say user where, I mean the user of the component, right? So your fellow developers basically. The component user should not have to think about what will happen when something like this happens, right? The API should be more obvious. The API should promote the user to kind of get into a pit of success, right? It's the orbit of pit of failure where you basically write code and you don't make mistakes, right? The API helps you do the right thing, right? How many of you use TypeScript? Whoa, so many of you. Yeah, I don't use TypeScript. But this is what the TypeScript fans have told me, that because of all the IDE integration and because of all the knowledge that you get in the compiler, you kind of, it's very hard to make mistakes with TypeScript. Like the compiler is kind of your payer programmer vouching for you, helping you out. So creating a good API is kind of the same thing, that you're helping people do the right thing more often than doing the wrong thing, right? So that's tip or advice, whatever you call it. Number one, which is a good component does not have conflicting props. So instead of doing something like this, let's just call it appearance, right? And you can call it multiple things. I've seen people call it type, which can get interesting because there is an HTML attribute also called type and then there's mixing. So I like appearance. Appearance is default primary destructive, like the whole list. All right, advice slash tip number two. So I have the switch component. It's fancy, I can click it and stuff. And then usually what you want is your user wants to attach an event handler, right? You say switch something and then the function should be called when this thing changes. So you can probably do something on click, right? That works. The problem I have with on click is that it kind of focuses only on the mouse user, right?  The most common scenario which I get into is I'm eating a sandwich with one hand and I can't use the mouse because the other hand is dirty. So I just tap, tap, tap, right? But then there are more genuine use cases like if you're using a voice reader, right? Then you can't really click. You're probably going to a tab. You're going to use the keyboard. Or if you're on a mobile device and you try dragging it, right? You're trying to drag it to the right. So on click kind of as an API forces you to only think about the click case, which is not actually true. So this is what I came up with. I was like, let's call it on toggle, right? Switch is going to toggle. So it's going to toggle between on and off. So let's put it on toggle, right? And I was really happy with this inclusive API that I built that it's toggle, right? Doesn't matter how you toggle, all of those are toggles. I'll have to zoom out here, right? So you can't see the whole thing with the idea is that internally you still map all of those things that the user interactions will have. So you say on click should call props.toggle. On key down, check what is the key down. If it's an enter or a space, you want to call toggle. If it's a drag and you drag it to the right, then it should call on toggle, right? So internally a good component should map all of the user behavior like the end user behavior. And I should say end user interactions like click and drag and map them to the API that a component user would use. Right, let's talk about this one. So this is like a text input. It's the most common input field, I guess. And then you have over here, we usually do on change, right? And we all kind of agree that on change is the thing to use, right? We kind of as a community coincided on the same prop name, majorly because HTML attributes also have an on change that come shipped with the browser, right? So it was easy to just capitalize one letter and bring it into the React ecosystem. And we kind of all agree this, but this is what happens when you put both of these components together, right? So I'm a developer, I'm trying to build a form and then I put a text input and I put an on change. And then I put a switch and I'm like, okay, what is the switch prop called? So I go to the documentation, documentation. I go to the prop types definition and I say, okay, what is this one called? And I say, okay, it's called on toggle. So then I come back and put an on toggle, right? So we have two components that make sense on their own, but they don't really make sense when put together. Like why are they basically have the same behavior, which is you want a function or a callback to fire when this changes, right? When the value changes. So why can't we call it the same thing? So which is where the tip two comes from, which is a good component gives names to behaviors, not interactions, right? So on change instead of on click on key down, all of that, right? You want the user of your component, your fellow developer to think about the functionality, not the interaction. The interaction is baked in the component itself. So give names to behavior, not interaction. Another way of saying this is the same behavior should have the same name across components. So good component does not only care about its own props, but also cares about the consistency of props across the code base. This concept is like, I first came across this concept in this talk by Sebastian Magboga, which is called minimal API surface area. You should search it, it's on YouTube, it's a great talk. His core idea was that you should limit the amount of API that a developer has to learn before they can be productive with your code base or your library, right? So if you're building a library and you ship it to people, they shouldn't spend the all day looking at documentation, right? Similarly, if you onboard a new developer into your team, you want to minimize the amount of time they can learn the entire code base and start being productive, right? So great talk, do check it out. Oh, by the way, this talk is from 2013, right? Which is super old, but six years later, everything is still super valid, it's amazing. So yeah, we basically just change on toggle to on change and yeah, consistency, awesome. Tip number three, I have this avatar and it has Simon's cat photo over there.  So we had this user avatar and we had a resource or application avatar.  So this is from GitHub. This is like a super big one and there's like a tiny one and this tiny one.  We have the same thing. So we put all of those out, right? User avatars come in multiple sizes. You put, we really like using T-shirt sizes for this because you can encode T-shirt sizes to pixel values and then you get a fixed set of things, right? You get an enum. So extra small, small, medium, large, extra large. We had like these five sizes, five sizes. And because the avatar component is the same, you kind of get the same thing for free for the application one. We don't really need five sizes for application, but it's free, so who's complaining? It's all right. All right, so we put both of them together and how you would typically use this is you won't really hard code the URL in your component. You probably get it from props or a user object. So you say props.useravatar or props application logo. And now with avatars, you kind of have to think about a lot of scenarios. What happens when the avatar is missing, right? The user has not uploaded a photo, right? Or we don't have a logo for the application yet. So you need like a missing one. So the missing one for the app, sorry, user avatar is the silhouette of like a face and stuff. But for the application, it's a vague application logo, which is just the company's logo. So you kind of have to make a decision if it's missing and the type is user, then use this one. If it's missing and the type is resource, then use this other image. So you kind of do a fork kind of a thing. With users, we can do better, right? You probably have the name of the user. So instead of showing the silhouette, we can show the initials. And this pattern was like made popular by Gravatar first, but then Gmail really picked it up and blew it up for everyone. So you can pass the initials, which will render over here. Sure, I'll go for it. All right, what's your name again? Summit, I'll remember Summit, okay. With the application avatar, you don't really want to show the initials, right? Showing FI or FB for Firebase doesn't really help. Instead, we want to show what type of application it is. So this one supports an icon. So you can show a database, right? And now you kind of see where this is going. You have this avatar component that has all of these props. It has image size type initials. And there are some unwritten rules over here that please don't use icon with type user or please don't use initials with type app, right? Or if you want an application avatar, don't make it circular and all of that. So there are like these unset rules over here. And there's this amazing word, which all credit goes to Jen Creighton. She calls it a prop collapse, right? It's a play on apocalypse, but with too many props. And the whole idea of this is a good component should follow the single responsibility principle. So this is a principle older than JavaScript, older than React. And the idea is that when you see a component trying to do too many things, and this is a React symptom, which is it just takes too many props. And there are like unset rules between how props combine with each other. This is a symptom. The problem or the cause is basically your prop is trying to be a hero. It's trying to do too many things. It might make sense to create two props out of them, right? So you create a user avatar, which just takes care of user single responsibility. And you keep a resource or application avatar, which is responsible for the application stuff. Another good thing happens here, which is like the prop is the same, basically. So you call it image. And instead of initials and icons, we can just call both of them fallback, right? What should be the fallback if data is missing? And the interesting thing that happens here is we kind of reach the same stage of tip number two, which is when you look at one component, say you're using user avatar, you know what the props are. Now when you have to write a resource avatar, you don't have to go back to the documentation or learn it again. If you know one, you know the other, because the props are the same. And that's really cool. So if you look at these two prop tables, they're basically the same, because they have the same props, right? The only complaint I still have with this is that the fallback prop for one of them takes a string which is initials, but the other takes a string which has to come from a set of icons that you already have, right? So there's like, it's not fully consistent, but it's way more consistent than the four. And of course, like if you're a developer, then you're already thinking, yeah, but it looks the same. I'll probably use the same abstraction underneath. So I'll use a base avatar and I'll try to hard-code some of the values. So for example, user avatar just returns a base avatar with hard-coded type. And the initials is just gonna map to fallback, right? So you get something like this. Same thing with resource avatar, where basically you just take the fallback, map it to the icon. And base avatar can again take both of them, which is smart, but then you can't really come up with that on day one, it's always safer to start with two and then find those patterns that come back. So Sandy met super big in the Ruby community. She gave this super scandalous talk which told like a thousand group of developer to do duplication over abstraction, right? And this is like core object-oriented developers. They went mad, they tore the table. Nothing, everything was fine. So her core idea was that no abstraction is way better than the wrong abstraction, right? You can always take this, these two, and create a common layer out of them. Doing the other way round is way, way, way more difficult. So you can start with duplication. Once you start looking at patterns, then you can create the abstractions you want. All right, we're running late, so quickly tip four. Yeah, I like this one. So you have a badge component, right? Badge components are everywhere. You see them on GitHub and other places.  So we did like appearance, information, blah, blah, blah. The good part is that we still use the appearance prop. So that's nice, but the values are different. So you do account, right? And then we had this label component, which took a text and put it there. Again, GitHub has the same, you have these private things, right? You have a private label over here. And luckily it also took an appearance and it had basically the same appearances. Now, when I put both of these together, right? Do you see something odd over here? Let me put it there. So can you tell me one good thing about this and one bad thing about this? Just shout it out. Is that the good part or the bad part? What's the good part? Awesome, yeah, so the really good part is that both of them have the same appearance prop. So if you've used one, you can predict how to use the other. The really good part is that all of these appearance are also called the same thing, right? So when you basically use them together, if you're using a danger or a destructive badge, you can say destructive label and you know they go together because somebody has taken the pain of keeping them the same names. The bad part is that they basically, both of them do the same thing, which is put text inside them. But the prop for doing that is called different, right? It's called count for a badge, which makes sense. Badges of count and text for label, which also makes sense on its own. But when you put them next to each other, it looks weird, right? It looks silly. So how about we call them content, right? Content is vague enough. It's like what content goes inside this, right? And I did this and then I like luckily five minutes later, I see this tweet by Brent Jackson, which is like don't reinvent props to our children, right? React already gives you a way of putting content inside of components, right? It's called children. It's a native property of React. So if you're defining props that take arbitrary inputs, like count and text, it's probably better to just use composition. And by composition, you mean just put it inside the thing, right? So that's tip number four. A good component is composable, right? So instead of doing something like this, just put it inside, right? So you say badge and the child is 12. Label the child as private. The good part that happens here, there are like multiple things that happens. But the lowest hanging, whatever thing happens here is that you don't have to learn what the badge calls its children because it's called react.children. You put it inside it, right? Once you immediately remove a prop, the minimal API surface becomes even smaller. And there are other really good things that you can do. For example, I have this alert, right? I have a type warning and then you can put a message. You can change the type and let me... This probably works or this works awesome. And then we kind of had a request that can we put an icon here, right? I want to put like a warning icon and I want to choose what icon. So if it's like a danger or a delete, maybe I want to put the delete icon or something. In this alert, I would probably have to go back, build it in, like accept an extra prop, put the positioning for it and then ship it back to the person who wants to use it. But if I actually accept children instead of this custom text and icon API, somebody can actually just put it inside, right? You say icon type, icon name is warning and the text inside it, right? So when you have an API like this, you don't have to ask someone else to bake this new feature in. You literally can use the icons that you have and put it inside it, right? Which makes alert more composable. You can change it, it's more flexible. The big nuance here, which like the first time I talked about this concept, a lot of people came back to me and said, what if we don't want this? So it's like, that's fair. If you want to have like design consistency where you say alerts cannot have icons. That's a rule we made up. Then don't do this, right? Then don't support children. You can always go back to supporting a fixed one, right? So there's kind of a difference. If you want a component to be super strict because you want to make it consistent, create a shape like this. But as in like 99% of cases, you want people to customize what's inside it, just use children. That kind of takes away some development work as well. All right, tip number five. Say you have this link, right? This link, you click it, it does things. And this is what it would render. So you have an anchor tag, you have an href and you have a class inside it. This is what the component does internally. If you look at the code, it says, it's basically a link, it takes the href and it says, class name is link and it renders that out, right? So you essentially just do href and you attach this extra link class that you have already written down somewhere. But can you guys see the last line? Okay, so what if I wanted to do a target blank? Would this component open it in a new tab or would it open in the same one? So this one actually ignores the prop target, right? Doesn't care about it, only cares about href. And this is like one of the first mistakes I did when I started writing React. I would pick what I could think of and ignore the rest and then it wouldn't work the way it should work, right? So you do this and it ignores it, which is bad. So another case could be you write a data test key, right? You're trying to add data attributes, like custom attributes. The thing with target or ID is that you can think of them, right? There's a close set of things. So you can put all of them in if you're like really eager. But then in like the HTML world, it supports custom elements, custom attributes as well. So what if I wanted to do something like data test key or data test ID? You possibly can't predict everything that's going to come here. So the wise thing to do is pass down all the props to your component, right? So you get the props, you pick what you need, you basically take them out like href and you basically pass all of them down to the anchor, the HTML attribute itself. So this way, whatever you pass here will basically just flow down, right? The interesting part is that children is also one of them. So you basically don't even need to do props or children. You just pass everything and then add your own custom property which is class name. Now, if you want to introduce new custom props for your link, make sure you kind of pull those out before passing them to the anchor attribute because you can only pass HTML attributes, not react props that are not meant for the HTML. So make sure you do that. Cool. So this is what it renders. It basically takes everything, drops whatever you give plus adds my own class over here at the end so that it's blue and pretty and stuff. Now, for whatever reason, I wanted to make a green link, right? So I pass a class name. This is how somebody using your component would do. They'll say class name green link and can like somebody tell me if will this render a green link? No, right? This still renders the same link and that's because you basically are overriding whatever class come from props. So if we expand this props up, it looks something like this. You have a class name, which is props.classname. You have a class name link and then you have the rest of the thing. So what you're essentially doing, you have two class names now, one from props, one inside this component and the second one will always overwrite the first one because JSX converts into an object with react.createElement and in object you can't have two skis that are the same. So the second one always wins because they get merged and squished. So you kind of end up overwriting this and you never get a green link. So how do we let the user of our component customize the look? One simple way could be just flip this order, right? Put your class name first and put all the props next. So now when somebody passes a green link, the opposite happens, which is your class name comes first, your class name comes first and then comes props.classname and then they can override it, right? Now this is again very interesting because this is pretty much a choice at this point, right? Do you want your link component to be customizable? Can the user override it? If yes, then put your native class name first and put the props next. If you don't want them to customize, if you want link should always be blue, nobody try to mess with this. Then you do it the other way around and put a warning inside it like a prop type that if you pass a custom class name, the user gets a warning that, nope, this is not allowed, please don't do this. The most common use case though is going to be something where they're trying to enhance it. So I still want a blue link, but I want it to be underline, right? With this approach, when I say class name underline, it will override the whole thing and you'll just get a ugly link with a underline, right? What you really want is to kind of merge and say link and underline attach both classes. With class names, it's actually with most custom props, that's usually the case. So what you really want to do here is pick out class name from the props, right? I'm using object destructuring here and I'm taking all the other props into a different variables with rest, what do you call it? Rest parameters, spread, I don't know. I can never say which one is spread and which one is rest, but the three dots thing, right? And then you say a class name is my class plus the class names that the user gave and then I can merge them together and then pass all the other props as a whole. So this way, when I render underline, you actually get link and underline together and then the rest of the props.  In that case, put props before your custom thing. In some cases, you want to let complete overriding. In that case, put props first, put the, what do you say, custom class name next. In most cases, you want to merge them, right? Think about onclick, right? If you create an onclick handler on your link and the user also wants to pass an onclick, you kind of do something similar over here where you basically say, call the users onclick, props.onclick, inside of my own component onclick, right? So you also want to merge events most of the time. That's pretty common. All right, so the tip here is that a good component is extendable, right? You want to take in the user's props. You want to think about that while building the component, which is if somebody wants to customize it, they should be able to ask something and then you merge or you ignore depending on what your component is supposed to do, right? The typical mistake I've did in the past was I just created an underline prop and then said, if props.underline, then also add an underline. Don't do that. You can have customization to like a perfect limit where you just pass without modifying. So this is a good way to do that. All right, number six, tabs, I really like tabs. So number six is that you say if you're building tabs, right? Now a typical user would use tabs something like this.  But if you are a user that's not using the mouse or if you are visually impaired, then you can't really see where to click, right? In that case, you want your components to be accessible. So let me try to open accessibility. Let's say, where is VoiceOver? Can you hear anything? Yes. VoiceOver is on. Nice. Chrome, the good component. Google Chrome, window. Tab one, selected, tab. One of three has keyboard focus. Right, so this is the key part. You say tab one, like this is the voiceover part of it. Where you say tab one, selected, tab, one of three, right? So you say there are three tabs, first one has focus. Then you put the right key. Tab two, tab, two of three. Tab three, tab, three of three. And then when you enter, you kind of get to this. You press another tab and you get inside. Enter some text, edit text. And this is the annoying part where it reads out everything you say, so. H-I-S-T-A-E. I don't know how they use this. I guess they're really good with the keyboards. And then when you tab it, it should go to the icon. Now this is like a pretty common modern UI trend where you put these cute icons, which the icon is depicted enough to what it does. But to somebody who can't see, the icon is like not there, right? It doesn't, the shape of it is no information. So. Copy button. Copy refresh tokens, button. Refresh tokens. Thank you. And when you can change this, it will also say what's the new thing. I hope. Okay, I don't know how to do that. So, the idea is that a good component should be, let me. Tab, spotlight, O, C, voice, voice. Oh, God, stop. Chrome, voice over off. Thank you. So, a good component should be accessible, right? If you create components that are accessible, your application has a higher chance of being accessible, right? Even if the person who's building the application doesn't care about accessibility, the fact that your component cared about it makes your application automatically accessible for like a lot of like more than 50% of the cases. Because HTML itself is accessible. So, in terms of accessibility, there's a few things that you have to do. For example, roles are really useful. So, if you say role tab list that tells your browser it's tab list, then you say this is my list of tabs. Each one of them is linked to a ID. And then you say, the one selected is, are you selected true, right? I'll drop a link which kind of has like a good description of all of them. And then you add this. Where you say tab event listener attach a keyboard event. And then you say, if you press the left arrow, switch the tab to the previous one. If you press the right arrow, switch to the right one. If you press enter, go inside the tab, right? And you have to kind of do all of this yourself to add keyboard support. Because the browsers can't really guess what behavior do you want. So, make sure you remember that there are more users than the mouse and try to do a keyboard thing. This is also pretty good. Let me bring that back. How do I, sorry, I want the sound back on. Bullet, bullet, bullet, unselected. This is really smart. I didn't know this, but when you say a password. Bullet, bullet, bullet. It doesn't announce your password into a room. It says bullet, bullet, bullet, right? Which is like so obvious, but I was like, wow, that's smart. Anyway, so when you have a button, right? And you put the text in the button. Refresh tokens, button. It will tell you what the text is, right? It will read the text out and this is perfect. But, bullet, bullet, bullet, text. Const link equals prop text. I was gonna bring the whole code. Voice over off. All right. Okay, so usually when like, this is like a more modern approach where you put like an icon. And this is really weird because even, okay, right? So I have the icon reload and appearance of link. Now, even as like a non, like even as a user who can see and hover and stuff, I have no idea what this is supposed to do. Is it going to reload? Is it going to refresh the page? I don't know. So, that's like bad for everyone. So the least, the tiniest thing you can do is put a title tag. And then when you put a tag, let me show you the voice over. That's even more fun. So it's a bullet, bullet, bullet. Voice over on Chrome. The good component. Google Chrome. Window. 12 characters, 12 characters. Insertion at end of text, secure edit text. Button. It's just a button. Button. Button. Best of luck with that. Figure out what that means. Bullet, bullet, bullet. Unselect it. Thank you. Voice over off. So, and when you have, when you add a title tag, you kind of make it easier for it to read because it can read the title tag. Voice over on Chrome. The good component. Google Chrome. Window. Fresh tokens. Button has keyboard focus. All right, let's switch to. 12 characters. Refresh tokens. Button. So this button, it will also say what is the button title, right? So that helps. And as a mouse user, you can actually hover on it and it will show you the title. But even better than this is to add a tooltip. Text. It comes to linky. Voice over off. So when you hover on it, you kind of see this as really fresh tokens, right? And it's really good for visual users. But then the moment you remove that title and you move that information elsewhere, you lose that information on the button because it's somewhere else now. So when you tab on the button, you're not actually tabbing on the tooltip because the tooltip is not visible. So again, visually impaired users can't really see anything. So that's where you can be slightly better and do something like this. So you have, this is my tooltip component. And what I do here is I attach an ID to the tooltip. And in the button, I say, wait, let me show you the output first because that's more useful. I don't have the output. Sorry, let me go back. All right, so what we want for the button is to add this ARIA label because ARIA described by, it comes in multiple form. You can also call it ARIA labeled by. There's a very tiny nuance difference between the two. But essentially you say the button is described by this other element and the ID of that element is this, right? So inside the component, you create a unique ID. You pass that ID to your tooltip and then you basically pass this ARIA described by to the button itself. And that will tell the screen reader, when you're on the button, the description is elsewhere. Go there and read it out. So this works. And again, there are like multiple ways of doing this. One way is you can tell your users that please remember accessibility, right? Unfortunately, most of us don't really know what that means, right? To make this talk, I had to research and like make sure I'm saying the right thing. So a good component should be accessible by default. It should try to offload most of the work, unload most of the work to itself so that the user doesn't have to do it. An easy way of doing this is you clone the children with a tooltip usually just have one child. So you clone the child and you pass this label to it so that what your user has to do is put this content which they anyways will because the tooltip needs some content and that is what the button will get by default. The developer might not even care about it. So a good component is accessible by default. This is like a great rate, it's called inclusive-components.design. It's like a really fun series of blog posts which is like really good to read and it explains so much. This is where everything I learned from. All right, number, cool. Is that five minutes, 10 minutes? That includes questions? Okay, let's speed up now. All right. Let's, I already said this, we can skip this. We don't, okay, cool, let's talk about this. So when you're testing components, right? How many people write tests? How many people are lying right now? Wow, good, actually hands went down. This is, cool, I'm very happy that so many people are writing tests. So when you're writing something like this, right? The same tooltip example. In this case, what you want to test is when the user clicks or enters, hits enter on this refresh tokens, does this thing change? Does the value change? And what this renders to is this div soup, right?  It has the classes over there. And the thing about React components is that you don't, when you're using the React component, you don't really care about what's the DOM output most of the time. And if the DOM output changes inside without breaking the API, your test shouldn't really break down, right? So the best way to do that is attach these data test IDs, right? Instead of relying on something like the first child of component and then the second child of the component, give IDs to things. And then you can have, even if the structure completely changes, the test IDs will remain there, so you can still use them. And then you can do something like this, where you say, if you're using enzyme, you can do wrapper.find with the test ID. And then you simulate a click and then find the input by the test ID. Or if you're using React testing library, which is awesome, you can just do get by test ID and then give your ID over there. So attach test IDs, it just makes testing easier, right? A lot of people have a hard time. Where do I start with testing? This is a great place to start because it makes the actual task of writing the tests so much easier. All right, so good component is easy to test. Number eight. Oh, number eight is how do you... I told you so many things, which is basically just rewrite everything you wrote, right? And the moment you start doing that, you're gonna burn some people, right?   So how do you bring changes smoothly? You basically support the old style of doing things, like in this batch, the count prop and the new style for a while, right? And to do this in your component is fairly easy, right? You say, prefer the new prop, but fall back to the old prop and then both of them work. And then in your change log or documentation or prop type definition, you add just like a hint that please don't use count, it's deprecated, switch to children, we might delete it at some point of time, right? And if you maintain a change log or if you write good documentation, then this is a easy way to do it. You say, soft deprecations don't be scared, but this will go away at some point of time. So the way to do that is you kind of can do prop types. You can add custom prop types validation, where you say, if the user gave a count, throw an error that count will be deprecated and whatever release 1.2.3 or more like 2.0.0, please use children instead, right? So a good component changes smoothly. It gives developers enough time and warning to upgrade. All right, so this is like the long list, which like, you can't really remember all of this. So I put this on a page where it's on sit.studio slash good component. And you can see the list. I wrote blog posts about most of them. So you can go in and kind of explore the examples and read more about it. I send this stuff every Friday, all of like everything you just learned except the accessibility part. It's on my newsletter. Maybe some people have already read it. So sorry for the redundancy. But yeah, I send the extra of every Friday. I think that's it. Yep, that's all I have. Thanks, Sid. I know we already have one question lined up. Yes. Can someone, one of our mic runners get a mic to the questioner? No, you can have my mic. Can you please raise your hand? I've already forgotten your name. Sameet had a question earlier, in the middle row there. So basically I have two questions, not one. So the first question is, in the batch component, you show, not in the batch component, in any of the component like avatar component, you show the props.missing. Yeah. So don't you think that it becomes the responsibility of the developer that if nothing is coming from the props, he has to explicitly pass the missing props in the avatar component based upon its appearance? I would say no. So the responsibility of making sure that your design is consistent should fall back on the building blocks of it, right? So if there are no props, instead of each place where the developer uses or each developer in your team trying to figure out what is the right missing icon for this, you bake the design decision into the component itself and that makes it consistent. Plus it kind of takes away the responsibility into the component itself. So I see your point that if you're a developer, you should test it out, you should know what you're doing. But knowing versus doing the work can be very different, right? If you're a new developer in the team, this is how you learn. You make a mistake, the component takes care of it and you're like, oh, this is the icon we use, right? So the more logic or the more fallbacks you build into the base building blocks, the better your entire application is going to be for that. And the second question is, you said that every component should have a similar kind of the behavior. So for example, in our application, if I have, like you show the switch, like the switch. So switch is basically a checkbox. So if I have the custom checkbox and the custom switch, so both are doing the same kind of the behavior, but they're entirely different in terms of the appearance. Should I make the same component or the different component? Awesome. So usually what you want to do is you want your developers and your users to think about the behavior, right?  The answer is never going to be, I'm trying to toggle a switch or I'm trying to click a checkbox. The thing is going to be, I'm trying to verify I'm not a robot, right? Or I'm trying to subscribe to something, notifications, right? So the user doesn't really care. As a developer, you want one way of doing a single thing, right? So ideally you should just have one of them. But even in the case where you end up with two different appearances on two different pages, just by making the behavior the same, you kind of get to the same thing where your developers are thinking in terms of the user or in terms of the functionality that how do I make this user say he's not a robot? Instead of how do I make, what appearance should this user be clicking to verify is not a robot, right? So if you always focus on the behavior and let the interaction be inside, that always helps. I'm sorry, but we are out of time for questions. Please take this offline with Sid during one of the coffee breaks. Thank you, Sid. That was a great talk. So Sid was modeling really good behavior in React. Our next speaker is going to tell us about some bad things that have happened. This is my favorite kind of talk. It's the one with drama. With, oh my God, that happened to me too. Well, not only is he gonna tell you all the terrible things that happened at Trebo when they were building their app, he's also gonna explain how they fixed them. So while we get him set up, come on up to the stage and please a warm round of applause for Kashi Grover. I would like to note that I want lots of applause for this man because this is his first time speaking at a conference. And how many of you have spoken at conferences? A few of you. So there are a few brave people in the audience.  You'll see how great he does and next year that'll be you. All right, I think we're all set up. All right, Kashi, it's all yours. Can you guys hear me, bro? So this is my first talk in a conference. Be kind to me, please. So I'll be talking about the mistakes that we fixed, a retrospective of the Trebo mobile app. So a little bit about me. I'm Kashi Grover and I've been building with React Native for about two years now. You'll find me speaking about React Native to my fellow developers in our local React Bangalore community. I also like to play drums, drink beer and cook. So about me at Trebo, I've been here for one year almost and I've been solely responsible for our consumer app. And I joined when the project was orphaned. So basically I got a code base, which I had to fix for them. And the developers at the time, they had left and they brought me into take care of this app. So we at Trebo, we absolutely love React Native and we have been using it for about two years and our consumer app is completely React Native. So all that said, it's been a super bumpy ride for us and even though it has been a really rewarding one. So today I'm here to talk about our experience with React Native. I'm here to talk about some mistakes so that you don't make the same mistakes that we made. The mistakes I'll be talking about are three of them, which is unhealthy code, bad developer experience and poor performance practices. So I'll be talking about all of these in detail one by one. So let's get started. So talking about unhealthy code, I'll be talking about engineering baggage, chaotic rules, improper app versioning, confusing project structure and unsystematic components. So starting off with engineering baggage. Now any not so simple app needs third party libraries or to implement different features, right? So our app, it was an experiment at the time by people who didn't know anything about React Native. So a lot of libraries at the time were chosen just to save some time. I mean, we already had a React ecosystem and we just wanted to be able to copy paste code. So, but some of these libraries would end up causing us so much trouble later that I had no idea and it was difficult to fix them because I didn't code them, right? So it was difficult for me to fix all these issues. And things like this would prevent us from going to a newer version of React Native and React Native development is super fast. I mean, you have to keep up to be able to, you know, get all those benefits that every other new version gives you and some of the newer libraries, they also required us to update to the newer React Native version.  So we had a library, we have a library called React Native RazorPay which helps us facilitate payments in our app. Now, this particular update, it required us to update to the latest version of React Native and it says, this package has been tested on version React Native 0.58 which is a very newer version. Now, you may ask me, why did we need to update this in the first place? I mean, it was working fine, but still why did we have to update it? That's because a few months back, Google changed their permission requirements around SMSes. So we couldn't ask the users for SMS permissions anymore based on our use case. We are a hotel booking app. We cannot ask the users to be able to read their SMSes. So we cannot take this permission anymore and this permission was being asked in this library and these guys, they went ahead and removed them, they removed that permission. And so we had to update it to the latest version, but to make our app compliant again, we had to update React Native as well. Now, we all know what an app experience is like. Some libraries were chosen to make it easier for us to copy page score. For example, we have a navigation library, we had a navigation library which didn't even save the scroll position. You go from page A to page B, to come back, all that scroll position is gone. In that's just really poor user experience. That's not like an app at all. So in our case, it was primarily visible when we went from search page to hotel page and then we came back, the whole search page would get remounted. So imagine you are on hotel number 40 and you just go back to the top right away. So these kind of libraries, they got stuck with us for a very long time and we also had been using a few component libraries. But tell me one thing, is it fair to use these kind of component libraries if we hadn't been using all those components that React Native gives us out of the box? And we weren't even using these component libraries completely, right? So figuratively, this is what our app used to look like. So to fix this kind of an engineering baggage, we have four options, updated. I mean, is this library better now? Is this something which is popular and does it continue to have good support? Remove it. Can we make an alternative for this in the existing code base? Replace it. Is there some other library which does a better job? Absorb it. Okay, so we cannot get rid of it and we cannot keep fixing these issues, but maybe we can fix some small things. So why not we copy that in our code base for now so that we can replace it later on? And we ended up building a few abstractions as well for things like components for load hash functions and other utils, or services that work with business logic so that it becomes easier for us to change these abstractions later on. And we ended up replacing this old navigation library I talked about with react navigation. And now that scroll thing is not there. Scroll position is saved because react navigation works on a stack. So, and you know, after getting rid of most of this engineering baggage, we spent some time to upgrade our stack. And I'm happy to tell you this that we are on the latest, I mean not latest as of two days ago, but the latest version of react native now 0.58.5. So the latest version is 0.58.6 as per what I read. And after making our package or package.json as lean as ever, it has become much easier for us to upgrade our dependencies for 90. Next thing I'll be talking about is chaotic rules. All our front end projects are based on react. And app, this react native app didn't even follow the same linking guidelines. That was just super bad developer experience. Imagine you are a web developer, you are taking a look at my PR, but it doesn't look the same. So, your reviews were super difficult. And because at the end of the day, I'm just writing react still. It should be easy for other front end folks to be able to jump to the app and probably implement a feature or two. So, also the same business logic was there between three projects, which is our website, our mobile site, and our app. And it was being written thrice, right? So how do we fix that? So what we did was we shifted all our front end projects including our app to our monorepo. And we now follow the same linking guidelines and got. And we, you know, some code is shared now through some common utilities and some common service functions. And there's even a possibility now to share business logic. This is what our front end monorepo looks like and that's the mobile app. Not sure who came up with the Transformers naming convention. Then I talk about improper app versioning. Now the app was, the way the app was versioned at the time was really bad. I mean, even if something was a feature, it sometimes was released as a patch. It was just really annoying.  While the developers, they did try their best to write the commit messages properly. Something was still missing. And, you know, as you know, React Native supports on the air updates, right? Which basically means that you can manually release a JavaScript bundle, your app, which your app will download and apply it on runtime. The most popular way of doing this is using port push, which is an open source project by Microsoft. But you cannot port push any native changes. So with React Native, you can also write some native modules, right? You cannot port push anything which is with respect to that. So how safe does this look? It says, port push, release, react, Pivo Android, deployment name production, target binary version 2.3.0 to 2.3.8, rollout 100% version. How do I know without any proper versioning that there were no native changes which were released as patches? There were no features that were released as patches between 2.3.0 to 2.3.8. So to become much more aware of what was happening and to be much more confident, we decided to follow a simple semantic versioning of major.minor.patch, which is something we were already doing, but now we decided to put some rules around that. Our commitizing for Git is an amazing software which helps name each commit properly and so we started using that. Even though we still update our app versions manually, it is easy to automate this using the commitizing naming convention. Let's see how that looks. So say I run a command, npm run commit, which internally runs a Git, a CZ, which is Git commitizing. And now I have some things to select, right? Whether it's a test, whether it's a feature, whether it's a fix, so that this particular tag gets added before my commit message. And obviously you can easily run a script on that, right? Because all your messages now follow a same guideline, so you can easily write a script around this. So if I select a feature, some script should run later to increase the minor version number. And at the moment, even for any native changes that we make in our app, we increase the minor, we increase this particular number because it's just a convention that we follow, so that we don't code push anything wrong. So if I select fix, it should increase the patch version number. How safe does this look now? All those native changes, not being code pushed anymore. I will be only code pushing a patch in this particular code push. So it's the same exact command, but I'm much more confident about it. Confusing project structure. So earlier we used to follow a type-based structure, and this is a project structure you get out of the box in most of the boilerplate projects out there. It's a very good project structure. It aims to solve a very nice thing, that everything which is a container will be in a container folder. Everything which is a component will be in a component folder. Everything which is related to Redux will be in a Redux folder. Similarly for styles and assets. But this made it difficult for us to plug and play features. Now we are a product-based company. We sell hotels, right? We sell room nights at hotels. So if I'm releasing a feature which is to get more users, I'm adding a wallet. So something like a wallet, let's see how that looks like in this project structure. You have your assets, which is in images you have wallet image. Containers you have your wallet page which has all the other components with that. In Redux you have something called a wallet duck. Wallet duck is basically just actions and reducers together, which are related to wallet. And then in services you have wallet service.js. I mean, how about we move all of these to one single folder called wallet? This is the question we ask to ourselves. So that's where we came up with the project structure that we use today. We now use a feature-based project structure. And it makes easy for us to plug and play features. And the context of the features belong to one single folder now. Now it's also much easier for us to, you know, search for code snippets and locate files which are just related to wallet. So this is what it'll look like now. You have a wallet. You have some components inside a wallet. You have a wallet image, a wallet duck, a wallet service and every other file which is related to wallet. Then you have user pricing, booking, hotel navigation. Everything is just a feature. Even if I talk about navigation it's just a feature at the end of the day that my app follows. So earlier it was sort of like this, assets, components, conflict containers. On the left you see how it was like before. Then in containers you have all your pages. You have Redux and services. But now it looks sort of like this. So if I added AB testing, it'll go to the AB folder. Something related to analytics goes to analytics. And obviously this is still being refactored. It's still in the works, but you get my point. And then in unhealthy code I'll be talking about unsystematic components. Over time as we progressed we noticed how unsystematic our components were. Even between our React-based front-end projects code would look extremely different. There was no single pattern being followed which would say make my app portal page look similar to the mobile site or the page. Why did this have to be a case? At the end of the day it's just React that I'm writing. Now to bring in some system and how we write components in our applications we decided to invest in a component library. And I think everyone should do that. They should have even a components folder where you get your components from. Have your abstractions ready. In our case we call it LeafUI and we set some ground rules. This is where all the basic components are exported from. We import everything from LeafUI and we rarely write styles anymore. I'll show you how we do that. Instead of doing that we use something called enhancer components. And these enhancers simply pass down styles as props to their children. Take a look at this example. You see a screen which has a center-aligned card. Card has two components, a tag and some text. Notice the code from top to bottom. Flex enhancer passes down some flex properties to a view which makes you a full screen. Then flex once again passes down some flex properties to a card which is elevated and it renders a tag and a text in a row. Now the space enhancer takes care of the padding and margin. Numbers that pass down to it are multiplied by eight and it takes an array. So if you see space margin over here, if you see over here, space margin 0, 2, 0, 0, that's basically top, right, bottom, left. That's being multiplied by eight. So I said that to the right side, apply a 16 margin. Other than flex and space, we have enhancers for size and position as well. This kind of a change obviously takes time. You cannot do this thing overnight when you decide to set up some ground rules. It'll take some time. Now my code base is like my room. It gets dirty. I clean it.  That's because it's my room and I love it anyway. So what I mean to say here is that we are always refactoring and we don't ask for extra time to refactor. It's just a part of our daily life right now. So if I'm working on, say, a hotel page, I will make sure that I refactor that as well as per the new LEAF UI guidelines that we have in place. The second mistake I'll be talking about is bad developer experience. So why I'm able to speak to you over here today in this talk is just because how confident I am about my releases now. I now rarely have to give any production support. And the practices I'll be talking about here are what gave me a work-life balance. Let's get started with point A, bad local debugging experience. So when I joined, I noticed that there was no proper tools. There were no proper tools for debugging in place. And myself was rather new to quality tools for React Native. I used to mainly rely on console statements. And at the time, the local debug flow in general at Rebo heavily used Chrome developer tools and console statements. And there was no information regarding Redux actions, API calls, local storage, among many other things. So fixing this was really easy. I just had to Google to find the right tools. And locally, there are two amazing tools available that I use personally. It's React Native Debugger and Reactotron. Both of these are open source and they give proper feedback around API calls, Redux actions, local storage, and a lot more things, which are just related to React Native. So debugging locally has become a breeze now. And they're both awesome. And I would suggest that you use both of them. So this is what Reactotron looks like in its timeline. Notice how beautifully it displays all the actions. So on top of where it says get landing page content, then you have some other Redux action, then some async storage actions that took place.  So log, image, custom display, connection, benchmark, API, mutations, actions, and even other things, right? But I personally don't use Reactotron that much because of this. Now this is called React Native Debugger. This is, again, an open source project. And this is something that I use every day. It gives me a combination of Chrome developer tools, React developer tools, Redux developer tools, and certain features which are specific to React Native. So say, for example, if I have to make my internet slow, I have to test my app on slow internet, I just use this tool like I would use Chrome to do that. Basically set it on 2G or 3G connection. And on the right side, you see the API calls properly, similar to Chrome. And on the left side, you see the Redux actions. So it's just too easy to debug locally now. But the nightmare for me was production debugging. So since the beginning, we have used Bugsnag to track our crashes. But our production crash reports on Bugsnag, they were paralyzed. I tried to upload React Native source maps to Bugsnag, but the result just wouldn't help me enough. Even after uploading the source map, the stack trace Bugsnag would give me used to point to a different line. I mean, imagine you have undefined is not an object. That's your error statement. And the line it is pointing to is some import statement in some library. That is something that used to happen. So I stopped uploading these source maps. And the report would now show me office-coded code. A line number in the office-coded JavaScript bundle. Luckily for me, we were using test IDs and accessibility label props in most of the components. So this is how I used to debug at the time. I would get the line number pointed by Bugsnag and manually find it in the JavaScript bundle. I would then copy this line of thousands of characters to a new file and then carefully go through it. I would pray for something like a test ID or accessibility label, which wasn't office-coded. I would then spend a few hours trying to reproduce the crash using all this information. But they had to be a better way. So this one time I got so pissed, I decided to post this. Roses are red. My app is red. Unhandled JS exception type error undefined is not an object. This is what my life was at the time. But as it turns out, Bugsnag is awesome. It's a brilliant platform for tracking crashes. Why it didn't work properly for us before was because of my own point. As I said earlier, source maps weren't working correctly. But it turned out that my builds and source maps weren't clean. Clean builds, they deserve clean source maps. So after setting up our CI, CDs, I basically added a source map upload script, which runs after every clean release. So we have a clean release. It deserves a clean source map. And so we also added some Slack integrations on Bugsnag. And now each time there's a spike in crashes, we get some slack alerts. So take a look at this snippet from Bugsnag. On top it says null is not an object, evaluating e.measure. And over here you have some stack trace. Now after the source map is working, it's telling me everything properly. Evaluating e.measure points to component.measure, which is something that was crashing every once in a while. But wait, it said null is not an object. OK. Let's go to the next slide. No CI CD. This was another pain point. Now even many months after I joined, we still were releasing to production from my own laptop. Imagine the amount of problems that could have caused them. The folder I was using to release was the same I used to work in. And you don't eat where you take a dump. Did I do a clean npm install? Did I clean Xcode or Android Studio before releasing? I think you understand what I'm trying to say. Now we tried different CI CD solutions and we decided to stick with Bitrise because it gives Mac machines. Over time, we set up multiple workflows in it. An example is a nightly build. Here also we get slack alerts for everything, whether the build failed or whether it was successful. And releases are also made using Bitrise now. These are built on clean instances and so there's no chance of them being dirty. And Bugsnag source maps are also uploaded from here, as I mentioned before. So this is what my app dashboard on Bitrise looks like. So on the left side, you see proper builds that ran every single day. I talk about no test automation. In general, I'm the sole developer for the app at Rebo. So I don't have time to write unit tests or any kind of test for that matter. But we did have some QA bandwidth. So let's see what we did. Now, all releases that we were making at the time were being tested manually. And due to human error, sometimes test cases could get missed. We also came to realize over time that certain bugs were device-specific. And all this uncertainty was hurting us. Because of all this, we decided to invest in building a test automation suite on Amazon Device Farm. A colleague of mine from the QA team wrote down a bunch of test cases of core flows in app. For example, the booking flow, you go from your home page to your information page for booking. Everything's there that happened. And they achieved that by using test IDs and accessibility labels. Because those are what point to that particular component so that you can write automation on that. Our nightly builds on bitrides are followed by multiple device regression. There's high predictability in app stability, which has resulted in very good business. And this has also freed up some QA resources for better work. Because you cannot just expect them to keep testing everything manually. Now, they're writing test cases and they're off to do better things. Let's see what this multiple regression I talked about looks like. You notice six different devices on Amazon Device Farm, which ran about 20 different test cases. And you can see how for every different device, they were failing. This could very well be some UI mistake that we made. Because devices have different screen densities. Maybe some component was overflowing. It wasn't rendering properly. Something happened. Maybe even the API is crashed. I don't know what this meant at the time. So let's go to the next slide. And I'll be talking about some poor performance practices. So three things, bad scroll performance, overdraws in Android, and poor APM, is app performance monitoring. React Native has its own performance issues. It does, but if you follow the correct practices, you don't have anything to worry about. It gives you a very nice platform to build amazing mobile apps. But you cannot keep on blaming React Native for whatever problems it has if you don't take a step to improve your app performance. So let's go through these one by one. An issue that we faced back then, and to some extent we still face today, was the highly janky scroll experience we had on the home page and search page of the app. After some digging in, after some spikes, we were able to find some factors which were at least visible to us. Now, we were using a library to render SVGs, which internally used web views. Since React Native doesn't support SVGs out of the box and we were fetching these over the web, this seemed like a simple solution, right? And the card component which was being listed out on the search page, it was rather heavy and didn't follow proper, you know, warning signals that React Native gives us. And the flat list wasn't well optimized. We hadn't read the documentation around flat list properly to be able to put some optimizations which helped you a lot really. And the animations on these pages were poorly implemented. Wait a minute, I said web views rendering SVGs. Let that sink in, okay? This is probably the most embarrassing thing that we ever did. So you see those scroll bars on top, right? On that particular component, those are SVGs and that's a web view. And on Android, you cannot even get rid of those scroll bars. It's probably still an open issue somewhere. You just cannot get rid of that on Android. So for a better scroll performance, we got rid of these web view based SVGs and now we use PNGs. And we simplified the flat list cards and removed some extra animations which were there in them. We added some simple to implement optimizations to flat list which are clearly mentioned in React Native Documentations. But we still haven't done enough gestures to the animations and we might just remove them or maybe a better, an easier to implement UI. While I spoke about all these visible factors, there was also something really big, a big invisible factor which was in the play. I'm talking about overdraws in Android. It's a major performance issue and it's not specific to React Native. Open any app in your phone and I'll show you how to debug overdraws. It means that a single pixel is being rendered multiple times in a single frame of rendering. It happens when two components overlap and it happens primarily when, you know, there are two different color components which are overlapping. So fixes for these overdraws, they can be too easy to be true and they have a very high return on investment. Basically, just don't overlap your components. Don't overlap your background colors. You have to overlap your components.  Take a look at this example. This is say, for example, a root of any app. It has, it is mounting root navigation inside some view which is a container. Now that has some styles on top which says flex is equal to one. Flex is one and background color is white. But don't do this if possible because you can always write a background color at some point later. So how do you debug this GP overdraw?  Now there is some color convention which is followed here. True color, I mean no overdraw. Blue overdrawn one time. Green overdrawn twice. Pink overdrawn three times. And red overdrawn four or more times. This is what our overdraws used to look like back then when I started debugging them. This is what it looks like right now. After the app looks exactly the same. There are few places where, you know, I could have used some extra background color but it doesn't impact the usability of the app at all. This clearly still room for improvement. Say for example, in the hotel space, last screenshot is from the hotel space. It's still room for improvement, but we have, we have reached, you know, we have crossed a long way here. So I also decided to do some performance profiling of our older app version before we did all these performance improvements. This is a profile of the user opening the app, selecting a city, scrolling, going to a hotel, booking it, the whole major flow that you would expect the user to do. This is what the profile looked like. That's, you can clearly see the CPU and memory usage. Whatever the numbers are, I mean, I didn't go into detail as to what percentage this thing denotes. I just decided to do a performance profile of the newer version. This is what it looks like. So profiling GPU rendering. How do you profile that GPU rendering? You go to developer options, select on screen as bars. Let's take a look at these demos. So this is our older app and just let that sink in. This is our homepage and I go to my search page and I was talking about janky scroll experience. Do you see those bars crossing the roof of the phone? This is how bad it was at the time. So let's take a look at the GPU rendering profile at this point. So not much of a difference on the homepage or landing page. You still see more or less a similar graph, but wait till you go to search page now. Much better, right? It's at least far more usable now. Wasn't even usable before. And we must have lost a lot of business just because of our performance practices at the time. This is nothing going through the roof exactly. So last thing I'll be talking about is poor app performance monitoring. We didn't have any statistics to measure apps' performance in production. This would make it difficult for us to convince business to implement performance improvements in general. There was no way that we could relate these kind of performance improvements with conversion improvements. And there was no way to tell whether the app was slow or whether APIs were slow. And we were already using New Relic for all of our other apps. So we decided to integrate their Android SDK with the app along with the native module, which we built to trigger it from React Native. We connected up pre-existing analytics events for which we used segment for that. So segment analytics events also now connect with New Relic so that we now get some performance metrics in place. We can now relate analytics events and performance and we then prepared some relevant dashboards. And we now have some well-defined benchmarks. So I'll go through that, you know, this is part of the dashboard. All these shots I'll be showing are part of the dashboard. So this shows Crash Rate by Version, which is already there on Google Play, Google Play Console. But it's good to see it all in one place so that you can track your releases properly. Then you have, again, crashes another graph for that by App Version. Then you have number of users by Version. And then you have number of users by OS Version on Android. Now, here you see four different dashboards, four different tables. ATFI, it stands for Time to First Interactive. It means the amount of time it takes for something to become interactable. You know, how often, how soon can a user start using that page? And this dashboard, it shows exactly that for both Wi-Fi and cellular on both our search results page and hotel details page. And this can directly impact user conversions if the numbers are too high, right? So if it's taking more than 30 seconds on a particular page or a page to become interactive, that's a really bad warning sign. And this is where we had some benchmarks in place. And this is what we strive to improve over time. And you have prepaid bookings day-wise. Can't show you the numbers, obviously, here. Then you have error rate by domain. So API crashes. Something went wrong in the APIs. Were there any 500s there? So you get to know all of that. Then prepaid bookings by App Version. Now, since this directly comes from segment, I can even track my iOS app here, which is something we'll be working on at some point. So finally, the conclusion of my presentation. We have an updated stack. We have much less dependency on third-party libraries. We have a great debugging flow. We have a proper CI CD setup. We have automated regression testing. Podbase is thriving in the Monorepo, great component library in the name of Leaf UI, and easy-to-read components. We have a much better navigation experience, much, much better performance in the app, greater understanding of the native site. And now we actively monitor performance. But we still have a long way to go. But where we wish to see React Native is we'll continue to use React Native no matter what. We absolutely love it. So as long as I'm there, I'll be using React Native for sure. So we wish there was some great performance out of the box. Maybe the newer architecture of React Native will solve that for us. And I wish there were some more warnings on preventing overdraws in Android, and more warnings on preventing some general bad practices which I noticed were wrong in how you write opponents in the first place. And it should be easier to upgrade. I spent about 25 days to upgrade to a newer version of React Native. So I'll meet me in the cafeteria or somewhere outside. I'll tell you how we did that too. And improved animated performance, and an easy-to-implement gesture system. I don't know how to use the gesture system even today. So I've done it. So I think we all deserve a cake. That was a long presentation. Thank you, Kashish. We don't have time for questions. But Kashish, along with some others, will be doing a Birds of a Feather session at 12.40 during the lunch hour. No, 12.40? During lunch on React Native in production. Yes? Yes, I remembered it correctly, React Native in production. So if you have questions, please do stop by the boff to ask. They're a fantastic way to do informal discussion and question and answer. Thank you so much, Kashish. We are now going to be having a coffee break, a tea break. Hopefully the coffee is actually available. We come back at 11 o'clock for our keynote presentation. And please do, I hate to have to ask this, please turn your phones to silent mode. I kept hearing people's notifications. Not cool. Enjoy your break, and we'll see you next time. So we would like to thank Facebook for supporting Pershiram's travel over here to coming to React Fu. So Pershiram will be talking about building React Native. So Pershiram, this stage is all yours. Hello, everyone. Good morning. Was it too loud? Hello, everyone. Good morning. My name is Ram, and I work at Facebook on React Native. I'm here to talk to you about building React Native, not just building apps with React Native, but building React Native as a platform. This basically is based upon my experiences as a web developer, all the way from starting websites to building the framework itself. When I started building websites, it was mostly about changing DOM nodes here and there. There was jQuery. There was Angular. The web has actually come a pretty long way. I think the key contribution of React to the UI engineering space itself is the way we think about UI going forward. The whole idea of using components, it's not new, but React basically set that in stone. The fact that you can use components not just in your web applications, but also on your mobile phones was actually pretty interesting. Apart from that, it's this whole idea of declaring or being declarative on your components. You know the fact that you have props, you have state, and then just using those two, you'd be able to create and ensure that React is able to manage the changes for you was a pretty big deal. No longer have to worry about, hey, if I click on something, what changes? React takes care of it with the React reconciliation algorithm. And this idea of building the web or using these components as building blocks is pretty critical in the way we think about UI engineering these days. Effectively, what we describe when we are writing a React code is a tree pretty much. It's like, hey, this is what my component tree is going to look like. My page is going to be composed of components. And then this component tree is transformed into something bigger and displayed on the web page. It's all about the trees at the end of the day. Effectively removing components, removing leaf nodes, stuff like that. So in my talk, I'm going to talk to you a little bit about how React native can evolve from React and also about the similarities. And more importantly, the differences between these two platforms. But before I jump in, how many of you here have done any sort of React native in the past by a show of hands? That's a pretty good number. So I'm guessing most of you know that React.js is a library for writing websites. On the other hand, you can use React native to build mobile applications for iOS, Android, and a bunch of other platforms using the same design paradigms and the development knowledge that you acquired using React native. The idea of React and React native basically was that you could learn the whole paradigm of React once, and you could apply it to multiple platforms. I think Tomo during his JS keynote said that it's the idea of learn once, write anywhere. So let's look at what React really does inside. What does React really boil down to? So on my screen right now, I have a simple component. And effectively, that component has the tree on the other side. Now this tree is converted to a DOM structure, and React takes care of it for us. Now let's say that I want to add a new element. Let's say an input element to type something using the keyboard. I would change my JSX for that. React would automatically change the tree and issue the necessary instructions to mutate the tree, and the tree basically can then get rendered on the screen. And when people talk about virtual DOM, which is basically a concept, it's basically this concept that they're talking about. The idea of taking a snapshot of your component at one time, comparing it with the snapshot after the changes have been applied, and then using those comparisons, generating instructions that can be sent to the browser to draw stuff.  So in React, you have this a little bit of weirdness where you have to say, hey, my value is based on a state. And whenever someone types something, I'd want to update that state. So this is more like a complete component that you use with React JS today. I haven't even gotten into React native yet. So how does this really work?  Why haven't I moved the hooks, right? So fine, I'm not a dinosaur. I like to live on the edge. Let's just use hooks. There's no difference there. So if the same thing with the hooks example existed, this is how the code will sort of look like. Now, let's say you have this application. The interesting thing, especially in a demographic like India, a lot of people also use websites on their mobile phones. And React doesn't really have an opinion about whether it's a website or a mobile browser. So let's pretend that this is running on the mobile browser. So let's say you whip out your mobile phones and you start typing something. That's a native event that the browser gets. That on-change event is called whenever someone types something. Because it's an on-change, it's a function that React components describe. And this will effectively say, hey, set the value of text to something else. And then that is sent back to the actual DOM element. There is nothing new. Most of you should already know about this if you've done any sort of React, right? This isn't this common paradigm. So this is how React basically works. Now, the question is, why does it have to be input text? Can we make it a little more generic and probably call it something that will work on the mobile phones also? So the interesting thing about mobile phones is, yes, you can display a web page, you can display a mobile browser, but there are tons of apps that look good and you will kind of look a little bit different when you adjust a website, not a app itself. So that's the paradigm that React supports. React lets you use, instead of saying input text, you can actually say something that's a little bit different, text input, and this would basically render real native components that let you, that become a part of your application. So the whole story about on change and all of that, that is exactly the same. No difference in terms of the way React versus React Native behaves in this specific scenario. However, there is a slight disconnect. Effectively, remember that on the browser, it's JavaScript manipulating the DOM, right? In React Native, there is no DOM. The components on the mobile phone are actually components that are native UI components that Android or iOS provides. The text box there is an Android text view. The text box on iOS would be a UI text, right? So those are actually Android and iOS specific components, which means this interaction wouldn't really work because it's not really you being able to call a DOM method. And this is where React Native starts to diverge from React. While in React, you can use direct DOM calls. On React Native, you use a concept of a bridge. The best way to think about a bridge is that it is a way for you to communicate between your JavaScript layer to your native layer or to your Objective-C or Java layer. What that means is instead of calling methods directly, you have to serialize them into something like a JSON area or something, and then send them across the bridge. So whenever someone talks to you about React Native and someone talks to you about the bridge, this is pretty much what they're talking about. The whole idea of how the React Reconciler can create JSON structures and sends them over the bridge. Everyone with me are still here? Is this clear? Okay. There's another gap in mobile app development which I have not really spoken about, and that is layouts. So on the browser, the browser understands Flexbox and CSS and all of that. Unfortunately, there is no concept of a Flexbox or any of the other browser CSS styles on a mobile device. I mean, Android has its own layout system. iOS has its own layout system, but they're actually different from Flexbox.  Like you have, say, for example, in Android, how many of you have done some sort of Android before? Okay. So you must have encountered things like linear layout and constrained layout and stuff.  HTML and the web world, on the other hand, kind of combine visual elements with layout elements. And the web developers have found this to be pretty useful. The fact that you can build your structure, your semantic documents just with the web structure and then style them and layout them in line using CSS has been a very powerful and very appealing method of programming. And React Native adopts this paradigm to make web developers be able to write mobile applications. What that means is when you're on Android and when you're on iOS devices, you need some way to convert your Flexbox CSS styles into something that Android understands. And this is where a shadow DOM or a layout system comes into play. The layout system in React Native is called yoga. And the primary use of yoga is you give in Flexbox and CSS and properties, and yoga will give you the X and Y coordinates of where stuff should be displayed on the screen. Yoga is very similar to CSS rendering engine, basically. Yoga does the exact same thing. And on the screen, what you see is three separate steps. And whenever someone says React Native runs using three threads, these are the primary threads for React Native where React Native executes in a multi-threaded fashion. What this also means is JavaScript has its own thread while the UI layer has its own thread. And this is very different from the way React works. On the React, your JavaScript thread pretty much interrupts the UI thread, right? React Native has these multi-threaded applications, multi-threaded way of doing things right from ground up. Now, this can be an interesting dance. So let's take the example of a typical render method and see how stuff starts getting rendering on the screen.  There's an asynchronous call from the mobile to your JavaScript player that says, hey, come on, render method, tell me what should I draw? The render method is then gonna start doing the reconciliation algorithm, trying to figure out what instructions are sent and it'll send it to yoga. Yoga would then calculate the layout and it'll start queuing all of that information over to the UI thread or the native UI hierarchy manager thread. This jump and this whole system of multi-threaded environment is primarily asynchronous. What that means is the UI thread is not waiting for JavaScript to tell it what to draw. The UI thread is super responsive. And this is one of the reasons why React Native is very, very performative. The basic point that your UI thread doesn't have heavy operations running is pretty impressive. In fact, most of the heavy lifting, in fact most of the business logic happens in the JavaScript thread. Most of your layout logic happens in the layout thread and the UI thread is just responsible for displaying elements. Now all this is well and good. Let's also take the example of the first example we took about keyboard and on-change, right? How does that work? So in React Native, the on-change method gets called and again this is asynchronous, right? So that's good. But once the JavaScript has finally figured out what to do with that on-change method, it'll send it to layout. And this is where the 1% cases of React Native's weirdness come into play. So because React Native is inherently asynchronous, what could technically happen is before the layout thread is done with its work, the user may have typed the next character. And while JavaScript is processing it, the on-change event is gonna go out. What this means is for a split second, the user has typed AB, but then the B gets canceled and only A is displayed because the set text instruction is shown. This is sort of a collision between, hey, this is what I want my state to be, but this is what my state is. So yes, you will get eventual consistency. But for that split second, there is this weirdness where you say, hey, I typed something but it doesn't show up. Of course, this is a little bit weird, right? I mean, we don't see this behavior on the web. This is one of the key, this is a side effect of the whole process being asynchronous. This is typically a race condition. Of course, eventually the final method will get called and the text will be set to AB. So the whole thing is fixed, so this is not that big a problem. However, this kind of has a janky effect. Like the user suddenly sees B removed for a minute and then shows showing up again, is a little bit janky and it's not the best of performance experiences, right? Like what do you want is smooth native first-class performance experiences and even slight glitches like this could be an issue. Again, this is only for the one-person cases or even less than one-person cases, but React Native wants to fix this also. Here's a much more pronounced use case that you see. Remember I told you that React Native UI 3 is responsive? It actually is. In fact, it's so responsive that the scroll doesn't stop and because the scroll doesn't stop, even though JavaScript is not sure what to render for certain elements, the scroll will continue. So what you see is actually white space and then the elements start showing up eventually. Now this is interesting and this is an accepted paradigm on the web. Like on the web, if you start scrolling, you can show placeholders and that's perfectly fine. However, if you take out your applications and look at native apps that have native implementations, they actually stop and start showing janky content and that is the acceptable way to do it on mobile browsers. And because with React Native, we strive to recreate all the features and the bugs of the way mobile works, we want to be able to replicate this too. So by now, I'm sure most of you are thinking, hey, all of these problems don't exist on the web, right? Why is that? Well, that's because on the web, it's all synchronous. Whenever a change event happens, you immediately respond and you can actually block and even cancel input events. Like whenever there's a key press on the browser, that is a synchronous call and you can always say e.preventdefault or event.setpropagationdefaults and stuff like that. You can't do that on React Native because it's a completely separate thread. On React Native, events are fire and forget, not so on mobile. So it's kind of funny that with fiber and all the improvements in React, the React JavaScript framework is trying to move from a synchronous to an asynchronous world. Well, on the other hand, React Native, which is inherently asynchronous, is actually trying to move to a synchronous world. And I think this is where both these worlds are starting to finally come together and look more and more like each other. And that's basically what I want to be covering in this talk. The idea is there are going to be use cases where you want to be asynchronous. Typically, like you've already waited one minute for one second for a network request, waiting another 100 milliseconds to render it is perfectly fine. On the other hand, when there's a user input like a touch or a scroll or a drag, that needs to be instant. So what this proves is there is in the world, there are use cases where both synchronous cases work and asynchronous cases work. Asynchronous cases would be performant for 99% of the cases, while we also want to be able to support synchronous rendering in case of React Native. So how is all this achieved? The first thing we want to do is remember I told you about the bridge. The bridge is basically the culprit here. The problem is that the bridge is fundamentally asynchronous. Now, if you typically look at computer science concepts, it's easy to make a synchronous call into an asynchronous call, right? I mean, you just add a set timeout and it kind of becomes asynchronous. The best way to think about it is if it's a synchronous call, just add a set timeout. On the other hand, if it's an asynchronous call, making it synchronous or making it blocking is hard. If you have a set timeout, how would you ever receive a response back? The maximum thing you can receive back is a promise. You may not be able to get the value back, right? Unless you do like blocking and add like semaphores and stuff like that. So that's the case we want to solve. What we are going to be doing is this bridge is actually a little perilous. It's a little dangerous. So we want to be able, in the new architecture of React Native, we want to burn the bridge. You want to get rid of the bridge. What we want to do is not use a bridge to cross over, but use more like a jetpack to jump over from one thread to the other. We want synchronous and asynchronous operations. Now, what does that really mean? Before I explain what React Native does, let's take some inspiration from what React does and let's see how that mirrors to what React Native could do. So the bottom part that I'm going to show you here is how the browser works. So let's say in the browser, you use an API called document.createElement. What does it give you back? It gives you back a node, right? And then you can use this node to append child to somewhere and stuff like that. Effectively, what exactly is that node? That node is an HTML input element. That is a C++ object. That's not a JavaScript object that someone created. In fact, it's an object that probably has a reference to a system control that's written in Windows. So if you look at a checkbox on a website, on a Mac versus a Windows desktop, it looks different. That's because you are inherently using on the background, the UI control that the system provides. Let's match this to what React Native does today. React Native uses native control, native UI. So that's that. Today we use JSON, but JSON is asynchronous. What we want is an API like this. And what we want to be able to do is exactly what the browser does. So in a way, React Native is starting to look more and more like the browser in the new world, in the new architecture. Surprisingly, over the four, five years that React Native has been around, it hasn't changed fundamentally. And I think this is one big change. The scale of the change that's happening right now is probably much, much bigger than anything that has happened in the past. And this is good not just for performance, because you now will be able to make animations much faster. This is also important to ensure that your applications continue to work and look just like native applications. So here's the fundamental idea. The idea is what you need is not a bridge. What you need is an RPC call or a method call. JavaScript should be able to call Java functions directly. That's the basic idea. The basic idea is all of these Java or Objective-C methods are directly exposed to JavaScript via C++ host objects. The reason you have to do C++ host objects is because React Native bundles a JavaScript VM or uses a JavaScript VM to execute your JavaScript code. And that's a C++ object, right? So JavaScript needs to be able to call these methods and JavaScript will be able to hold references to native objects. Let me explain in terms of code how this might look like. And the first thing to understand is whenever you're talking to someone and they say JSI, this is the basic idea they're talking about. Now, JSI is a pretty interesting idea because this is the basis of all of the new improvements that we are making in React Native. For example, in case of view managers or in case of UI elements, what's gonna happen? So in case of UI elements, all of the view managers are gonna be exposed as host objects. And then React reconciling, you know the set props and set value that I showed you for initially, that's gonna be, instead of serializing it, you can actually call that from JavaScript into native land. So in terms of code, what it might, like this is pseudo code, so this may not work, but here's what you do in the browser, right? What you'll be able to do with React Native is something like this. So this is not the exact code. Again, this is pseudo code and this is in flux, but the idea is this. You'll be able to create a node on the UI manager directly, and that node is no different than an HTML input element, except that node may be implemented in a C++ object like this. And this is starting to look like JavaScript already because if you see there's a getter object, so this one here is getter, is a getter, it returns a value, and if the method is create node, what it basically says is it invokes an Android or an iOS API. So whenever JavaScript calls create node, it'll call a C++ method, which will eventually call an Android or an iOS method to create the view or create a UI view or create an Android.view. And all of this again is synchronous. If you want, you can make this method asynchronous. Basically what you can do is create a new thread in here or create a new thread inside the Android API or the iOS API and make it asynchronous. So this is for UI manager views. What about native modules? So in React Native, if you want to access Bluetooth or geolocation, you use this idea of a native module.  Sort of, okay. So let's take the example of the browser. In the browser, this is how you take a picture or record a video. What exactly is navigator? So you say navigator.getUserMedia, right? What exactly is navigator? Navigator is window.navigator, but it is actually a C++ object that the browser exposes to you on the JavaScript side. In React Native, there's no window or there's no global really. So you might just require a native module called camera and then call the method on it. Just like the view managers, the C++ is gonna be, hey, the getNativeModule camera will actually be a host object. And whenever the getPictures method is called here, that would call the Android or the iOS getPicture API.  So here's a simple use case of why this is much more performant than what we have today. So let's say you have a scenario where you wanna take a picture of what you're eating and upload it to Instagram. The way you would do it is you'd get the native module for taking a picture, that will give you a picture back, and then you'll call the upload method and pass the picture in, right? Like this is straightforward, right? Today what happens is this is what happens. So that's the JavaScript side. You have the Android side here. The getPictures method returns a picture, which is sent over to JavaScript. And then this JavaScript is sent back to upload. Unfortunately, because these are two different lands, and because you have the bridge today, you have to do JSON conversion for both of them. And imagine converting a blob type to like JSON and then sending over. That's painful. In the new world, in the future, the way it's gonna look like is this. GetPicture will actually be a picture C++ object, and JavaScript can hold a reference to it. And when you want to pass in this, you just pass the pointer back in. In fact, because this is a pointer, you can actually start even calling methods on that picture object. And this way of direct calling is much more similar to what the browser does. And if you think about it in retrospect, you'd be like, hey, why isn't React like this from the day one, right? So you saw a lot of C++ code. How many of you here are C++ developers? Two, three, four, five, okay. How many of you are JavaScript developers? Okay, keep your hands up. Keep your hands up. How many of you, so all of you who are a JavaScript developer and want to write C++, keep your hands up, others put your hands down? That's surprising.  There are JavaScript people aren't really super interested in writing C++ yet, right? So the question is, does it mean that you have to write C++ in React Native? Not really. In fact, most of the code that you saw about the host object and stuff is sort of repetitive. If it's repetitive and if a computer can do it, why do humans have to do it, right? So we are actually thinking of a code generation system. The idea of the code generation system is this. You'd use something like Flow or TypeScript to define what your native module or what your view manager is gonna look like. Computer can look at this and says, hey, this is a native module and these are the different functions in it. And we can have a system that generates the C++ module for it. There's another hidden advantage of this. So effectively, the big advantage is, one, you have the C++ code generated so you don't have to worry about it. But more importantly, when you do things like over-the-air updates, a lot of people have pain trying to compare the native version versus the bundle version. For example, you have native version one, you have a bundle version and then that bundle version uses a new API. Can that new bundle go to older versions of your app that's published? So this is really painful. And with this new architecture, and the reason why this exists today as a problem is because you might have a type system in JavaScript, you have a type system in native, but there's no way to translate them between each other. And this whole code generation will actually solve that. You'll be able to translate your types into C++ types and tell exactly what exists on the device. So what does this really mean for, like, this is new architecture, what does it really mean for you and me? Like all this theory was good, but our day jobs are writing production applications, right? What does this mean? For JS developers, almost nothing should change. I mean, the JavaScript code that they write is going to be pretty much similar. There's going to be code gen and all that is going to be very similar. For people who write native modules or for people who write view managers, like basically people who write Java code or Objective C code, this is going to be backward compatible. So if you want the performance, you can convert your existing native modules and view managers into the new system, or you can continue using it with the backward shim, which obviously is going to be a little slower than the modern system. Question is, can I use this? What's the state of this? You'd be surprised to hear what a lot of this code actually exists in React Native, which GitHub repository today. Technically speaking, if you want, you may be able to, again, I say may because I don't know what the state of it was last night. I tried it and it worked last night. I don't know if something changed today, but you may be able to create a turbo module or a view manager. At the minimum, if you want to understand how the system works end to end, you should be able to read the code and figure out like, hey, this is how the end to end system looks like. So all of this is actually in production right now. In fact, in Facebook, we are testing the system to ensure that this doesn't crash and the performance is actually as good as what we say it is. And this is backward compatible. The goal here is we want, it's not backward combat, it's backward compact. We don't want to fight backward compatibility. You remember how when Fiber came in, you didn't have to worry about it as much? You remember how Hooks came in and you didn't have to worry about it because Hooks was just one way of doing things? I think that's something I really like about the React team. The React team very consciously thinks about their APIs and ensures that they are backward compatible and we want to follow the same suite. So that's about the new internals of React Native, but React Native is not just about Facebook or not just about what we are doing. React Native is about the community. I'm not sure how many of you are following the React Native blog, but there was a time when there were tons of pull requests and tons of issues and people were not sure what was happening and there were companies not using React Native and stuff like that. Things have improved tremendously since then.  Of course, there are multiple of these view managers and native modules. So one of the things we are doing is to ensure that the community has the power, we are moving many of these outside into the community repository. What this means is React Native will be much thinner. This effort is code named Lean Core and what this means is your upgrade, so a lot of people actually have trouble upgrading React Native. Now that React Native is gonna be much more thinner, it'll have much less components. Upgrading is gonna be much easier. In fact, a lot of the benefits of this we are already starting to see now. The latest version of React Native replaces a React Native div and uses React Native Purge div which makes upgrading much, much, much better. Similarly, we are gonna now start supporting Cocopods by default, which means that all of that pain about you going to try and understand the next code project and modifying it, no more. You can just use Cocopods and upgrading will be much, much easier. The whole paradigm here is React Native is a community project and it is the community that is able to make this framework so powerful. You can read more about it at the URL below, but that's where all of our architecture discussions happen in a very transparent manner. So anyone in the audience here can actually go influence the roadmap of React Native. There are some really good discussions and proposals happening related to turbo modules, fabric, the new JavaScript, the whole JavaScript VM, upgrading it, Cocopods, Gradle dependency, even removing the CLI out of the React Native core. That's a good place to get there. I mean, if you're getting started with React Native and want to get involved, that's a good place. And as I said, it's the community that's building React Native and all of the work, the hard work that community is doing is actually paying off very well. Inside Facebook, we use React Native for a ton of apps like our Ads Manager app or our Analytics app or our Oculus companion app. They are all written in React Native completely. They are Greenfield applications. Even things like Instagram and the main Facebook app have tons of React Native screens. In fact, in the main Facebook app, if you look at Marketplace, that uses React Native and it's not just Facebook. Even bigger companies like Microsoft, Amazon, Sony, Wix, all of them actually use React Native. In fact, Skype has over a hundred contributions into the existing React Native framework. Skype runs React XP, which is like a cross-platform React Native web sort of an abstraction and a lot of mobile versions of Office, the Outlook app that you see, parts of it actually are written in React Native. You'd be surprised, you wouldn't know and that's the whole point. As a user, you don't have to know if your app is written with React Native or not. It needs to be smooth, it needs to be performant, it needs to be a native app. Here are some more, I mean, here are some of my favorites, like Pinterest, for example, has React Native. Like if you have the Pinterest app, that uses React Native. A game like Zynga, the words with friend games, that is actually React Native. People writing games are using React Native for delivering buttery smooth performance and there are many, many more. I am personally very excited about the future of React Native and the direction in which it's going. I personally have been working on cross-platform and hybrid frameworks forever. In fact, I'm actually a commentator in the Apache Cordova project. I speak regularly with people from the native script team. We recently visited the people at Flutter, at Google at Flutter, we're doing Flutter. I used to also report to the same management chain that did Xamarin. I've been doing hybrid apps for a very long time and I think we are in a world where hybrid apps are finally starting to deliver top experiences and top application performances and this is what is React Native and this is what is where React Native is headed. If you have any questions and are socially awkward like me, ping me on Twitter, my DMs are open, but that is what is React Native bringing to you in the future. Thank you. Okay, so we will be taking the questions. Yeah, okay. So, questions? Yeah. Sandeep, can you please hand the mic? Hi, Pashram, my name is Manu. I wanted to ask what are your views on React XP? It sounds like a good concept that you write good ones and have it work on all platforms, but why is it not taking off or what are your views on it? Hey, that's actually a very good question. In fact, that's also something that we are exploring inside Facebook. I'm not sure if you've heard but we have hired Nicholas Gallagher who wrote React Native Web. We also hired Vincent Reimer who wrote React Native DOM. And Facebook internally, I think we do believe in the React way of doing things. Today, a lot of people think about React Native and React DOM as two disparate systems. What the way we want to think about it is there is a React way of doing things and React DOM, React Native, React VR are just ways or renderers on top of it. So, I actually really like the idea of React XP and React XP is not the only one who are trying that. There are multiple of these people there are multiple places where people have one component library and then they just reuse it. In fact, yesterday I visited Mindra and Flipkart and there's a talk by the people from Flipkart who are gonna talk about this but this is a very interesting concept that's getting, so this is something that's getting picked up and I think this is where the future is and people are starting to pick up. I wouldn't say it's not, like React Native, React XP is not popular. Skype is using it and again, the JavaScript community likes drama. So, saying popular versus non-popular is, I mean if it works for you, it's popular. That's the way I would put it. One more question, sorry. So, the concept of having JavaScript call your C++ functions and everything sounds pretty much similar to WebAssembly. Is it something that React Native is aligning to? Is it something React is investing into? I mean, I can't talk to what React is doing but it's similar to what the browser is effectively. Browser does this, it only makes, this makes natural sense if you think about it. Okay, next question, anybody? Do we have questions? No? Yeah. What are some components that are being moved away from core React Native? Like, I saw that async storage is being moved away. So, the question is, what are some of the components that are getting moved out of the core? So, last half, we experimented with WebView. How many of you here use React Native WebView? And how many of you know that it's horrible, right? Like, it uses the old system and stuff. So, Facebook hasn't been able to do justice to React Native WebView. We moved WebView out and in a matter of two months, not only were they able to rewrite or like, move it to the newer versions of WK WebKit, but they were also able to accept a ton of pull requests. So, that's the basic mentality and what we are trying to do is, we are trying to move out all non-essential or all components that we think the community can handle. So, one set of components are like, components that are either iOS specific or Android specific. Snapshot iOS, Android progress bar, things like that are moving out. The second set of components, the second set of components are components that we believe the community is heavily invested in and want to pick up and run with it. Like, there are people who have expressed interest in ensuring that async storage moves faster. And there's no reason for Facebook to be blocking them. And we figured, hey, let's just move it on. That's the general philosophy. I think in general, the community has been doing an amazing job. The rate at which now people can merge pull requests is much, much faster than if it was only Facebook being the bottleneck. Any more questions? So, my question is that for, if you are a new developer, you want to start on open source and if you want to work on React Native or try to build on some of the modules which you have externalized, what are some of the tips which you would offer? So, I think that's a very good question. And it's a question that comes up often, especially in a demographic like India where people want to get involved, but there are no clear guidelines, unfortunately. So, my recommendation would be, remember the URL I showed you about discussions and proposals? Go look at that. And that actually has a call for action. It says, hey, are you interested in picking up this component? You should go pick it up. So, that's one way. The other way is, so I actually spoke with him yesterday. He's from Mintra and Mintra is doing some really good stuff with React Native. They have some amazing components and if they were to open source those components, that in itself will be a big deal. So, that's another, like, if you are a company and you think that you have built some really good components, open source them. At the minimum, there'll be this extra order of people sending you pull requests and stuff. Sure, you can choose to ignore them, but effectively, that's actually a good way to get started because remember, everything that you, like, you personally may not think that that's a big deal, but for people outside, the work that you do is actually a big deal. So, there's nothing wrong in either putting stuff that you're already doing out there or trying to see if there are any call for actions and getting involved with that. In fact, almost like two months ago, Eli, who's on the React Native team, he said on Twitter, he posted, hey, here are some first tasks. Can anyone help us?  And now they're actually starting to own bigger pieces and bigger chunks of React Native. And that's actually a pretty big progress from like in two months from doing your first PR to now managing the entire community. So that's actually another good way to do it. Watch out for the Twitter, follow me or follow like two people on React Native and we kind of ask about this or the better place is on GitHub where the discussions and proposals happen. Thanks. One last question, we have one minute. Yeah, quick question, please. Hi, my name is Pawan. So I have a question. So this new architecture, how will it affect debugging and especially I'm coming from an Android background and also debugging with multiple different packages together with React Native? Hey Pawan, that's actually a very good question. In fact, I should probably cover that but it goes a little deep. So the one thing I would want to tell you is debugging with React Native today is one of the best hacks I've ever seen. Yet it is a hack. What you do is when you start debugging in React Native, you actually run React Native code not on your device but on Chrome on a desktop. And that's because the JavaScript VM cannot be debugged directly. With this new architecture, when all calls are synchronous, you will be able to attach your debugger directly to that JavaScript virtual machine. So you know how you debug Node using Chrome because Node uses a Chrome remote debug protocol? The new debugging is going to be exactly like that. It's going to, JSE or the JavaScript VM is going to expose those methods and you'll be able to directly attach to that. Yeah, Ram. So we're... Thank you everyone and we also have a birds of feather session. If you have any questions, especially questions that are specific to your product, please come talk to us and I'm here to help you people. Thank you. So yeah, thank you, Ram. That was a good keynote. Very surprising facts there. So I have an announcement. The birds of feathers will be starting. So the sessions are on GraphQL and React Native in production. So these happen one after the other. So if you want to go there, you can go. It's on the first floor. So we have Toshi here with us who will be speaking about a React Native vegetized framework. Move fast and build things. Yeah, Toshi up to you. Guys, so I announced earlier to put your phones on silent mode, but I don't think many of you have done that because I heard few phones ringing. Please turn it off or put it on flight mode. Yeah, thank you. Hello everyone, I'm Toshi. I work with Flipkart with the cross-platform team and we use React Native and React Native Web to build pages and features which run on all the platforms, web, Android, and iOS. In my journey of building web applications using React to now working with React Native to build cross-platform applications, my team and I have come across various technologies, the challenges, and the optimizations. And here I am to put together the learnings we have had in these past years. So today I will be talking about a React Native vegetized framework which will help you to move fast and build things. I'll start by taking an example of a feature or a program that we just launched, a loyalty program, Flipkart plus membership. And I want to point out what were the changes that we had to do in the front end or the UI part of all the applications. So we had changes around the pages. We have various pages on the Flipkart application and all the platforms. Yeah. So we have various pages, the home page, the browse page, the product page. And when we launched this program, we had certain changes on all these product pages. And these changes were also across the verticals. Flipkart serves a lot of categories, hundreds of them. And we launched Flipkart grocery as well.  So yes, we had changes across these verticals and all these changes had to be replicated along all these platforms. We are on desktop, mobile web, Android and iOS. So I put this perspective in a three dimensional graph which comes out to be something like the one axis is a platform where web, iOS, Android reside. The second axis would be around the verticals that we just discussed. And the third axis is around the pages that we developed for in an application. So if I put this, a new feature in this three dimensional space, we need developers to have knowledge of these three, of these three accesses. And probably for one feature, I'll need nine developers and for some three features, I might need 27 developers. And the scale at which we operate at Flipkart or the scale at which you would be operating at your product company could be something like this. At Flipkart, we have 100 backend teams which are providing us content. And we have around 50 product managers who are ready to run experiments and change layouts. And we have around 200 UI experiments currently running on all the four platforms combined. But that's the way we operate that we have one UI team which supports all these platforms and takes care of all these humongous changes. So this needs an optimization on our end on the systems. And so let's get into the idle world which we think should be applicable here. So I need not write code multiple times in multiple platforms with the same business logic. I should be able to write once and render everywhere. Also at the times when there's high traffic, for example in Flipkart, there's big billion days we have. And there are changes that we need to do in real time. So we need a tech stack that helps us fixing issues in that particular time without waiting for any app releases whether it be Android or iOS. Also we need to be page agnostic if a developer today is developing for a browse page or for a cart page he should be able to develop for a product landing page as well. So you have to be domain agnostic at some point. Then the core UI teams when the business logic is written at one place the core UI teams get some time to work on the networking layers, the caching layers, the app size optimizations. And also having said all of this, we need not compromise on the user experience or either the developer experience. So I'll move on to the accesses one by one. The first access that I want to talk about is the platform. At Flipkart we use React Native and React Native for web to do the cross-platform application development. We have our various pages written now in React Native and React Native for