 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. Big binary who today you will sort of see Vipul and Abhay and a bunch of other people who will also be running the BOF sessions. 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. And he's got a list, well, not a list, a bunch of tips and tricks, and a computerized voice. 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. And then a lot of people, Google, kind of shit on it and said, no, it's so big, the bundle size is large. 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? Like if you do something stupid, then something stupid should happen, which is you don't know which one will win. 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? There are a bunch of people who would want to use a keyboard, 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. And again, how avatars usually go is like you have a bunch of them. So we had this user avatar and we had a resource or application avatar. So we put the Firebase logo there and you usually see avatars in a bunch of places, right? So this is from GitHub. This is like a super big one and there's like a tiny one and this tiny one. So you usually have a bunch of sizes. 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. And we actually needed a bunch of them. 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. So there are a bunch of cases where you want to enforce the consistency that you're not allowed to modify. 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. You click it and you go inside it, right? 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 like a bunch of things. 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? They'll have a pull request, you made some changes, they're gonna back merge, they're gonna complain about it. If you work on a library, you're gonna make breaking changes, the users are gonna be mad. 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? What the end user, what is the user trying to achieve? 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. It's a little scary to get up and talk in front of all your peers, but don't let that stop you. 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 were sort of stuck in a loop and I mean, so let's talk about an example. 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. And our commit messages weren't doing enough. 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. It gets dirty again and I clean it again. 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. And if you decide to filter this timeline, you'll see all the features, other features that it gives you. 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. Don't overlap your background colors wherever you, you know, can do that. 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? You go to your developer options, you select debug GP overdraw and you say show overdraw areas. 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. Now, of course, inputs are a little tricky with React because inputs are controlled components. 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? Now, I know what most of you are thinking, hey, hooks are out for almost six months. 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. In fact, both an Android and an iOS, your layout components are a part of your component tree. 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. So they actually become a part of your component tree. 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. So what's gonna happen is, as soon as your application is loaded, your mobile phone is gonna say, hey, I'm ready, let's go draw something. 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. Everyone here knows what a native module is? 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. And again, remember, because this whole thing is a synchronous call, JavaScript will be able to directly call into native Java or native iOS methods. 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. I mean, look around you. 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. If you look at the way React Native is effectively structured today, there are a bunch of view managers, there are a bunch of native modules which run using a singular React instance layer on which there is a JavaScript VM and this is where React JS and your product code work. 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 all of those tasks were picked up by people who have never ever contributed to React Native. 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 if you are a plus member, you will have various delivery charges exempted. 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 web. So React Native provides us with one feature to be running on one feature or one page or component running on all three platforms. And we have the native fields intact. Since React Native tweaks the native elements of the respective platforms, we have the native fields of the user experience intact there. And also we have capabilities to fix issues in real time with over the year updates. And we have our own in-house dynamic update system for that. And also those who are not familiar with React Native for web, these are the abstractions written over web API which helps you use React Native components and APIs using React DOM. So many companies are today using React Native and React Native for web for writing their application. But what we did extra here was building our own abstraction layer or own kit which is called the cross-platform kit. Our aim is to write components inside that kit which abstracts the user or a developer from the implementations and these components are guaranteed to run on all three platforms. So I'll take an example. These are the three pages which have a similar component or a reusable component which is like a sticky footer here. And we have three pages and this sticky footer capability is added to the React Native Recycler List View which we have open sourced. And now you as a developer can directly access it, write your code over it and you did not know how this part was actually implemented. So there are several other components that we have incorporated in the cross-platform kit. And this is how we want to move on with the cross-platform development from now on. So the current state of this dimensional graph we just eliminated the access by writing one code which runs on all the three platforms. Now the next access I want to talk about is the page-specific development. The problem statement I feel here is how a developer develops for different custom layouts. For example, you are on a product landing page which looks a bit different and then you are on the payments page which looks a lot different. So you as a developer should not be restricted to okay, today you cannot build that page because you don't have that domain knowledge. So we took a very standard approach here of digitizing our page. We have now divided our page into basic building blocks which are horizontally and vertically scrolling which we call widgets. Also these are reusable and extensible across all pages and it was easy to add and update the number of widgets that are entering on a page. But what makes this framework a rich multi-digit framework? So for example, these are two pages, page X and page Y and these are the widgets that are entering in horizontal or a staggered layout whichever way you want. It might have a header and footer to this page, custom to this page. So we have a custom header and footer support. You can reuse these components or these widgets across and you can add new ones. Also we support inter-widget interaction here and to optimize the payload on the wire, we also give time to live to these widgets as well as the page. So the problem statement what I want to address here is if you are a product manager or a backend developer or stakeholder for that particular page and you want some UI changes or want to run some experiments, I want that you should be able to go to a configurable console, change the way the page you want to look, want the page to look and the UI should change without any UI developer intervention. So let's see how on a high level it looks like. So these are the data providers for the backend systems. We have, I'm taking example of Flipkart, data providers that we have and this is the data flowing to the content aggregator service. This is the place where all the data from different backend systems would be aggregated and you have a layout console which connects to the aggregator service and this is the layout console, this one, where your product manager would actually go and make the changes. And as soon as the changes are made, the data in the form of the widgets or the building blocks flow to the front end systems and gets reflected. So ideally you are not making any UI engineer interventions here or deployments here and the changes get reflected in the front end systems. So now the state of the graph comes out to be one vertical axis and this particular axis is subjected to your product. It might or might not exist. For us it does and we're still in the process of solving this and this still exists for us. So the slide that we just saw that where we want to be the ideal world, let's see with the concept of cross-platform using React Native and React Native for web and using digitization, where are we? So we are one feature, one code on all platforms by the use of React Native and the cross-platform kit that we have built in-house which you today should also build at your end. We are solving this problem of replication of code. Also, by the dynamic update system that we have in-house and the over-the-air updates capabilities of React Native, we are able to fix issues in real-time. Also, by the concept of digitization, we now view the page in form of components. It's no more a design. It's more about components, how the API power these components if it's in the order of 1, 2, 3, 4, 5 or it's in the order of 5, 6, 7. So whatever API gives me, I render that. And I am page agnostic as we discussed. I also pointed this that we have enabled different stakeholders to make the changes now. The UI is not completely dependent on any UI deployment there. We are still in the process of onboarding more and more pages in React Native. Flipkart is a hybrid application right now. And we need our core UI teams to work on different app-size optimizations and network layers. We have definitely improved developer efficiency. We are like 75% efficient now. It takes a lot less time to develop pages when we have digitization and when we write one code. And having said all of this, React Native and React Native for Web allows us to build even the beautiful animations that we have today. For example, if you see Flipkart's gaming platform, you will see we have done a ton of animations even on web. So these are a few pages that we have on Flipkart today and there are more of them. You can just go and have a look. And what are the challenges ahead here for us? We're still trying to close the gap between the native and the React Native components. The React Native library, as Parshuram said, that we are still in the process of, we need contributions from the community. And bundle size splitting and reductions as more and more pages are getting onboarded on React Native. The bundle size is increasing and that increases the JS passing time. And we need stability on certain devices. We are still to be browser compatible. So these are some open source tools you can look at which we have open sourced in Flipkart and it's an appeal to the front end community to build cross-platform tools and share all amongst us. Thank you very much. Yeah, Q and A, questions please. So do we have questions? Yeah, sir, can you please turn on the mic? Hi, my name is Ajit and I want to know how you fix the real time issues especially for the Android application like in case of the big billion day and all that. Yeah, so well, since I told you we're a hybrid application but the parts that are written on React Native we use our dynamic update system that we have made in-house and we can just update the bundle there but in case where the parts are native we will have to wait for Android releases but that's not a very big chunk. Yeah, any more questions? Yeah, so that... You mentioned that you've not yet solved the products part of the thing. What is the challenge in that segment if I may ask? So I talked about the verticals. For example, I'll take example of a vertical which is grocery and so if some changes come on that particular vertical the people or the developers who have that domain knowledge of their work that with vertical grocery they will have to make the changes. We're still not there that okay, a grocery product manager can go and make those changes and just render it there. So I think if it's electronics, if it is a different category like footwear that might be different UIs that might be needed. Okay, so yeah. Rana, can you hand over the mic? Hi, my name is Satish, very good session. So I have a question that your widgets, right? So you're planning to use them maybe substituting them in different pages. So what are the benchmarks that you follow for creating these widgets? Because say for example, a widget is taking say 500 milliseconds or something to load. It might be okay for a thank you page or something like that but it might not be okay for a search page or something, right? So we make the widgets customizable that way. Sometimes we do give height and width from the backend the data that comes for the widgets. It will have the margin, the height or sometimes the color as well. We might tweak the basic UI part from the backend in terms of color, height, size or if it has to stick to bottom, if it has to stick to the top. We do keep these contracts intact in the data part. And how dynamic are these changes? Because say for example, I'm trying to evaluate the performance of a page and you are repeatedly changing widgets around this. So obviously every widget would have a different rendering time, right? So how do you track those things and how do you make sure that things work well? So my main point to know here is like what are your benchmarks for creating a widget? Because there has to be a standard to work across different pages. Yes, definitely. We do have those benchmarks. For example, a widget will have its own TTL. I just mentioned it here as well that as you're talking about optimization, we might have a TTL for that widget. If the data for that widget is expired, then only we'll render it again. Otherwise it won't come up on the payload at all. And if the particular widget has not expired and it still can be reused with the same color or maybe the same image for that matter, we just send, we don't send the data over the payload. So that optimizations that you're talking about has been taken care. But yes, the benchmarks vary from widget to widget. And as I told, a widget will consist of the actions or the behavior. The data, that means the data that has to be displayed in the widget and the tracking that we have to do with that widget. So these three are the standards that always come with the widget. And according to your use case, you can always have those optimized whatever are the requirements. Thank you. Yeah, that's it. Thank you, Doshi. Yeah. So guys, do you know one thing? There's an option called silent mode in your phone. So somebody's phone is ringing all the time. I don't know who is it? So if you don't know how to put your phone on silent, please come and ask me. I'll do it for you. Yeah. Okay. To speak. Cool. So Xavier will be talking about kickstarting a library of internal React components for multiple teams. Yeah, Xavier, up to you. And this? Closer, yeah. So, hi everybody. So I'm gonna talk about how we, for the past year, created several libraries of shared components for our clients I've been working on. I'm working with. First, let me introduce myself. So, hi, I'm Xavier Lefebvre. I'm French, I live in Paris. I'm a team leader on React and React Native projects for a company called BAM, indeed. It's overall, it's a consulting and development agency. We work for any type of companies to accompany them to build some successful products. And so, as any of you in this room, I do love tech as much as I love traveling. So being there with you today is quite nice. It's like quite an amazing opportunity to go to India. And like that. Good. You're less gonna hear the breathing. Now it's good. Like that. You hear me well? Yeah? No, no. Thank you. And I do also love, among other things, motorcycles. But why do I put motorcycles here? Because I have this little image of a motorcycle and all its components. And it made me think of that. What we're doing is a little bit of that because it's like many different components with different sizes, with different responsibilities and scope that we need to assemble together to make a website or to make several websites. And depending on the motorcycle, some components can be reused on other websites. So what I'm gonna talk about. I'm gonna talk about why we started this project of shared components and how we tried to tackle this topic. Then I'm gonna deep dive in some of our design decisions that helped us make this a success. And at the end I'm gonna tell you, it's a little bit of a business part. I'm gonna tell you how we consider that we're making it a success and how we organize ourselves to tackle the issues that other teams or our team meet while developing on this project. So it started from a wish last year. Our client, which is a big bank, said it would be awesome if we could finally and successfully, because we already tried, create shareable components in order to read them on different apps, give them to other departments or even one day potentially, sell them outside. We didn't reach this place yet. We're still at, we're approaching give them to other departments. So why did they say that? It's been a long time we worked with this client and we developed a lot of different websites. Over the past seven years. And it happened quite some time that we redeveloped the same kind of features. Slightly different, but in the business of the bank is always the same behind. And so some features can be accessed, could be reused and are reused effectively on websites which have a different user target. So let's see a little bit what I mean by that. So that's an example, okay. That's an example of one of those features. It's a full page feature. It's called a fan sheet. A fan being like a source of money that's used to be invested. And it's part of life insurance, for instance. And this specific feature, it's a full detail of the fan. So it can be interesting and it is interesting for B2B, for internal purposes or B2C. And this fan sheet has been, for instance, remade several times for different websites. So our first attempt, which was named Commando. So the setup is, a team is working on one website, another team is working on another, but they have to share a component. There is something there that they could reuse. So what we did is we created out of the blue like that a command code base, which was called Commando, and both teams were contributing. From that, we output a simple, huge JS bundle that was served directly as a script. So which was directly downloaded by the website. Problem was that the code base was growing without specific architecture. And so a lot of components I really didn't find, didn't follow the same syntax as the same architecture. The JS bundle was huge, same, just one for every purpose. And in the end, at this time, there was no versioning strategy. So if you had, if you pushed a new version with breaking changes, you could be pretty sure it would break your website. So after that, of course we didn't work out, we ditched it. After that, a second project was called Tapas, which is, I don't know if you know about Tapas, which is like a little Chinese dish food that's meant to be shared. And so same setup at the beginning, but this time one team started to own the project. So they were the one taking care of its architecture and its improvement. Or the other team, for instance, team two or more, were contributing to the project directly. Then this time we versioned, of course, our JS bundle on GitHub directly, and we packaged them. So they could bring it directly into their code base before bundling their final website. It still had some issues. First issue is once again, the first team, the team one, but first and main objective was to take care of its own website. So they didn't really think enough in terms of reusability and they didn't really have this focus. Second one being that once again, it was a big JS bundle. So any type of components, even if you didn't use, need them, you had to bring them into your final bundle. And last one is that the versioning system was on GitHub. So you needed a GitHub account to be accessed to our private GitHub team to be able to access them. So it was clearly not perfect. And there is solutions for all of that, but we didn't at this time try to use them properly. So last attempt, last year, at the moment where our client said the quote I told you, we launched this project which is called Component Studio. Same setup at the beginning. So this time with a specific core team, like you would have for any open source project. And other team contributing. After that, we created and split architecture in several libraries and same at the end, we packaged it in order to be reused on the host projects on the websites. But this time, for each of the solutions, we for you for managing several libraries into one repository, we use Lerna, which you might know, which is a mono repository manager. And for giving our packages to our users, we used Verdatio, which is a private NPM open source. And this made a big, big difference. Thanks to this, we can say, and I'm gonna give you a proof at the end that it works. So that's a demonstration of what we have right now in our project of reusable components. It's, we use Storybook. It's our basis of development of validation and it's our showcase as well. Everything is accessible from there. So a developer, when he's gonna develop, he's gonna develop thinking, even though he is from another team and he needs to contribute, he's gonna develop thinking about reusability because he's gonna develop directly inside of Storybook, apart from his own project. Storybook is extremely convenient in order to play around with your components. You have the knobs, so it's a props of your component. You can play around with them and see the impact it has in live. And it's also used for our own product owners to validate and to show what the capability and what the components are available in our project. So let's dive in for some tips of what we think made the difference. So if we come back to this part of the diagram, first I want to dive in a little bit into how we organize our packages and components. Then let's dive in a little bit more into our code structure of each of those components. And finally, how we limit the impact of breaking changes because it's a project for instance, there is six other teams working with us on a daily basis and pulling requests of changes on the code base. So we are not capable as a core team to check all of them. The thing is that we want to be agile and go fast. And so we had to set up an automated process, a strong process with formation to make it work well. So first, how we cut down our packages and components. We follow our atomic design. So I don't know if you know about the atomic design principles. It's Brad Ford who created those principles and it explains you how to cut your UI components in a hierarchy. So the biggest one, I'm starting to start by the biggest one. It's called, in our case, we used the organism as the biggest one, which is almost a full feature, a full page feature. Then inside you have the molecules. A molecule can be composed in order to make an organism, of course. And then you have the atom, which is a simple UI component. So let me come back to that. The impact it has on our code organization. So UI, as I just told you, as you've seen before, it's an atom. It's pure UI, there is no business in it. So this is the part you would expect in a design system like material UI for instance. It's completely customizable and composable. Then what comes next? We called it widgets. It's business connected directly this time. It still has a pretty small shape and it's composable when it shares a common business purpose. So for instance, I was talking about fans. Fans, it's a specific business data. So all the widgets about fans can be composed together to make a bigger product. And at the end, you have the organisms. For instance, the fan sheet I told you, or chatbot. So that's the advantage. And there are full page features and they do satisfy by themselves a user need. So a fan sheet is a composition of widgets. But we also, for instance, have a chatbot. And this chatbot needs to answer some questions about fans. So directly, the chatbot is gonna retrieve those widgets and display them as it would have done it with a fan sheet. Let's take a deeper look at the code now of each of those parts. So that's impossible to read. So let's go a little bit in it. At the bottom, so you have the UI. UI is pretty simple. There is not a lot to say about that. You have a component, you have its style. So it's not connected, so you don't have much more. And we do have a theme setup and feature. I'm not gonna talk about it now because I'm not gonna have the time, but I would love to talk about that later if you're interested. After that, so you have our widget. Our widget on the right of it, you see, it's called components. So this is the UI place. This is where you have your JSX. It's a composition of UI components, mainly, that's being fed with data from a container, which is classical. The container is gonna fetch its data from a service that we created in order to optimize the composition of widgets at the organism level. And it's using what we call a modelizer, which is an adapter of the data that comes from the back in order to just clean it and to have calculated the variables if necessary. So this widget, we export it in three ways. As a standalone, so you just take it, you put it inside of your website. Even if you don't have React, it can work and it displays the data. It fetches it, it closes it, of course, and it displays it without using it. And we export it in two separate pieces as well as a dump component without any data and the data fetching service by itself for you to be able to recompose it from the top. So for instance, the French hit, an organism, is composed on the right side, as you can see, with the purple of widgets and of UI components. On the left part, because our stack, our stack of our website is made of Redux, we decided directly inside of those organisms to put Redux. So in order for the host projects to be able to embed the store of this product in case, for example, inside of their own, to do optimization, not have to call twice the same data, or reuse it somewhere else in the application if the data is already available. And this Redux store is using our fetch widget data service to be able to get the data that is necessary for the widgets you're using. So now I wanted to dive a little bit into breaking changes because it's an interesting topic and even more for us that any team member, any outside team member can do a request, merge its code in its own with its own team directly. So there is a risk of high risk of breaking changes because if they change something that another team is working on and without communication, it can be problematic. So breaking change just for reminder is a change in one part of a software system that causes other parts to fail, which happens when you change the existing API of libraries without one user, of course, even more. What should I pay attention to? So for instance, we expose components, we expose some functions, but mainly we expose components. So the signature of your components, if you change it, if you delete some, some parts, some props, for sure you're gonna have issues. So the exposed components and function names are their props or the function parameters. That's part of the potential breaking changes you could make. The component style as well. So it's the style by itself. So I don't know if you change a color or a font. It is somehow a soft breaking change because it's still gonna have an impact for the end user. It's not gonna break your site, but at least if you change a font, it might be real. But beyond that, the space it takes in terms of height, width or margin is might, for instance, in this case, might break a website. So this is part as well on the little things we need to pay attention to when we talk about breaking changes. And last part, when we break the peer dependency, which has a breaking change, for sure the whole project we'll have, normally we'll have to update this peer dependency, but we'll have to pay attention to the same breaking changes. So you need to warn them. The example here being, for instance, style components. We do use style components to develop, to take care of the style of our components. And it's a peer dependency because you can only have one version running on your code. So if they push a new version with breaking changes, we will have to make sure that our host projects use the same version and fix the same problem with the same type of breaking changes. What we set up to help developers anticipate? We use Flow. It could work with TypeScript in our whole code. And we expose, in the same way as Flow typed, our API with Flow types connected directly. That's a nice advantage because Flow typed is really, is disconnected completely to the base project it's supposed to type. We provide directly the types with our libraries. So they're connected directly. So if a developer changes the signature of a component, changes its props, it's gonna break in his ID because he's not gonna have changed the exposed Flow API. So then it's gonna break, he's gonna need to change it. He doesn't have a choice. The CI will be read. He's gonna adapt his Flow type API. And if he didn't pay attention, his pull request will directly, thanks to dangers that runs in the CI, tell him that he changed a Flow API file and that it might mean breaking change. So he needs to pay attention. And it did help us in some cases to anticipate breaking changes. There is also an automatic semantic versioning system based on the commits, like was mentioned a little bit earlier in another talk. And so when the developer knows he's making a breaking change, he's capable of seeing it directly at the commit level and it's gonna create a major directly. So people know that if there is a major to bump, there is potentially a breaking change. And thanks to that, at the same time, there is an automatic change log generation with all the details directly coming from the commits, using commitism. So how do we know that such a project is successful? The little business part, I think is interesting for all of us because even as tech people, we need to be able to potentially find a way on the speech to convince business managers to do such kind of projects. So our return investment formula is quite simple. It's for sure, improvable. It's the same for all components we expose. Of the cost, it would have, if it was redone on a normal project, times the number of times this component has been reused. And to this, we subtract our project by itself, full cost, our team, but even the time that the contributors spend to contribute. So as a tech team, our main focus is on the right part. It's not on the left part. The left part is the sales part. It's the fact that you find people to reuse your components. It's mainly on the right part. It's to reduce the project cost, meaning that it needs to be faster and easier and more robust to develop on this website with as few bugs as possible. But we did not arrive to this point after a year without struggling. So what we did, we started tracking the issues, like the issues you would have on a GitHub repository. That's a pretty complex graph of our issues. So at the bottom of the bar, you can see that all the issues, it's orange plus red, all the issues that were made, for instance, by the other teams that they wanted to share with us. And on the blue, it's a contribution. So it's activity on the repository. It's to see if there is correlation between the number of issues and the activity we have. So there is a correlation, for sure. We can see that at the middle, on the number four, we did, before that, set up enough actions and positive tools and improvements on our code base to have a flat number of issues, even though the activity was a little bit increasing at that time. Why did it increase three times? We discovered lately that it was mainly because there was a lot of turnover, because we're an agency, so there was a lot of turnover in the developers. And each time that there is an increase in issue, it's mainly because there were new developers coming on our project and they didn't know all our flow and how it worked because it was on track. We then prioritized based on the type of issue. So if it's a bug, it's more important than if a developer just was blocked for five minutes and the developers lost time. So thanks to this prioritization, we are capable of then tackling the most important ones every day and going into the depths of each issue and to their root causes to understand exactly what in the flow which can be the training of the developer. It can be that potentially it's missing a little tool to prevent him from doing a mistake to do. And then every week, we took weekly actions to make sure that in our development flow normal, we to make sure that those biggest root causes, as we call them, wouldn't come back. So this is an example of our diagram, of our graph of main root causes. And the top one, for instance, lately, is we have a lot of issues with Yarnlink. It's like, I don't know if you know Yarnlink. You connect your own library to a host project to see directly the impact it has live on your host project. So it's useful if you want, for instance, so you're developing a website and you're using a library, but something doesn't work well or you want to improve it and see the impact it has on your website, you use Yarnlink. So is it worth it to do such a project? We consider, thanks to the little formula you saw before, that we saved 18% of development cost for those projects since almost a year ago. So for us, this alone is enough to tell us that it's worth it and we're gonna continue. And a second side effect that rise naturally was the fact that it created a consistent UI design across all the platforms. That was not always the case because each team was separate. You don't really, enough talk to each other and organize themselves well to have a consistent UI. Now that they shared a common base of components, of any size of components, the UX team at the same time had to start synchronizing themselves even more. So for us, it is a success and we're gonna continue in the coming year. So that's it, that's it for me. And I wanted to thank the people that worked on this project because it's not, I wouldn't be here if we didn't do that all together. Yeah. Yeah, we have one here. Micronus? So I wanted to know how you guys are managing the versions of the component for the library. So suppose team A, suppose you have a component in the library, tap component, which is an internal component. And team A is using version 0.5. And there are some bugs and something like that in that component, you fixed it and you expose the new version or whatever. So are you asking all other teams to upgrade their components in their project based or what, how you guys are managing that? Yeah, for the moment, it's like, it's really an internal company project. So all the teams, we're not that far from each other. So we do have WhatsApp chats and we do give news when something is changing, but we're not obliging anyone, no one to upgrade. They do as they wish, like they would for a normal library. So we trust them in making the right decision based on what we changed and what we improved if they see the value in it because they have to prioritize their own development roadmap as well. Okay, so on second question, when you ask your other teams or other products, let's say, application team A or two, what you say, so you guys are exposing it through some Git directory or you are creating an NPM bundle for that? Or, okay, so you guys are creating NPM bundle. I didn't want to put this. Yeah, this one is huge. But yeah, we do, is it, is it, is it? Yeah, on the right side, you can see the little bits, it's Verdatio, so Verdatio, it's a private NPM. So it means that we, each package is pushed on this Verdatio, it's really like NPM. And then the other teams, when I need to take the latest update, they do a Yarn, Yarn add the name of the thing with the right number, the right version. Hi, so when I'm writing my code as components, I always get confused about, for example, if I have a component that takes some text and renders it with a box shadow and with some font color and all those things. I'm always confused about how much customizability should I expose on props for that component. Should the box shadow be also customizable, how much of the styling should be customizable. So how do you guys look at this problem of when you build components, how much is inherent to the component and how much can be customized using props. Okay, what do I have there? I don't know, I didn't put it there. I was expecting a diagram I don't have. How we do that? So there is those three layers, there is UI. So we call it UI, which are the atoms. There is a molecule and then there is organisms. For the atoms, we consider that. So first, of course, they are already compliant with the UI design of the company at first. So most of the time, I see it's gonna be enough for the other projects. But then as a really simple component, we allow full customizability of the component by itself for the other teams. They can do whatever they want with it. We expose most of the style. We use a specific themes system we did by ourselves with style components. Then at a higher level, when you go through the molecules and the organisms, here is different for instance, because it would be too customizable and too complex and too crazy after to anticipate some breaking changes. So here we do a lot of some stuff, but based on what was really necessary, based on the questions that those teams asked us in terms of improvements they wanted to make in the style. So it's mainly like color of text or font and sizes of the components, for instance. And it doesn't go further than that. We want to set the style. At the same time, as I told you, it does set the UIX for all of those projects and it's a good thing. One second, please. Please do not leave the auditorium till the QA is done because we have a few announcements to be done. All right? Yeah, next question, please. Hello? Yeah. Thanks for the presentation. It was a nice one. So how do you tackle the inter- these components communication that you guys are doing? What's the strategy that you guys followed for that? The communication between... These components when they communicate or if there is a communication happening between these components. Yeah. So here, here for instance. So the fun sheets, so that's the little thing I didn't explain here because it would have taken more time. The fun sheet is made of widgets, of different widgets that are supposed to be connected indeed. And how our backend is done is that it's one route, one huge route, that gives all the necessary data to create a fun sheet. So of course here, you wouldn't want to have to, if you call 10 widgets, you wouldn't want to make 10 calls to the same route. So that's why we created, and it's pretty raw and straightforward, created a full service with all the widgets that compose a fun sheet in it. And for in this service, when you reuse it, you call it and you give it the name of the widgets you're composing with, okay? And it's gonna, for you, make the call with the right parameters. And there is several routes, there is four routes in total, there is some other stuff I didn't mention. And it's gonna, you're not gonna have to think about that. It's gonna put this all the data properly with the modellizers that I told you, so the adapters for each widget. Inside of an output object with the name of the widget and the data it needs to get to properly get displayed. And then you just have to reduce the connection. So you don't care at all, yourself at least, about how it works inside. But then if you want to create a new widget, it's another problem and it's way more complicated because it's like a big function with a lot of if-else. Yeah, next question. Anand here. So of course a nice presentation and we asked about the versioning and all, right? So someone asked from there about versioning. So it's like you are managing Monodepo and how you are actually building these components because you are having atomic molecules and organism, right? So you might have different build process for these components and how extensibility is working for these components. You think that they might have different build process? I'm talking about like what build process approach you have taken for these components. And suppose I need to tweak a bit of, you know, the... So for example, I take an atomic component and I want to write something on top of that, right? Which might not be the part of that repo, like atomic component, but I want something to be changed. So how extension is going to work for those components where I'm trying to use it. So I don't know if I'm going to answer the right question. You tell me. I think you put it there. Did I? Did I not? I did. So we have a... It's a tree, I'm sorry, you cannot see it well. I'm going to tell you. It's a decision tree that we give to all the peers, the product owners and the developers, for them to be able to make the right decision before making any change inside of the project. And the first step is to make sure that the change they want to make can be a change on something that already exists or it can be a new feature. It has... They have to prove that it's going to be reused by another team. If they make a change directly to a component that's not going to be reused, we tell them to customize it directly or extend it directly on their own project first. If they do prove that, then they need to make sure that the UX UI is compliant and validate it with the UX UI once again. So for this whole UX UI, working together well. And then last step, it's a technical step and we do a workshop with them. It depends on the complexity of one hour to hours to understand where we're going to fit this feature on architecture to put it at the right place. All right, so and what about the server-side rendering, like how you guys are managing? We didn't for the moment. It's pure SPA. It's a good question, but we didn't tackle that yet. Yeah, next question. Mentioned a tool that you use in production for monitoring. I was unable to catch the name of that tool. Can you talk more about that? A tool for... What was it? It's for monitoring your production issues. Yeah, issues. You use a tool. We use a handmade tool with Google spreadsheets and Google scripts. And it's working pretty well. So all the issues that are shared on it, we use Trello a lot. Trello boards, a lot. Our development process is on Trello board, and it's specific from my company. Our solving process, issue-solving process, is also on Trello, on another board. So when a team has an issue, they create a card with a specific template inside of the Trello board at the beginning of the flow of resolution. And we connected directly Google script to the API of Trello to be able to get the right data and to show it this way. Yeah, any more questions? Thank you. Those were some really good tips and atomic design principles. That was really good. All right, so how many of you folks are going shopping this weekend? Hands up. Okay, so we... All right, and those who bought ReactFu t-shirts collected from the counter at the registration desk. Then the event hashtag is hashtag ReactFu. So if you're posting on social media, please use the hashtag ReactFu and post your photos or whatever you're posting. The next thing is flash talk session is from 3.5 to 3.25 p.m. So we had four slots. Now we have three slots for five minutes of presentations. So flash talks are five minutes each. You can talk about anything, but you're not supposed to pitch your product. Your products are do hiring over here. So any site projects, open source projects, something like that. I got an idea today for an open source project. So in a hall full of auditorium with people with mobile phones, if they're connected to the network, just turn their phones on silent mode. So you can build that with React. All right, I want to do flash talk. Please write the topic with your name and phone number on a slip of paper and hand it over to me, Herschel or Todd. So that's me, Herschel, yeah, Herschel's there. Or Todd, Todd was here. All right. Yeah, selected speakers will be informed during lunchtime. So whoever gets selected, you can come and give the flash talks. All right. And one more thing is just before the lunch, there will be two BOF sessions. And after lunch in the BOF area and room one. So volunteers will assure you over there. Yeah, so that's it. Please go and have your lunch and please come back again. We'll have a great session. Thank you. Hello everybody. I hope you had a good lunch. Let's settle back in. So there's some announcements. There are two tracks of BOF sessions going on upstairs in the BOF area and there's one more going on in room one. If you go upstairs, there'll be volunteers to guide you. There is also an impromptu BOF happening on building AR and VR applications. So if you're interested in that, AR and VR applications with React, obviously. So if you're interested in that, that'll be from 4pm onwards. And again, I want to remind you guys that I saw some of you guys bringing in food and beverages. The venues strictly prohibits that, so please cooperate. Up next, let's welcome Vivek Nayar from Trusting Social. Hello everyone. Am I audible to everyone? Perfect. Everyone's back from lunch. I hope you guys are not sleepy as such. But even if you are, you'll just avoid some of the mistakes that I might just make. But I'm just very happy to see such a huge number coming up for the conference. Everyone, including the speakers, organizers are, everyone is really happy to see you all in this huge numbers coming up here. And I'm really honored to be speaking for React 2. Slightly up. Okay, perfect. All right, so the topic that I'm gonna talk about is a very fancy background and a very fancy topic as it looks like the magical land of ASTs and with baby Lea Slinton code mods. The purpose of this name was when I initially started coding in React or let's say any framework or JavaScript as such, Babel, ESLint, and these things looked really magical to me. Things were getting auto corrected. Prettier was auto indenting my code. And really, I didn't have to do much here because this was all magically happening behind the scene. Async await was working, even though it wasn't supported in some browsers. Internet Explorer was working well with even Async await and promises. So these things were all happening behind the scene with me being completely unaware of how Babel is doing all of these. So that was really magical for me how these things were happening. And the purpose of this talk here is to reveal that it's not that magical. And ASTs, as the name suggests, sounds really complicated at the beginning that you need to understand how machines work or how bits and bytes work. It's not as complicated as it looks like. And hopefully once the stock is over, once the entire conference is over, when you go out of this room, you will all understand how to create Babel plugins, understand how to create ESLint plugins and be better in writing your code, writing better optimizations, writing better organization-wide linting rules. And you probably will no longer require to do a find and replace into your entire application as something changes. You would probably use a code mod to do a large scale refactor on your code base. So that's what the purpose of this talk that it will open a new wide spectrum of possibilities for you. You can obviously do a lot of open source contributions if you learn how to write Babel plugins. You can write ESLint plugins for your organization. So a lot of opportunities that will become available if I'm able to convey the message of this talk and be able to help you understand how easy it is to create these plugins. So how many of you here have actually created Babel plugins or have worked on any sort of AST parsers or ESLint plugins? Is there anyone who's created one? Oh, so there's one I can see and okay, two here, perfect. So, three over there, right, perfect. So then for the rest of you, I think this is gonna be a really interesting session and I hope you learn something out of it. And that's what the objective is. I'll quickly go through the introduction part. My name is Vivek Nayar and I work for a company called Trusting Social. We are a fintech organization working for doing credit scoring and producing products. And if after the talk, there are any other questions which are unanswered. We have a BOF session as well, which is specifically targeted to Babel plugins, ESLint and code mods. But even then, if there are certain questions which are not able to ask here or in BOF, that's the Twitter handle where you can ping me and it will be, I'll be happy to chat on any plugins that you create. I'll be happy to contribute to them. And there are certain plugins that I have created then you can obviously do your open source contributions to them. So that's the Twitter handle you can follow me. And if there are any questions that are unanswered, that's the place to find me. So an interesting question that immediately comes up is I've been talking a lot about ASTs. I've been talking that everything with Babel, ESLint and code mods revolve around something called as an AST. But what is an AST? How do you explain it to anyone in very layman terms? What is an AST? So abstract syntax tree, a very simple thing. But if you see here, I've written a very simple code snippet which says const A equal to three and A plus five. So the very first line says it's a variable declaration that I'm doing and then I'm assigning it to a value which is a numeric value which is three over here. And then in the next operation, what I'm doing is I'm doing an addition operation. So it's A plus five. So it's a very simple thing that I'm writing in my VS code or any editor. There's an assignment and then there's an addition that's happening. But this is what you write you and me write in our editors. But this is what the computer gets to see. So if you see, this is a JSON representation of what an AST tree might look like. So some of the keys have been removed to help you better understand what are the important points in it. But the main thing to focus here is the type declarations that you see. So every plugin that you create with ASTs have certain AST nodes, AST types associated with them. So in our example, we had const A equal to five. So that was a variable declaration, which is why you see the very first is type variable declaration. So that is the first AST node that we created. Now, variable declarations can be many. It can be const A comma B comma C. So which is why this const is a variable declaration. And then you have a key called as declarations, which is an array of variables that you have declared. And all those have a type called as variable declarator. So these types are associated with everything that you write in your code, be it a variable declarator, be it an assignment expression, or you write a sink await, which is an await expression. They all have certain types associated with them. So here, we see we had declared a variable called as A. So there's an ID with the name A here. And then we had assigned it to a value, which is five, which is a number. That is why it has a type called as numeric literal. It could have been a string. In that case, the type would have been a string literal. And then finally our variable had a type called as constant. So that is why the kind is const here. It could be let or where. So this is a very simple representation of what the computer gets to see when it parses your code into an AST. And this is a flow chart of how things work. Every Babel plugin, when you write a Babel plugin using Babylon as the parser, it always starts with a root node, which is program. In our example, we had a variable declaration. So you see a blue box with variable declaration written in it. Then we had two declarations, which was A and assigning it to a value called as three. So you see two nodes on the left side of the tree. One is an identifier A and the other was a numeric literal three. And then we did an addition operation, which is an expression statement. And because it's two things involved in that operation, A plus three or A plus five, it's a binary operation, which has a left side to it and a right side. The left side was an identifier A and the right side was a value, which is a numeric literal five. And then there's an operator, which is plus. So this is how your AST tree actually looks like when you, in terms of the flow diagram, this is how it looks like when your code is actually parsed. And whenever you're creating Babel plugins, if at all you can do this diagram on your paper, it will help you better understand writing Babel plugins. So be it Babel plugin, be it ESLint or be it code mod or be it any Java compiler or a Scala compiler or anything, all these compilers follow three important steps. One being take the code which you and me understand and parse it into an AST, which is an abstract syntax tree. Then you want to do certain transformations to it. For example, I want, maybe want to remove certain notes from it. Let's say I've written a code which has debuggers in it. And I do not want those debuggers statements to make it to production. So this is the step where I'll remove those debuggers statements. So you can either add, edit, delete your notes of one AST and transform it into another AST. So this is the second step of any compiler. And the third step is finally you have transformed one AST to another AST. Now it's important for you to convert it to back to a code which you and me understand. So the final step is generate the code from the new AST that is generated. So three important steps, parse, transform and generate. You write Java, you write Scala, you write Gola, you write whatever language you have, these stages remain the same. So the same thing to better understand things. You write a code like this, you parse it. There's a tree that's created. You see three blocks over there. One is a green node, the other is a blue, then is a red node. I do a transformation on it and I'm swapping the red and the blue node. So this is a new tree that got created. And finally with generate step, my code is getting generated with the new AST tree. So this is basically, I'm repeating these three steps because this is the building block of any plugin that we're gonna create today. Parse, transform and generate. And precisely the talk would focus on the basics of AST. It is gonna talk about how do you create Babel plugins. It is gonna talk about why ESLint and why not other linters which are available. And we'll be doing a lot of live coding. I'll be coding few Babel plugins, few ESLint plugins and at the end, code a production ready code mod for react applications. So that is how the talk is structured. What we are not gonna focus about is we are not gonna go deep dive into how lexical scoping works or how tokenizing works. That is the topic of discussion for some other talk. So some of the production ready plugins which I use in my applications and probably some of you might also be using, one of them is Babel plugin, Lodash. Majority of the time when we see our final bundle that get generated, it's usually bloated because it's either moment JS, which is taking a lot of time or it's either Lodash, which is occupied a lot of space for us. And it usually happens because you're importing the entire Lodash library or you're importing entire underscore. So this plugin helps you with that. This plugin will only import what you're using in your particular code and will not bloat your production bundle. So this is a production ready Babel plugin with someone has created with the understanding of ASTs. Another important plugin which has been used is Babel plugin transform react remove prop types. Prop types, people working with react would understand that it is something that we use for while we are developing our application to make sure that we see if you're passing a prop of a different type to a particular react component or we throw a warning or an error to us. But you do not want your prop types to make to production bundle. So this particular plugin will remove those prop types when you're generating a production bundle. Another plugin that's very useful is react class to function. We have been talking a lot about hooks these days and people are running behind converting all their class components into hooks. But this plugin had been already there long back. What it basically does is you have a class component, you give it to this plugin and this plugin would convert it into a functional component. This is a plugin that I was recently working on which is better async await. This is inspired from Golang because that's what I'm recently started learning. So usually when you write your async await syntax, this is how you write, you put them in a try catch block, api.getdata. If there's any error in this API calling logic, the catch block will call it and you call handle error. But if you have multiple of these APIs in your function, you either put one try catch or you have multiple try catches, which is eight increases the lines of code and probably is difficult to read as well. So this plugin was inspired from how Golang does it. So you see there's an api.getdata on the left side. There's an array expression whose 0th index is an error and the first index is a response. So you just check if error is populated, then something went wrong in the API. And if response is populated, then you got the response and it was a successful 200 okay. So you don't have to do anything. This plugin basically makes sure that when you make an await call to an API, error or response either or fit will be populated. So you don't have to put try catches now because that plugin had already put it in the code that it has written. So we'll quickly do a demo of few Babel plugins to help you better understand how all these things work. This is all theoretical at the moment, but these plugins will help you understand. So one important thing when you're developing any Babel plugin or ESLint or working with AST, this is the most important site that you have to be on. It's AST Explorer and the advantage of the site is that it will tell you the AST representation of what your code will look like. You can transform it here. So majority of your time you will be spending writing your code on this particular AST Explorer and then taking it to NPM or publishing it somewhere. But first you do your experiments on this particular web page. So what we are gonna do is a very simple plugin to start with, let's say, is it clear to everyone? Is it now? Perfect. One more. So one thing to notice here is you can choose different parsers for your AST tree. There's Acorn, which was initially available, which is Babel ESLint for your ESLinting. You have Babelon 6, Babelon 7, Esprit is the parser which ESLint uses by default. Babelon is the one which we are concerned about because we are writing Babel plugins at the moment. So I'll go to Babelon and select this parser. And what this very simple Babel plugin is going to do is, in your code you might have a syntax like this. You write const a equal to five and then you might have a debugger statement somewhere and then you do a equal to a plus six. Now there are a lot of companies and there are a lot of organizations where there are no proper PR reviews in progress. There is no pipeline where in people could figure out that there's a debugger statement which is making it into the master branch or going to production. So in all those scenarios, you can write a Babel plugin which will make sure that if there is debugger statement anywhere in your code, this Babel plugin will remove it. So how will we do that? The advantage is first for this AST Explorer, you click somewhere on debugger. Let's say I click on debugger here. It gets highlighted on the right-hand side and lets me know which AST node I have to target. So it says I have to target a type called as debugger statement. So I go to VS code. This is the bare minimum of how a Babel plugin should look like. It exports an object, it returns an object which has a visitor key in it. Visitor key is basically because it follows a visitor pattern which is a different topic of discussion. But visitor pattern is an object, is a visitor key has an object and here you basically say what node do you wanna target? So I wanna target a node called as debugger statement. So when Babel, Babelon will start traversing this tree when it reaches this particular path, when it reaches a debugger statement, I want this Babel plugin to remove wherever there's a debugger statement. So I say when you reach this path, remove this debugger statement. So a very simple example, there are complicated plugins also which we'll do but this is a very bare minimum of how you can remove debugger statements. So you say part.remove and anywhere there are debugger statements in your code, this will remove it. So let's test it. Let's add this Babel plugin to our plugins array here. So we say my plugin lies inside plugins directory slash remove debugger. And now let's run this. The file that I want to execute it against is remove debugger.test. And you see I have a const a equal to five. There's no debugger statement which is present over here. There was a debugger statement initially. This is what the code was const a equal to a plus five and a debugger statement with this Babel plugin. It has removed the debugger statement which was present in that code. And if you run it against your production bundle everywhere there is a debugger statement, everything will get removed. All the debugger statements will get removed. So this is one simple example of how things, how Babel plugins could be written and how you can target different nodes. Another example that we can go is a lot of times it happens a very simple thing. You write const a equal to five and then for debugging you have alert statements in your code. Let's say you don't want to put, you have alert statements and now again, very similar to our debugger statements, you do not want alert to go into a production ready application. So A, you do how you did with debugger statement, you remove them or you convert them to something like a sentry reporting or you report it somewhere. Here we are going to convert it into a console.log statement which is harmless for us at the moment. So what we want to do is we want to convert this alert statement. So I click on alert and I see that it is something called as a call expression on the right that I see. So what a call expression, any function call that you do is a call expression. But if you are doing an API.getData which is an object and a property and then you calling a function that is called as a member expression. So the two important things that we need to understand is what a call expression is and what a member expression is. So any function call is a call expression and any object property, then a function call is a member expression. So we understood that we need to target something called as a call expression. So we quickly go to our code and the bare minimum is ready. I say the thing that I want to target is a call expression. So you say, okay, this is what I want to target. And now I have to do something with it. I need to replace it with console.log. Now, how do you do that? You click here and you figure out that, okay, this call expression has a cally and that cally has a name alert. So I say I want to target call expression whose cally has a name alert. So I go here and say, if path.node.cally.name is equal to equal to alert, I want to do something with this. So now what I want to do is I want to replace it with a console.log. So let's see how that looks like. So this will look like console.log. So again, I click over here and figure out that a console.log looks like, again, a call expression. But the difference is that the cally here is a member expression, which has an object, which is console, and a property, which is log. So now I understood that I need to replace it with a call expression. So I say path.replacewith. I replace it with a call expression. Call expressions, cally would be a member expression. Member expression has an object. So I say that's an object, which is an identifier with a name console. And it has a property with an identifier called a slog. And this call expression, if I see, takes a cally in arguments as well. So arguments is A. Now how do you get arguments? Because in alert statement, you already have arguments. So I take the arguments out of that alert statement, say const arcs is equal to path.node.arguments and pass it to this new replacement that I've done. So this is a call expression. If it's an alert, take the arguments which are passed to alerts, now replace it with a call expression, which is console.log, because it's a dot operator. So it's a member expression, which is console, log, and then you pass the arguments to it. So let's add it to our plugins area. It's inside dot slash plugins slash convert alert to console. The code that I'm trying to convert is this. It's an alert I am here. I want to convert it into console.log I am here. So I'll go and run this code. This is inside convert alert to console test. And you see alert I am here got converted to console.log I am here. So the alert statements everywhere in your code will now get converted into a console.log statement with this plugin. So far, so good. Perfect. Another complex example that we're gonna do is most of us write things like this, one comma two comma three. You map over it. You get a value and you say value into two. Let's say you want to just multiply it by two. This is an arrow function expression here. And there are scenarios wherein your browsers might not support it and you want to convert it into a function expression. So you would want to convert it for any number of reasons. Let's say you want, you do not want arrow function expression and you want to convert it into something like this. So you want to convert it into something like this. Oh, oops, okay. Yeah, so you want to convert it into something like this. So now we click here as always we figure out that note that you want to target is an arrow function expression. So we go to our code arrow to function. We say the note that I want to target is an arrow function expression. Get me the path of it and we'll do something with it. Now I need to extract this value that you see over here because this is the same thing that needs to pass to this function. So how can I get that? It's inside params as you see on right. So it's arrow function expression and params. So I extract this out from here. So I say const params is equal to path.node.params. I also want the body to be same because that's exactly what I'm gonna do. Except the return statement, everything is same. So here if I see the body is a binary expression which has all the things in it. So I copy the body as well. I say the body is path.node.body. So get me the body, get me the params and now I will replace it. I'll say part.replaceWith. I want to replace it with what let's click here and it says I want to replace it with the function expression. So I go here and say I want to replace it with the function expression. Babel types is the place where you can figure out what is needed by home. So what are the parameters needed? I see function expression takes an ID. It takes params. It takes body generator for generator function and async if it's an async await. So I know that function expression here would need an ID which can be null for now. Params we have already extracted. So I say, okay, just copy paste the params that I've got. Now I can't place the body directly here because the body here looks slightly different because there are parenthesis here and that parenthesis basically means it's a block statement. It's a block of code. So when I click here, I figure out that the body is a block statement. So I say, okay, replace the body with a block statement. That block statement if you see takes a body which is a return statement. So I say, okay, the body will be a return statement and the body would be what I've already extracted above. So this is my plugin. Now let's try to add it to our run.js file which is our array of Babel plugins and we say it will be plugins slash, what was the name of the file? Arrow to function. Arrow to function. Okay, now when I run this file it should lead to an error and why I'll tell you test arrow to function. Okay, it leads to an error as expected. It's saying property key expected but got this thrown new property body expected of type array but got an object. Your body can have multiple statements in it and it cannot be a single line. It has to be an array of statements. But what I've done in the code that I've written, you see the block statement that I've written it just has one line in it return statement. Instead, it should be an array. So let's just convert it into an array here. And now let's try to execute this. And you see your arrow function expression is now converted into a function expression with a return statement with everything and you return an arrow function got converted into a function expression and with very few lines of code. So this is what ASTs, if you understand ASTs this is what you can do with them. These are probably a smaller example. So what all could be done but you see the bigger production level Babel plugins which have been used they all follow the same fundamentals target certain nodes and modify things in them. So those were the plugins that I had for demo for Babel. Most of the things that you saw I was adding plugins into and particular array of plugins. Your plugins and presets go to a file called as Babel.rc file. It's where you specify your presets and your plugins. This is how a very simple Babel.rc file looks like. I have react ENV and I'm using a plugin called as transform object res spread. So now a question that arises that immediately came to my mind is I've understood what plugins are but what are presets? So Babel presets are array of Babel plugins. So you can either publish one plugin or you bundle them all together as an array of plugins and publish it as a preset. So if you want to look at what Babel preset ENV comprises of this is from my code base it may vary for you but this is what Babel preset ENV has. These are the plugins that come bundled with it. You can enable the debug mode in your Babel preset ENV and you'll print the plugins that it is using. Async to generator because I does not support Async await so that is why this is there and there are a lot of other plugins as well. So presets basically being an array of plugins and another important question that immediately comes to mind is what is the order of execution? Are plugins executed first or are presets executed first and how does that happen? So plugins are executed first in top to bottom and presets being an array of plugins are executed in the reverse order from bottom to top. So the order of execution is plugin from top to bottom and presets from bottom to top. So yeah, so that is that is all about how Babel plugins are created. One quick question that comes to my mind immediately after this because it's related to the next topic that we're going to go on. How many of you are actually using linters here to actually have linters in your code? Oh perfect, almost all of them which is really great and are you using ES lint for it or are you using something else? How many on ES lint? Oh perfect, then I don't need to explain what other linters were available, okay. Okay, so this is happened with most of us, right? You write a code in ES lint tell you that you weren't supposed to do that and this has happened with me recently because I started working on a code which was in Hapi and Hapi node, Hapi's framework for some reason has some weird, weird ES lint rules which is at most of the time it used to give me an error saying you're not supposed to do that. So I turned off all of them rules and then put mine in it. So this is usually what happens with people when we are really started working on a old code base being maintained by someone else. But linters is a very good practice and why is that? Because static analysis of code if you're not really into reason or you're not really got into the type script but you still want your production code to be lesser buggy as compared to as compared to what it could be. So have linters in place because that will give you a static analysis of your code that will show you your errors if you have undefined variables which you're using if you're trying to import something that does not exist. So static analysis of code it will encourage best practices you can have Airbnb style guides or Google style guides to enforce better practices in your code. And finally, if you're using let's say a prettier which most of us are using at the moment or a prettier or standard or anything it will enforce certain style consistency with ES lint also it happens you can say that I do not allow semicolons or I allow tab versus spaces so all the styling consistency can also happen with the linter. The other JS linters which I think none of us care about at the moment were JS lint, JS hint and JS CS. JS lint was the very first that came with was created by Douglas Crockford the some of the cons of it where that it was not there was no configuration file available for it so you cannot really turn on or off a rule you cannot put in your own custom parsers or rules to it which is why it didn't really work out so JS hint came into picture which was a forked version of JS lint it had a configuration file but it did not allow you to write custom rules so again people really didn't like it and then finally JS CS came in which had configuration files which allow you to turn on and off the rules but also allowed you to write custom rules but then it was not catching errors like an undefined variable being used somewhere so it was not finding potential bugs in your code but it was telling you if there is a style inconsistency so JS CS I think recent not recently but got merged into ES lint so finally ES lint came into picture which almost everyone here is working on which is great and using in your applications you can write your own custom rules you have custom formatters custom parsers a very big example of a custom parser is Babel ES lint ES lint had it own parser called as Esprit but then Babel wanted to make sure that all the new features that Babel supports also are shown problematic by ES lint so they created something called as Babel ES lint as a parser so that's ES lint's parser taken plus Babel's functionality is added to it and then you have a new parser for linting things which is Babel ES lint so very good you can write your own custom parsers you yourself can write your own custom parsers you can turn on and off the rules which are not available for different the linters which came before ES lint you can set them to one or error you can specify whether this will be a warning or an error this is how an ES lint rule looks on my VS code editor it will look different on you but this is such a detailed message that it gives you that there's something wrong in your code and ES lint when you write an ES lint rule this is how a basic structure looks like you have a meta which says type type is suggestion, problem or layout suggestion can be, this can be problematic but it will not lead to a buggy code if you say type problem then it will be a buggy code 30 minutes, right? okay, it will lead to a buggy code and then when you say fixable code this basically means when you do an ES lint minus minus fix this rule will automatically fix your code and the create function is the place wherein you actually write your rules when you're working with ES lint rules you always create three files one is your actual rule file one is your test file and one is a markdown file which basically is for documentation so if you have to do this thing so we choose an SPRE parser we go and transform and say I wanna do an ES lint transform and the code that I wanna transform is I don't want to allow anyone to use promises because async await is in place so I say cons data and I say get data.then response and then response so I don't want to allow anyone to use promises so I will throw an error if someone uses .then I'll tell him or her that you should use async await syntax so I click over here and figure out the thing that I need to target is a member expression and that member expressions if that member expressions property is then so I say I wanna target a member expression and if that node.property.name is equal to equal to then it will help me identify that it's a member it's a promise call and then I say I will throw an error and how will I throw an error? I will use something called as context I'll say context.report and throw an error the message would be use await over promises this is the node that I wanna pass okay so you see it's throwing an error on the right it's saying use await over promises okay check it okay use await over promises but you see there's a problem here it's pointing the error at get data instead it should be pointing the error is at .then so a quick fix to that we say the exact line of code that you wanna point an error to we say node.property.loc and you see now it's exactly pointing to the place where there's an error so use async await over promises this is what that ESLint plugin does it's a very simple plugin which you can use in your apps at the moment if you do not want to allow promises the last bit so celebration time it worked successfully I'm running out of time so last bit of the talk is about code mods when you wanna do a very large scale refactor of your code base this is what you use for writing code mods we use something called as jscodeshift jscodeshift is a library provided by Facebook which will help you do a large scale refactor of your code and how to use jscodeshift you do a global install you specify what your transformation file is and then you specify that I want to transform everything that is in the src folder so I say transform everything that's in the src folder and it will convert everything so yeah so that's it for the talk these are the certain resources that you can that will help you understand ast there are a lot of them documentation is the biggest resource then there are certain jscodeshift has all node level APIs which you can follow to understand what APIs it provides and how to use them and finally there's a Babel handbook which is like the greatest resource to understand anything about writing a Babel plugin so yeah that's it thank you everyone for listening to it and if you have any questions around this then please demo like that hi so you mentioned that jscodeshift is for large scale transformation but like technically do something extra to handle those large scale transformations or it's similar but so if that question is can I do the same thing with Babel exactly so yes you can definitely do that with Babel as well is just that jscodeshift provides you certain APIs which makes it easier for you to do the transformations so there are certain level of abstractions that jscodeshift has provided you for you to easily modify them and plus recast parser which will help you do the formatting and pretty printing of it as well so that is also something that comes with it so but yes it's very much possible you can do the same with Babel as well you can write a Babel plugin and do a transformation but with jscodeshift what you can do is you can do a dry run of things so you will understand what the modifications are going to be and whether to commit them or not and it will give you proper statistics off to how many files were modified and then you can actually manually check if these are correct or not and then finally merge it to your master one more we don't have enough time for follow up questions so he will be around actually we are running out of time so you can catch him offline so yeah there is a bof session that we are doing outside so if there are any more questions we will catch up thank you so much till the next speaker gets set up let's play a game do you guys know the person who is sitting right next to you on the left and the right unless you are sitting with your friends why don't you introduce each other let's do that right now I am not kidding let's do it right now can we remove this yeah let's come back to it part 2 of it make sure that the phone of the person sitting right next to you is on silent we have been mourning you since morning but there are offenders and I will promise you stickers if you find a culprit so let's do that I am not kidding let's do it right now I want hands raised oh this guy next to me is the culprit just put your phone on silent and show it to the person next to you I am not kidding do it right now okay I am trusting that you have done it let's go on hi everyone can you hear me everyone fine yeah so good afternoon again and welcome to re-add foo I am Santosh Gramprohit and today I am going to talk on delivering the re-add yes applications at scale yeah so before we move on to the topic let me introduce a bit more I work as a developer at Walmart and for past few years I have been working on React and some other frameworks and libraries like Angular or Polymer and so on below is my Twitter handle and the personal and the official mail IDs where you can contact me on so let's get back to the topic when we talk about delivering the applications at scale there are multiple meanings to how can you scale the applications as a developer you can write efficient code you can write performance code and then scale your application or from a diverse perspective you can increase the number of servers when the traffic increase and then scale it but what I am going to talk today is how are you going to scale the applications by having a proper architecture and the CI CD system to support it and then scale all the multiple applications to explain a bit more we worked on a solution to host multiple enterprise applications under a single entity sort of like hosting portal and we worked on scaling those applications which were built by different teams so our agenda is going to be something like this we will start off with the challenges and the opportunities that we faced when building this approach then we will move on to the basic UI architecture of it and the CI CD system to support that and we will talk about something called as CDD that is Confit Driven Development and we will finish it off with the performance benefits of using this approach so let us start with the challenges as I told you this is a sort of a hosting portal where you have multiple applications coming inside it so what it means is that these applications are built by different teams and they have their own roadmap and they have their own release cycle so you cannot tell them to release their applications today or tomorrow or day after tomorrow what it also means is that these applications might have their own text track as well so we had the challenge of supporting the existing applications which were built on AngularJS on top of these challenges we also found out we could build on some opportunities like a single sign on where the user logs in one application and he or she need not login to another application or say user analytics where the application team will get to know how the people are using their application and some benefits like high availability of the application and faster development and time to market so let us start with the basic picture that we followed so as you can see there is a main application here and then you have these child applications 1, 2 and 3 now these child applications are npm modules and these modules are added as a dependency to the main application as you can see the application 1 is at 1.0.2 while the application 3 is at another version 1.4.5 because these applications are built by different teams and they are coming inside the main hosting portal that is the main application now one of the obvious question that you would have is why would you go with this approach of building npm modules for your application so let's see the benefits one of the benefits is that npm supports versioning by default so you know something called as semantic versioning where you have the major update the feature update and the patch update if you do a breakable change you update the major number if you do a feature update you update the middle one or if you do a bug fix or something like that you update the patch version so you have the versioning capability built in on top of that npm allows you to reuse the components very easily so you can just add the components that you have created inside your package.json and you are good to go so the whole dependency thing is also built we also found out that when people write npm packages for their application they tend to write modularized code so if I am doing, if I am breaking my application into multiple npm package I want that those packages should be used by other teams as well as by my team so I will try to write more modularized code also our npm module consisted of the usual source code and the distribution code the source code was written in the jsx react while the distribution code was the esy code which was transformed by bevel another advantage of using npm is that the dependencies between the packages can be shared what it means that if the main application has one UI framework dependency then all the child applications are going to use the same one so you have the consistent styling and you have the consistent theme across all your applications inside the portal now that was the theory part of how you can build your applications and divide it into npm packages but how are you going to do that in your code base? now think of this scenario where you have multiple repositories for your packages so if I divide my application into 3 or 4 packages and if I have 3 or 4 repositories in github then if I want to release the application I would have to go to each of the repository send a pull request, get it merged and update the version number and so on so that's a bit of an overhead task so there's a concept called as mono repose wherein you develop these packages in a single code base and it's not new, there are many open source projects that use it like say react or angular or just you can go to the source code of react in github and get to know how are they doing it and there are multiple ways as well if you are using yarn support doing that something called a workspaces so you can have multiple workspaces in your code base and you can develop these packages we use something called as lerna because we were using npm client and lerna allows you to do the same thing that is managing multiple packages in a single code base so as you can see on the screen we have the main folder here we have the mylerna repo folder and inside this folder we have the packages folder so this packages folder consists of the package the npm package you are doing for your application and each of this package in npm module and these packages are added as a dependency to the main one so you are developing these packages inside a single code base instead of having multiple code bases another advantage of doing this is that you can add these dependencies at local, test it out and then publish it to the npm repository that you have now we used internal npm repository for publishing the packages not the public one and we used lerna for management of the packages in the code base that's fine, another approach that comes to mind when we talk about using npm and dividing the application into multiple packages is the micro front end let me explain the micro front end a bit think of this application about the product where you have the description of the product, you have some filters and you have some reviews now this application, this product application is being built by multiple scrum teams so you have team A working on the description part the team B working on the filters part and the team C working on the reviews part how would the development be here so these teams would create the custom element for their package it will be independent code base and this custom element would in term be developed by say angular react or the framework of their choice that's how mono repose works and it would look something like this where you have the product description custom element, the product filters custom element and the product reviews custom element and you are going to pass the product tidy to each of them and based on this product tidy it is going to fetch the description or the filters or the reviews for it now however approach differs from this is that when I showed you the previous slide we had the main application and the child application so we work at a higher level we consume the applications as a node packages how these applications are being built whether they are using mono whether they are using micro frontends or they are using monolithic approach the single SPA approach does not concern to us that's one of the main advantage that we have we do not govern how the application teams are building their apps another distinction is that you don't exactly know how are you going to share the components that you have created in micro frontends by using the MPM approach we already have the framework to reuse the components we have the framework to share the components as well on top of that we provided a robust CI CD system which checks all the code quality that is going into the code base and by having this MPM approach the styling the theme of the portal was consistent and that's how this approach of using MPM differs from using micro frontends that's fine we talked about having MPM approach but it is of no use if you don't have a robust system where application teams can easily put their package in the repository so for that we had to build a robust CI CD system in place and how did we do that so we provided a boilerplate repo to the application teams now this boilerplate repo had all the code quality checks written so all the links and the test would run whenever you send the GitHub pull request and when these child applications are published with a new version whether it's a feature update or a patch version it would also trigger the build of the main app so if I want to tell you the CI CD workflow from the server perspective it would look something like this where you have the child application at version 1.0.0 and the application teams are doing some parallel features that is feature 1 and feature 2 so once they are done with the development they would send a pull request to the dev server and the reviewer would check it and do the code review and finally merge it so it goes to the dev server and depending upon the servers that you have it will go to QA or stage and finally it would go to the prod 1 now in the prod server the feature number that is 1.1 is updated because you have done 2 features and not the bug fix or the breakable change and how you increase the version number is again dependent upon the teams they can do it manually or you can parse the commit messages and also do that and finally once you update the version it is going to create the build of the main app and if I want to show you the workflow from the developer perspective how do they release the applications it will look something like this so you have to clone the boilerplate repo this is a one-time process on-boarding process once you have clone the on-boarding boilerplate repo development team has the development branch where can they do development so the development team would take a feature or a bug fix shortly branch do the code changes and send the pull request back to it so the quality checks would run on the delta code that they have written and once these automated checks are passed it would be going to the reviewer who can review the code and finally it goes to all the service that I mentioned before and it gets published to the npm repository after running all the code quality checks on the entire corpus and not on the delta code and once it published to the npm repository the internal npm repository it is going to create the build of the main app and when I talk about the code quality checks I mean as simple as this this is a sample screenshot from the Jenkins server where the links and the tests are running and you have this report the test report that is generated this is a sample report where it tells you the coverage by statements or by branch or functions or lines of the individual files and you can also have something like say a threshold and if the threshold is not met then it would fail when you talk about the branching strategy there are multiple ways again you can do it in your codebase we follow something called as trunk base development where you have the main branch that is the trunk branch and you take short loop branches out of it daily do some bug fix or a feature update and send the pull request back to it but there are other ways you can also do it in your codebase like say git flow and again the application teams are free to follow their own strategy if not tell them how are they going to do development but yeah they can follow git flow or they can follow trunk based as well and for continuous integration we use an internal tool of Jenkins called looper which is built on top of Jenkins and for continuous deployment we use an orchestration tool called conquer now for this orchestration engine or tool does is to take the artifacts from one server to another server put it there or spawn a server and run the test and all there are many open source engines available as well you can check like facebook chef it does the same thing and also provided the link for conquer at the end of the slide so you can learn more about it and also implement it in your project if it fits well so that was about the architecture of the portal as well as the CI-CD system to support it but we found out another way where you could also scale the applications that is config driven development in ADD now what it means as the name suggest is that you are developing your applications by writing more configs and by writing less core now how does it help so we found out that there are teams many teams who do not have a dedicated UI developer so they want to do a quick prototype of their applications without investing much time into it and in order to fasten those development we created a standard set of components now as I mentioned in the previous slide where the application teams would divide their code into multiple packages and create these packages so that it can be reused by other teams there it helps because we have already have the code base of these components created the standard set of components created why do I mention the word standard because there are many components you can create for each of the use case you cannot tackle for each and every case out there so we focused on solving for visualization or the reporting solution we do not try to solve for other solutions like say building the layout and etc and by focusing only on the visualization aspect we found out that many teams could use it in the code base and do the faster development and put it in the production faster there are two parts to it first is creating the standard set of components that is already achieved how are you going to use these components in your code base so for that it looks something like this where you have the micro services API created for your application and you map these micro services API to some visual component that is out there like say bar chart or it can be a pie or a line or any of the chart and then you export that code snippet and then you consume it in your project it sounds very simple let me show you a short demo of how does it look so this is a replica of the app that I have created let me expand a bit so that you can see it properly fine it's not the full-fledged app that we have built but it's a replica I want to showcase only how you can export the components and consume it in your project so you have the standard components here on the left-hand side you have the bar chart you have the pie chart and you have the line chart now these components are created by the application teams it will be very last set here depending upon the visualization components that you want to use and you have something called as configuration ID what this means is that this configuration ID is tied to some micro services API so when you fill in some configuration ID here it would fetch that data from the micro service API so this is a replica and there is no server running behind the scene think of this as a configuration ID where you have ID something like this sorry and when you click on submit it's going to fetch that data here and then you have the visualization of the bar chart created and you can as well toggle between the pie chart and the line chart and do the different visualization for the same response data and when you click on the export component you have the code snippet available for you and use this code snippet in your project and consume it so where does this help one of the advantages that the application teams do not have to write the transformation functions require to transform the response data to the format that required by the line chart or the pie chart and the advantage is that they can just copy the snippet and use it in their project without downloading the dependency etc because we provide a boilerplate repo the package which does the line chart or the pie chart is already there in the code base so they need not download it again and they can quickly do the development of their project so that's how the consumption of the components the standard components works in config-driven development so that was the demo of how CDD works let us see the performance benefits of using this npm approach so I told you we are using the npm modules for sharing the dependencies between the application what it means is the dependency payload that is downloaded when you move from application 1 to application 2 is going to be less and because you provide a boilerplate report to the development teams all the code that is required for say minification or say obfuscation of the code or say the dead code elimination or tree shaking everything is built in by default so the developer need not invest their time on writing the code for say lint or minification etc they can quickly start doing their business use case so all in all the developer experience is better in conclusion as I told you we had the challenge of separate code bases by separate teams yet all of these code bases all of these applications were hosted together in the portal and we followed the npm based module system where in the dependencies were shared between the applications and because of having the robust CI CD and having the config driven development we could provide the high availability of the applications as well as faster development and faster time to market these are some of the references that I have written you can learn more about Concord here or how the learner works there are some links from micro fronted semantic versioning and trunk development where you can go and learn more about it again the contact information and thank you now I open for the questions that you have yet my name is Anand so one question is so it's fine like it looks fine and presentation was good so you have suppose two or three components that you publish to npm right yeah either being internal or something so once you use it right how each component can interact with the other one so suppose suppose any component has some event that got triggered and based on that some other component need to update how that part is being handled in your framework so if you have seen the slide where I talked about the mono repose we are using learner so you can easily add the packages as dependency and you can even share the packages between them so if there are three package and the package three is a dependency for one and two you can just add it in there and you can do that did it solve answer your question kind of but the thing is then you are creating a dependency between one component to another component right so then it's not whether that package has to be created or not so if you have these dependency between the packages it makes sense to have it in a single package once you have it in a single package so if you see your application and you can think that I talked about product application then you can logically divide it into three modules I cannot divide it into other modules where you have dependency or cyclic dependency going on so you need to properly if you properly divide the application into modules 90% of time you will not face that problem so super interesting concept but I am having a lot of scenarios running I want to know is how much granularity is Walmart going to is it based on product feature level like a product search product filter or is it at like a very smaller level something like search which is used by product search or you know and review search that is one question how much granularity answer that okay so as I told you we work on a higher level where you have the applications coming inside the portal now how granular that application needs or how they are doing development what branching strategy are they following that is not a concern for us this is a portal where the teams are coming application teams are coming in performance as I told you we have provided the boilerplate code developer experience is good improving the developer productivity but I am talking about the performance in the when the app actually renders in the browser so did you see a lot of performance benefit like the load time increased or the load time decreased or you know interactions became much more fluid and the dependencies which are common across the packages are shared so if there are two applications which share most of the dependency then it would not require downloading it again but if you create an application which has which has complete dependency different dependency tree it would again have some performance implications so I would say because this is a portal because at a higher level then we could solve for some of the application performance but most of the the ownership of improving the device at the lower level we did what we could do at a higher level hi thanks for the presentation my name is Sakeer I had a question around the boilerplate code so you said it's like a one-time operation you just copy the boilerplate and then start development I am assuming the boilerplate contains all of the webpack configs something like react tab where you download everything so the question is if you make an improvement in the boilerplate repo how does someone who has cloned it and like development has moved forward significantly how do you back propagate these improvements so that's where the versioning comes in so if we do a breakable change you update the major version if you do say a bug fix you update the patch version so because we also have the versioning done we also release it consistently like say every three weeks or four weeks depending upon the changes that we have and the teams would get to know these versions have been released and based on that they update their codebase if it is required for them they can do a merge as well depending upon the changes that you have so if we create a breakable change you have to create a new repo but if you are doing say patch versions or say minor feature update then it would be sufficient for that or we can talk more about it later after this sure we can catch up in the burst of feathers as well could you could you throw some light into micro frontend what use cases that did you use it for we don't use micro frontend because the micro frontend approach sounds similar to the approach that we have so as I talked to you about dividing the applications into multiple packages you have the application divided into multiple modules so both of these approach sounds similar I wanted to show the difference that we operate at a higher level and this is at the application level so how do you do the application is not a concern for us the application might be using say multiple scrum teams or they might be using single SPA something like that yes you can take follow up questions offline he will be available so how will you get something like code splitting in your node modules kind of framework we provide the boilerplate code which already had this code splitting so you can't code split the code from node modules folder that's not possible so you have to do it in the boilerplate itself you provide the provision to do that in the boilerplate code you can take up later so one more question you are publishing the NPM packages so for example I publish one NPM package which uses React one uses Angular we are using React for this entire approach so you are not having the approach where I can have different kind of packages that I can publish no not currently so for the framework for the applications which are built on different frameworks we are using I didn't get as a single link so for the existing applications like AngularJS the support line is deprecated we are adding it as a link that's it we are not including it as an NPM package yeah so the question that I have is around common services like settings and all so these common services is something that is shared by like most of the components so how do you resolve duplicates like I have a common service which fetches the settings of a user let's say like settings as in it can be anything the default language that I have the preferences part yes and it fetches from somewhere so I have a common services package which does so the common we also have a mono repo but the common problem is if anything changes in the setting service because it is used across all the components either all the components have to upgrade to a new version or there might be multiple versions of the same setting service sitting around in the code which will cause our bundle size to increase so how do you solve this kind of problem so you are saying that the preferences would be a separate package and it is shared by multiple applications yes so that depends upon again the application team so we are working on the framework for supporting these applications if two or three applications have their own individual package then it's their ownership of making it proper versioning you don't we are not concerned about the versions of the packages that they are using those of you who have given your names for flash stocks can you just come forward we will get you set up let's keep the questions going if there are any more also a lot of you have bought t-shirts along with your tickets itself so you need to go and pick them up a lot of t-shirts which are already bought have not been picked up and if you would like to buy react food t-shirts they are available I have a question for you so you mentioned that let the user paste in the configuration and then configuration id could be used to render yes so aren't you making an extra network call in affecting the overall performance for all the pages that are using such things because a configuration id would then load a configuration and then on top of that configuration id is tied to the api anyways you have to make the call to the api to get the first the response data there won't be any extra network call for first to get the configuration and based on the configuration get the data it gets the configuration to load that response data in say pie chart or the line chart is already built in in the boiler plate the extra call that we make is to face the response data which is dynamic for different scenarios you definitely make a call for getting the configurations also right based on the id there is an extra call we have the data required so the data that comes is the data required to visualize that component so if I have the pie chart I need to render three columns I will require the data for that there we make the this network call to face it so isn't it an extra network call affecting the performance or anything of that sort how is it an extra so normal scenario if you want to do if you want to visualize the component you of course have to call to get the data right so configuration in the sense the chart configuration that is built in what we call is for the data render it visualization data hello hi just once this side this side so are you stitching the whole thing on the server side or the client side client side everything is like so the main app loads first and then it loads the smaller apps are there any more questions are there any more questions alright thank you so all the people can can you just comment and fill in the seats like sit next to each other everybody quickly we will just do an activity so that we are not sleepy anymore can we please stand up people stand up yeah just sit next to each other fill up the spaces in every in this rows guys stand up okay standing up Shankar will be giving a flash talk first flash talk now yeah hi everyone I am Shankar I am from Blockstack okay this is exercise not because of me so but this is true this is for you anyone can notice what is this this image so this is going to be a disruptive talk okay this is penopticon it's a jail architecture the reason why I am saying is that we are all living in jail in terms of application development okay and what we are solving is centralization centralization means like say if you take facebook or any application that has been developed today it stores your identity and data it stores its own cloud and doesn't leave that that's the problem of centralization you know this thing happened quite some time we know that facebook it's of a continent it's own where the biggest threat apart from Trump it has been said to Mark Zuckerberg the reason is that he holds all our data and he is kind of ruling it so we are trying to come out of that so how we are solving this is that just see this image this will be useful for this talk so here the data identity is locked in and what we are doing is that we are releasing this identity and data to not be locked in into your application that's what we are doing and say it is based on blockchain so the talk is about how you develop a decentralized app using react this is what it is about and I will quickly run through it so this is the architecture this is the blockchain network it can be Ethereum or Bitcoin anything so whatever application you develop will be sitting in a virtual chain so this is off chain computing is what we are kind of doing and innovating in the block stack so what it helps you to do is that you as a developer you can concentrate only developing on your application for example consider it as a Facebook say why we use Facebook is mainly because to connect with friends and share our post but what really happens is that Facebook owns our data owns our post they sell it that party but imagine that tomorrow Facebook is not there what happens or if you don't want to share your data but you have you got an identity from Facebook and you kind of delete Facebook what happens is you lose all the connection you have made that's right so the application space is storing all the identity and data that is the problem we are trying to solve so this is something an whichever we are built up I will quickly go into the demo I wanted to give okay so this is block stack browser it has an identity for example Shankar dot personal dot ID is my identity this identity is being saved on the blockchain for example you consider it's a bitcoin identity and a name has been mapped to it so what say being at react conference what we do is say consider this is a small app just like a text editor maybe so here I am storing do you like internet where it is decentralized so I am trying to save this post what actually happens is that this post will be saved in a cloud of my own choice okay it will be encrypted and saved in there whereas this data will not be saved in any of the applications or it will not be with respect to application context okay there is one more application I would like to mention is like spring roll here so what happens is similar to LinkedIn where you can create your own private note say if you are sharing with your friends or anything say hi there okay and save it or you can create a reminder or whatever you want say actual data has been stored on AWS cloud but it will be encrypted so for the cloud player the data is just like what you can it's just like a black box for him okay so this is what we have done thank you all I am Saurabh Bairani I work with Druva data solutions I would like to give one small talk on common library Javier covered all the things but in Druva we already did the similar thing and we did it on a huge scale and yeah it's a successful so there are some points engineering pitfall as a developer which you should consider so I wanted to share those with you I haven't prepared anything so please go easy with me okay so as Javier covered what are the problems so example we have three products right now all are migrating to reactjs from older technologies so all are having their own components they are using the same components most of the time like tab or something like that but they are building via their own ways or own approaches so it makes sense to give one library to them which they can use and the whole product of one company should look similar behave similar so like that so that was the one problem which we wanted to solve solution build a library simple one word solution okay but it's not that easy library converts its own problem so I have tried to list down some engineering problems that we faced and we overcome and that we think everyone should consider first one we discuss on this like two or three times in previous sessions about versions so as I raised a question to Javier also suppose team A is using one library having version one one component is having version one and library team try to upgrade it or fix some bug now there are two versions of that particular component so do you want to ask all consumer that is products to upgrade their library no you cannot do that so one thing that you must take care of that these all components they should be backward compatible no other product should break if you update those things so semantic versioning is the perfect choice for that which we eventually landed on that the second one is decision so I want to use example for a tab component but product B says I want tab with these these functionalities and I don't want to use this so you that is a big challenge where you want to where you need to pick all products into same platform agrees them and carve a component which fulfills the needs of all components so that one also a challenge which you should take care of third one is usage so how you ask other products or other consumers to use your particular components from your library so there are two ways either you should the first thing you can do is create a NPM package out of that and ask them to do NPM install whatever your name is and the second approach is which is quite okay to create a Git repo and inside the package.json directly mention that Git repo but a disadvantage that comes with this approach it will be just like dumping the data it will just copy that repo and put it over there so you won't be able to compile the library over there so in that case you can use hooks like post post installation and all that things you can check those with NPM documentations so so these are the things that one should consider while creating a common library on a huge scale so specifically when you have lot of products lot of teams to working on that and they have their own lot of requirements so these are the pitfalls and things that you should consider so that's all I wanted to share sorry I haven't created a proper content or I haven't framed my sentences properly any questions for that no great thank you guys Hello everyone my self is Anand Kumar and I work for Publis recipient so I'll quote one of the presentation that we had recently and they were mentioning about micro frontend right so I'm going to talk about that of course I'm not prepared so but anyway so we mostly we prepare we create the application like single page application which becomes like monolith right and behind that we have microservices which all of us are aware of so what if we can have something similar at the frontend so that is where comes the same thing so it gives us the benefit like we can deploy individually each app small app we can have less regression then build process of course can get more optimized and it also gives us the leverage of having better A B testing right so what we can do with micro frontend so for example one of in the in the talk they were talking about learner right so we can leverage the learner to build small applications to build it at its own it can have its own webpack and all right so it can create its own application the one thing that I want to talk about is the build right so what if we can build the application the small individual application and deploy it to the cloud as a cloud function so if we deploy it as a cloud function what we can get it can be rendered as a server side and we can render it individually also in the browser or what happens is each developer can work on the individual application and they can deploy it they can test it individually and it can be available on cloud itself when I say cloud so like Firebase this supports lambda functions right so what you can do is it can scale it automatically so if your component being hit multiple times and if it needs more memory it can scale automatically to worry about how it is you know behaving on higher loads so that is one of the advantage and that so how it can be stitched together so we have learner we have different applications but how to stitch it so there is come TaylorJS if any one of you have heard about it so we can use TaylorJS which gives you the option to use fragments and you can use fragments to turn on any part of application, small application into page, if you want to insert one insert it, if you want to remove get to remove it so for example I have a home page and I have a header, footer and the content area so what we can do is we can have some kind of template engine where you can compose your page and you can enable any component you can remove, you can add and that template can be served at the server side like it can do the application of your page do the server side rendering and serve the page at the client side so it all becomes very easy to work like a lego so you can put one thing on top of other so yeah I mean so cloud function is the thing and aggregated TaylorJS so you can so one of the project we delivered on this also it was not using TaylorJS but micro frontend we did but yeah I mean if you guys have any questions around this we can talk offline so I mean I'm not prepared for these things but yeah so thank you so much that's all the submitted flash talks we had so some of you, some of us we are frontend engineers and we know a lot of these things and sometimes we wonder you know I could give a talk so before you submit your talk like maybe you want to test out there's an idea in your brain you want to test out the stage for five minutes then we have one more slot for a flash talk so if you have a good idea or an idea just ringing in your head we can allow you to go on unless it's a hiring pitch or a product pitch nobody? okay we'll break for evening tea and then we'll reconvene alright see you guys hi guys welcome back again so we have our next speaker here you might be knowing that there are two BOFs going on one on ARBR applications with React and one more I think on Geekery so if you want to attend that you can go there too our next speaker is Kiran Aburi yeah so he'll be giving a talk on deep dive into Apollo client so the stage is yours hi everyone should I reduce the volume it's fine so hi everyone welcome back for the last set of the talks so I'm Kiran and I work as a freelancer and I also organize ReactJ's Bangalore I hope most of you here are front-end developers so in my opinion there are two main areas in front-end one is UI what I mean by UI is how the app looks or how the app behaves things like styling, animations those sort of things and React does pretty good job with this thing so React is primarily a UI framework and the API and simplicity of React works very well for us so the second important challenge in front-end applications is state management so what I mean by state management is how we fetch data from the server how we manage it on the front-end how we implement business logic how we keep our server in sync with the front-end so there are quite a few unfortunately React does support some sort of state management but it's not meant solely for that things like contest might help but not for very large applications so there are quite a few libraries like Redux, Mobets and quite a few others as well but still even by using these libraries like Redux and Mobets still we have to implement logic on our own even getting state management right with all these libraries is still hard so this is where GraphQL helps so GraphQL has much more structured back-end compared to REST which is kind of not very strict GraphQL has much more structured back-end especially things like type system in the GraphQL and features like introspection GraphQL supports these are my two favorite features of GraphQL features like type system and introspection help us build a lot of tools right and which will help us build better applications with less code Apollo is one such tool which leverages the features of GraphQL and Apollo is by far the most popular client library so GraphQL is something that runs on the server and because of its unique features we can build client-side libraries which leverage the functionality of GraphQL and make our life easy so in this talk I will talk more about GraphQL, Apollo and how it helps even with Apollo it has it simplifies it is much better than Redux or Mobets based applications but it still has its own challenges and I will explain how to walk on those things so in GraphQL or in any back-end based applications like we have three concepts one is queries, mutations and subscriptions queries are used to read data from the server which is equal to get in HTTP and mutations are to modify data on the server which is equivalent to post with the HTTP subscriptions are for real-time updates so if you are building any real-time applications you might be familiar with sockets subscriptions are built on top of sockets to provide real-time applications so let's start with queries and see how Apollo helped with this so this is a simple GraphQL query here you can see in this query we are asking for users with within users we want properties like ID and first name so this is a typical GraphQL query so GraphQL is quite different from the REST in the sense in GraphQL clients ask for what they need in REST we just hit an endpoint and we get the data back but in GraphQL the clients request for what properties it needs for example the users database might have like 10 more properties but the server doesn't return those properties the server returns just the users with ID and first name because that's what GraphQL client ask for right so this is a simple GraphQL query and to use it in our applications we can wrap this with GQL so GQL is a helper function which takes a string GraphQL query and converts into a JavaScript object which we can use it Apollo or any other library so how can we use this query and fetch data from the server and pass it to our components there are couple of ways and so using high-order component is one way so we can import GraphQL from React Apollo and user list is a simple React component which just renders which gets a list of users and renders the users and it's a user list is simple React component and we use a high-order component called GraphQL and we'll wrap our user list component with GraphQL high-order component and pass user query pass user query and so this is the only line of logic we have to write and Apollo takes care of the rest of the things Apollo makes an API call to the server gets the data and pass it to the server like if you are doing the same with Redux or anything so you have to implement using some sort of edge use or fetch you have to make an API call get the response, implement error handling and storing the data in the cache so on and so forth so those things we need not do with Apollo so because of the previous step in addition to fetching the data from the server and passing it to our components we also get loading state and errors and so for example while the request is happening the loading will be true so if you want to show some spinner or something we can do that or if the request fails we get errors we can handle the errors as well and if the request is successful we will get the users data and we can use that to render the company so you can see that without writing much code we were able to get data from the server and use it we are not writing any additional code for managing the loading state or handling errors or fetching the data Apollo is taking care of that automatically all we have to do is write a GraphQL query and wrap our React components with GraphQL queries and Apollo also caches the data in the sense once Apollo makes a request and it stores in the cache and when we render the same component again Apollo doesn't send the same request again and so we need not implement that kind of logic also Apollo takes care of itself and Apollo stores the data very efficiently for example let's say when we when we made a request for the users we got two user objects and it is storing with reference to user one and user two and it stores the user one and user two objects separately so that if some other queries features the same data we need not duplicate the data so this is called data normalization so it stores efficiently and avoid any data duplication if because of some other query if one of these objects are modified the data will be synced across all the components so there won't be any data inconsistencies so if your application is read heavy for example if you are working on some media applications or some content based applications where you read different sort of data and render it on applications then GraphQL and Apollo works great so as you can see we haven't written much code we are writing queries and wrapping our components with that so if you are building dashboards or if you are building content based applications this fits very well so the next part is the mutations where we are making edits and sending so some of the applications where mutations will be heavily used is some sort of CRM based applications where user enters data and the data is saved into the backend of the applications so let's see how Apollo fares with this so to send data to make changes to the server again we write queries these are called mutation queries in this case we are writing update user and to this update user field we are passing arguments so GraphQL query language is quite extensive in the sense it has augments, it has variables it's quite extensive so in this case we are writing variables like arguments like id and first name and in response we want to mutate the server with id1 and first name is called Johnny and once this mutation is once the server got updated we want to get the response back in the response we want id and first name ideally the data will be the same so this is a typical mutation query as you can see in this query we hard-quoted id and first name but in real applications we don't want to do that so we want to use some sort of parameterization so for that we can use things like graphical variables in the sense we have one more layer where after mutation we can give an operation name and in the operation name we can specify the augment types in the sense for example we can say id is of type int and first name is of type string so graphical is a strongly typed long ways so whether it is getting data from the server or specifying the augment it takes care of it takes types very seriously so this query is almost same as the before except that in this case instead of hard-quoting the id and first name we are using parameters so how can we call that query there are several ways to do that so this is one of my favorite way where we will directly call mutate on the client how we get this apollo client during the setup page we will use apollo client library and give the cache and so on and so forth and finally we will get a client library apollo client and that we can directly call mutate and for that we can pass the mutation which is the query which we wrote earlier and pass the variables so these variables will be passed to the query and it will be evaluated on the server and once this mutation is executed we get the response from the server in some sort of dispassion like we get the data inside that we have update user because the mutation field which we sent is update user so in the response object also we get the update user and inside that we have id first name because that's what we ask for and in addition to that we have underscore underscore type name as you can see in my previous cache diagram right so apollo is storing with as references like user one right so so these cache keys are very important because whenever apollo sees some response from the server and if it finds underscore underscore type name and id right it immediately maps with the cache and updates it so we need not write any code in the sense you know we got some response from the GraphQL server apollo automatically understands that okay this data should be updated at that particular location and updates it right we need not write any logic so again this is very helpful and it also supports something called optimistic response let's say for example if you are implementing chart application and you entered something right you want to see that message immediately even before that message went to server and come back right it takes some few milliseconds before even getting response from the server we want to show that response immediately for that we can use this optimistic response in most of the cases we know how the response for example when we are sending a message we know what the message will be right even before coming from the server so we can give you a mock response based on our assumption in this case you know for example update user we are sending id and first name but that's the same response we are going to get back so we can give a mock response as an optimistic response so what apollo does with this thing is it renders the react components twice once before getting the response from the server and once after getting the response from the server so that where you see the instant response in the sense you know you enter something immediately see the response even before getting the response from the server and once the actual response comes from the server you know apollo re-renders again and you know does it correctly so this gives you know better performance as you can see it looks good in the sense you know we are not writing any additional logic to update cache or anything but still it seems quite a verbose right all we want to do is update first name but for that we have to write a query and you know all that mutation function so it seems verbose right what if we have a function like update record right and for that we will say I want to update record for the type name user and id1 and this is the data I want to save it to the database and this update record method can be used for n number of fields for example your application might be having like 3 tables and you can use this method to update any any table and any property right so we can do that you know apollo doesn't provide this method but we can implement our own on our own right we can write a generic function we can use this 3 information like type name id and data and generate the query the query which I have mentioned before right which essentially contains this information right we can take this information write a function which generates that query automatically right and call the mutate function so with the help of that function we can have a cleaner API like this instead of writing the mutation query for every single update we will write a generic function and use that function everywhere right so this reduces the boilerplate code so far we are looking at the good parts of apollo right so we have seen how fetching the data from the server with apollo is very easy and you know how it provides loading status errors you know how it's providing cache right and how we can handle updates we have discussed that you know updating is slightly verbose but it's handling the cache well but it's slightly verbose but we were easily able to write a simple function called update record and remove that verbosity so far we are good with apollo so these are the hard parts of apollo you know creating and deleting objects and you know subscriptions so these two things require a lot more effort than the previous cases I will explain why this requires more effort let's say you want to delete a user right and again you write a mutation query called delete user and you pass an augment called id so you want to delete user number one right and in return you just get an id right but apollo don't know what to do with that you know we send a mutation to delete user and you got an id back what should apollo do with that but in previous case you know update it can update the cache but in the delete case that particular object might be referred from several other places right so apollo can't guess where it has to delete so it's our responsibility to give more guidance so this way things get complex in the sense you know in addition to the passing the mutation and variables right we have to implement a method called update right and in this update have three steps like first again apollo cache stores the data in a separate format we can't directly read the data right the only way to read the cache is reading the query so to read the cache we'll pass a query right and we'll use cache.readquery and pass a query and we get the user's data and we want to delete a user right so we will filter we'll iterate over the users and delete the user which we don't want now we get new set of users and we'll write it back right so we have three steps and this is a simple case right things can get complex let's say you have a role based application where you know you have users who have roles like admin super user and user right and we have different queries to get this data the moment you use you delete a user you have to update these queries as well so the previous query the previous logic which I have shown is for one query let's say you have to implement the same logic for three more queries right so you can see it's already 20 lines of code and it can be a hard tedious and it can be error prone as well for example let's say someone else is adding a new feature right and they added a new query they might forget to add update method in the world features right and it cause lot of problems and inconsistencies so manually implementing the other way of doing instead of implementing the update method is refetching all the queries again manually specifying which queries to refetch is also tedious and it has the same problems as this right so can we automate it right instead of manually implementing the update method which we have seen is quite verbose can we automate it so again previously I have shown an update record method where we are passing type name and that API looks good right and can we have the similar API for this when I want to delete some particular object all I want to call is like call some function like delete record pass the type name and ID that's all I want to do right so the rest of the logic should be taken care by the delete record method but Apollo doesn't provide it can we implement on our one so if we if we can find out all the queries which are related to user so I'll show you a demo so you can see here right currently there are two users right and when I add a new user and I assign a role as admin you can see the moment I add a role as admin here this list got updated and if I go ahead here and change the role to user you can see this particular section of the UI got updated right and if I delete something right you can see that the user from this section got deleted so the UI is interlink and to implement this we have like four queries one query is to fetch the users from the server and we have three queries here one query is to get the list of admin users one query is to get the list of super users and one query is to get the list of users right so how can we do that as we discussed so till now like doing that manually and manually specifying the update method or manually specifying which queries to fetch is tedious and error prone so how can we do that automatically so we wake today morning and we can use some tools like AST traversal and GraphQL schema introspection these are the some of the features of the GraphQL and we can use these to automatically identify which queries need to be automatically updated so so this is a simple GraphQL query so the entire query is called a document and inside if you see whenever you see a curly brace it's called a selection set right anything within the curly braces is called list of selections and the first one is called the field again it goes on so it has a predictable structure right and this is very basic query the AST of that particular simple query looks something like this it looks daunting but it has very predictable structure so that's what AST is for right it takes the ASTs takes the human readable code and converts into a much more complex structure but these complex structures are friendly for programming right so today morning we have seen how we described how we can use the ASTs to write Babel plugins and ESLint plugins the same concept applies here as you can see for the previous queries we have selection set inside that we have selections inside that we have field called users right so so the next part is like schema introspection right so so this is the query which can be used to get the data related to the schema right and so in this case you know we can get the list of the fields and the types of those fields right we can combine these two things to automatically find the queries which are related to users and in addition to that Apollo tracks all the queries in the app for example as you are using the app Apollo keeps fetching the data from the server and it also tracks those queries which it has already executed so Apollo has a list of the watched queries and let's say you want to delete a user so from the list of all the queries we have to filter out the queries related to the user right so we can use the AST concept iterate all the queries find the queries which we have as field users right if we have any confusion related to the type of the fields we can use the results from the introspection once we have the list of queries related to the user we can implement a generic update method right we can iterate all those queries and implement the three step process which we have done read the cache do whatever modifications we have to do and write it back right we can automate it the challenging part is finding the queries related to user for that we can use the AST introspection so the same problem happens for create also right when we are creating right it will have some side effects right those things should be updated for that also we can implement the same logic similar to delete record so the next part is subscriptions subscriptions is little bit hard to implement subscriptions are used for real-time updates it has like a lot of moving parts like you know whenever you change something on the server with mutations if you want to implement subscriptions we have to publish those changes like let's say you added in user you publish that right and you have to implement a subscription resolver in that in that resolver implement authorization so on so forth right on the front end you will write a subscription query right and again this subscription has the same challenges which I described for the delete and update right this subscription will get the real-time updates from the server but once it gets the real-time updates from the server Apollo don't know what to do it if a new user got added what should Apollo do it doesn't know right so here also the challenge of you know implementing the update method happens but you know we can so we can use some of the methods which we have developed but still it's verbose right and it requires a lot of effort to implement these subscriptions and you know it also causes performance for example in our application we have 30 tables and for each table we have three subscriptions one for delete one for update and one for creating a new item like if you have 90 subscriptions the performance of the app will grow high the more than number of subscriptions we have the bad the performance of the app will be right so there's an alternate proposal called live queries right so the idea with the live queries is we have a regular graphical query and we'll mark that as an live right so without implementing any logic the library which we are using should take care of keeping this data in sync with the server if something changes on the server client should automatically get updated right without writing any code that's the idea or algae so this is still in the proposal phase which is not yet confirmed or there are no implementations available but in our applications we had to implement it on our own because you know we have a big application and subscriptions are not working out for us so we went ahead and you know started implementing on our own live query system so the implementation will look something like this you know whenever the clients are querying the data from the server we wrote an extension which keeps track of all the objects which are sent to the clients right we'll store that in the send radius when the clients are sending the mutations right we'll use database trigger to identify those changes that are happening right so we'll use this to information like the objects which are stored in the radius and the triggers and based on this we will write a efficient subscription single subscription to keep the data in sync so the beauty of this architecture is we have decoupled our you know data syncing logic from our business logic right so it's kind of a one-time effort we'll implement just a single subscription instead of having like hundreds of subscriptions we'll have a single very generic subscription called onchange which will get the data action this action could be either an update delete or create right so it can be one of these three actions and data is the actual data which is changing and type name and id so with this just single subscription we can keep our entire front end in sync with the backend again yeah Apollo is mostly good things like mutations and subscriptions are a little bit hard but we welcome them with you know implementing our own systems like you know update record and live queries yeah so that's all I have so if you have any questions you can reach out to me at kirana underscore abori do you have any time for questions okay catch him he'll be here or outside somewhere alright so we have reached the last part and we have come to our last talk so you all know that if you have taken any photos or you are tweeting or something and the hashtag is hashtag react poo so please use that hashtag to post on social media so we have the last speaker for today Shrekan GS so he will be speaking on building a highly scalable exchange to react or not to react yeah so he'll be on the stage hello hi guys give me a sec so that I can set it up hey guys good evening and welcome to the last talk of the day so I am Shrekan GS I had technology at a company called operations private limited we are a 30 odd crew and we are also a fully owned subsidiary of a company called bill desk some of you guys might know about the company it's a largest payment processor in India so before actually getting into what we used to do or what we did I'll just give you an insight on what we used to do before this particular product we were into the BFSI and fintech domain and payments so our expertise were into payment processing and such kind of typical areas but we kind of deviated from all those so we kind of deviated from all those when we were kind of interested in the cryptocurrency domain and that's all this is about and when we got interested in it we thought okay we'll just go ahead and make a cryptocurrency exchange it's not very difficult to look at it's just something like a single page application you can just go over and make one and then we had some level of expertise in the crypto links as well so based on that we thought okay we'll just go ahead and make one this is me in a nutshell I kind of travel I can decode and I can manage stuff more of a technologist and the last part is what I am right now a crypto evangelist so what this presentation is not it's not going to be a coding exercise I think there will be like very very minimal or at least one slide with the code it's not a programming tutorial you are not going to gain any programming knowledge out of this and it's not a technology recommendation I can't react or any other particular stack as a takeaway from this and there is no demo it's going to be me talking most of the time and it's more about it's about self learning at the end of the day you kind of forget to look into what you did and how it impacted a lot of customers and your own developers and also it's about the retrospection on what you did and what you did wrong and right that's all this is about that's the whole presentation is about that we built a cryptocurrency exchange and it was during the whole boom and in 2016 early 2017 when the wave was happening the whole cryptocurrency wave and then we were like wanting to catch the wave as well so we built something like this this is roughly the screenshot of the product just to highlight it has a lot of data and the whole exchange concept if you have ever traded in a NSE or a BSE stock exchange through any kind of broker Zerodha, GeoJit, Sher Khan whoever it might be you might see that the whole dashboard is filled with data and all decisions are made based on the data and if you don't get those timely data you are kind of on the wrong wagon altogether so this was our initial stack we used to write Ruby on Rails for like years probably a decade or so right now and in the prior company everything we used to write Ruby on Rails so it was a first as always you know we don't ever think on what to use for a stack it's Ruby always and then we use Ruby on this the entire deployments were on dockerized so that was an experiment which we took instead of the traditional kappa strano based deployments we used a dockerized deployment model this was a whole experiment that we took at that time it kind of really really paid off and then the orchestration was done using Rancher so Rancher currently the 2.0 runs on Kubernetes but earlier it used to run on its own cattle framework so Rancher is something that we used and the last two part this was brilliant you know we would ever go back to something else this is something so good but you know this is the best part writing on Ruby on Rails it's very easy you know it's one of the best backend stack you can use to write on stuff and we had the shortest time to market we actually wrote code for 6 months or less so it was like a huge short time to market actually and things went pretty well until the side of the story you know the people come you know the whole customers came in we never anticipate the flow of customers like that you know when you write good product and then you tend to push it to the market and then what so happened is that we did a good PR so that was a good thing and the company that is owning us they did some kind of a backend work as well to promote us and the whole thing paid off so we went up and had the best thing to face ever which is the 3.0s and it's about scaling and the user experience and availability you know you kind of tend to couple scaling and availability is something totally different actually availability is about what your customers actually sees you know they don't really see scale they only see the availability of story and the experience and scaling is your worry your customers ever get to see scale at all so what went wrong you know the very very simple thing the stack couldn't scale the rails view rendering wasn't really efficient because when we used to do the fintech and payments the transaction you know it had its own flow it had multiple tags and there was asynchronous behavior in it it used to go through banking and then come back from banks as a redirect all those flow used to be there and in that time we got that time you know between the customer experience there was a lot of time and that time played good for us but in this case we didn't have time customers needed that data instantly and we had to show it to them because if they don't see the right data what they're going to end up is with an opportunistic loss you know so we can't really blame ourselves or the customers can't get the right price at the right moment to make the sell or buy decision but then again that's what the problem is you know you shouldn't ditch your customers and give them wrong data right so rails view rendering wasn't efficient we just had jQuery in front and that was like the simplest thing to go ahead with we just had plain jQuery vanilla jQuery and rails were back in and this was in the solution you know and then we faced the business horror which is this EU asking me what went wrong and then comes the three-letter word that they always tend to put on emails RCA they need the root cause analysis of everything and all the CEOs out there they don't get the tech but they just need that RCA you know with lot of stuff so yeah we gave the RCA it was heavy long running SQL queries the main evil out of that and we didn't have efficient caching a very natural thing for a small product which was kind of cooked up in six months and then we had we were throwing final to bad gateways to our customers just like that it was like people would just type out domain and then they would see final to bad gateway engine X a proxy running it on front so we didn't have any way to let the customers know that we are down so what happens here is that unlike a banking industry where you put your money in an SBI or an HDFC or any other bank and you believe that when the net banking goes down you don't really think that HDFC looted your money now you just assume that it's out there it's in the bank it's in the branch so you can walk into their bank or maybe if it's like you can tie UPI you can do imps you can do any channel get your money back but when a cryptocurrency exchange which holds the people's money goes down the immediate thought they have is that we looted their money and ran away because that's what you see throughout the globe you know mongogs and every major exchange out there they face this challenge all the time you know people run away with people's money and there is no trace so when our website goes down it's more than the availability it's about the trust that's going away you know people just assume that we ran away with people's money and then again it's about the data you know a trading app or a trading exchange it's mostly a single page app you know when I say mostly you have other pages which actually takes care of deposit of cryptos withdrawal of cryptos all those fancy stuff but most of the time people kind of stick on to the page that you saw earlier sorry this one you know people kind of stick on to this page where you kind of see the you know the markets out here and the personal summaries out here and this is an order book you know you kind of see the sellers and the buyers listed out and on the right side that's a trade history so people kind of worry about this you know this is the decision logic where they see the trade history and this is the open orders by your cell and based on that they kind of tend to make their own decisions and the whole thing is about data so it's almost a single page app most time is actually spent on the trading and data is extremely important if you have ever traded a cryptocurrency trading in on any platform you would really wonder when the bitcoin actually shoots up to 18,000 dollars and come down to 4000 dollars you kind of panic and you kind of try not to die so that's how it is and it's real-time updates customers make decisions based on data again so real-time updates when you kind of drill down it's mostly web socket updates the servers actually throw the data through web sockets we kind of display through charts and graphs decision is based on the candlesticks and all those kind of fancy graphs Fibonacci graphs and all and all the etc. requests that's firing back and forth along with events alerts and notifications you know you have to give customers all these life cycle data whether the trade was successful whether the order was well placed all these kind of miscellaneous data so this is the nutshell of the data we have to give customers on a very very aggressive basis and this is the problem at hand scaling it's a mammoth task you can't really assume that you can throw hardware at everything and scale you know that's the starting point when we had something like 10,000 plus customers on a real-time per second basis and we had to throw hardware at the problem it didn't work technically saying we were so bad that we had a 64 core 512 GB DB instance and it couldn't handle the load and that's so pathetic you know we really have to admit that that's how bad it was and so splitting it into the you know chunks fixing the SQL queries that's obviously problem that you have to look at caching of responses and the last thing I'm here to talk about it's about decoupling the front-end you know the customer should experience a totally different experience compared to a traditional Ruby on Rails app so fixing the back-end issues this is just a single slide stuff about what we did we fixed the SQL query the obvious thing to do we moved it to Amazon Aurora which kind of gave us a 3 times more performance than I opposed gray we cached the requests and data we used Memcache and Redis it was good as well lot of stale data you kind of make lot of lot of data every single order that was placed every single transaction that went through every single trade that happened you don't ever want to go back to it it's historical but customers want them so you kind of move them to ELK stack the Elasticsearch stack and the final part you know the ugly part which we really did not want to do but I'm a Microsoft fanboy so I kind of push c-sharp you know I get to have that top-level approach of things I push c-sharp and it actually did pay off we did the complex weightlifting through c-sharp and .NET so that's the stack we are trying kind of moving to f-sharp right now this is the javascript part of the story we had to do simple you know manipulations we had to show the customer data handling of event cycles which was the data coming through web socket we had to present it to the customer and remove it when it was stale you know when the trade happened you had to remove it from the order book or else customers would assume that there is still a buyer or a seller out there this was what we used to do we used the coming bundle with rails and then vue.js for simple data bindings this is when we actually stepped into something other than pure jQuery we had something for the data bindings so this is the limitation of the setup you know you might obviously be getting it it's cluttered and spaghetti javascript code you write more and more and more javascript code and finally you have no idea where to touch it's so ugly that you kind of ditch it and then rewrite it everything again there is never ending conflict across multiple frameworks and vue and jQuery had some kind of conflict between them and they were quarreling every single time like your mom and dad so this was happening more and more the frontend was still tightly coupled with the backend because it was still Ruby on rails again you know you kind of assume that it's something totally different you can imagine it is different but still it's the same thing again vue rendering was a toll on the app server you know we used puma underneath and then along with the nginx but then again the whole server side rendering of the whole frontend you know we just so we decided to decouple the frontend and deciding on a frontend framework that's the most challenging part you know you have a lot of contenters out there if it were just one single framework out there it would have been so nice and easy and your problem would be like over okay I have this I'll just pick it and make it use of it now you have vue you have react backbone angular I think there's more I don't know more stuff so that's all that things that I know so we had that and we had roadmap for mobile apps in it was early 2017 so we didn't have mobile apps we had a roadmap for mobile apps as well we wanted have android and iphone apps so that was also one of the reasons for choosing the frontend this is what we finally came down to we had vue js as a contender and the react this is the very very very traditional comparison study which we did finally this is I don't even think this is relevant anymore but back down in 2017 it was very much relevant there so you had a lot of good parts you know we had it was very lightweight you know when we use the data bindings part of the view it was very very lightweight it had much better documentation you know it was so well written that we were in love with the documentation it was really easy to integrate the plug and play behavior of vue into a traditional html app it was really really good but then again for react we had a lot of benefits around as well you know the pure javascript nature of react that was one of the most lovable things out there which had a really good community and the last part you know this is something that the cto always tends to talk about it's about the hiring you know you have attrition in your company people walk out you know you need to have that talent pool coming again and again and for that you need to have find the right stack you know you can't just assume that hey you're a full stack developer come do whatever stuff you want to do people just don't do that anymore so react had better talent pool at that time again 2017 this is the shortlist we chose react and it was because of extremely good javascript library support and the exceptional talent pool which we could hire and the last part the react native for apps vue also has come up with something good but then again at that time react native was kind of really robust and it was a really good option for building native apps as well this is when the whole problem started you know you just tend to be at the top of the food chain and then you assume that your developers will immediately learn stuff you recommend to them and then they'll use stack immediately you know you tell them react yeah you get it in a month you tell them you you get the month you know that's what you assume that's not what you get eventually it was too minimalistic you assume that's a good point that's really bad point not all your problems were taken care of you had to figure out what is the right piece of the react which you need to use for the right purpose you know if you were to choose angular you had the whole framework coming with you that's what we had with rails as well it's there you need something else that's there everything is there you know but when it comes to react everything is there but you need to figure out what to use with what and you have God knows no way of identifying what is going to have a conflict with what you just assume that they're not going to fight each other the concept of a state store was new you know until then when you use jQuery or even to some extent view you were throwing state around you know state was there which was actually associated with a single element or a component and then you tend to store there itself you mutated you play along with it it was all imperative in behavior you know you kind of go with the flow if it happens it happens you know and that was something new to us the single state store that was something new to us and the one-way data binding was extremely challenging I'll say what it was good or bad later but it was extremely challenging you know earlier we could just pass data it's our god damn framework you can pass data from one component to another who's actually stopping you but in this case it was you know the hierarchy it was a parent-child approach and that was quite quite difficult to digest to start with and not so good documentation again you know you have queries you have difficulties you have all your problems you know if you were to use traditional Ruby on Rails or Python or anything the documentation is so well done you kind of go back to it and then okay do a half-day digging and you kind of get what you wanted to know in the case of React that was not the story oh my god this is where I had a lot of fights with my developers and engineers they really did not want to write JSX you know they were like HTML ERB we are fine with it we might even write Hamel for you but we will not write JSX for you how much of a good it is whatever good nature it has developers were like totally against the idea of writing JSX and I had to push it down them so this is where I have personal retrospections and self-learning as well you know you shouldn't push stuff down your developers throat it's really really bad to do but then again when you have business pressure when you have a necessity to bring in revenue customers breathing down your neck as demons you have to give them that you know you have to push your developers to do well this is bad but this is the learning part you know you kind of go down the approach for one year or two year you can improve yourself and give better life for your developers so in difficulty and inertia learning JSX it was extremely painful for them but they kind of learned it the good part so we had components components and components everywhere the whole thing was cluttered earlier now you have beautiful separate separate small components you know the trade history that I showed you the sell order book the buy order book everything is a component right now you want to put it in two different pages we can do that it's very easy you know it's a component they are not going to fight each other it's a totally decoupled self-sustaining stuff out there you know reusable code with single responsibility you can use single responsibility as a magic word everywhere when you write you know Ruby on Rails as a backend stack single responsibility lean methods and you know never touch fat methods more than five lines of code and you can break it down it's not really easy to go for that approach anymore so we got that actually when it came to react we got that single responsibility thing coming out very nicely it was very easy to manage as I said you know you can decouple it and you can throw it around like balloons and then it just worked without any or very low side effects this is what was the magic part of it you know earlier it was side effects side effects it was everywhere actually so you kind of update something something else update somewhere else you have no idea it got updated then you kind of tend to update it again and it wouldn't just work and then you go to the console and developer console and everything and you kind of try to figure out if there is any console.log the developer actually wrote which he did not obviously then you kind of juggle through the code and try to figure out where the problem is we didn't have that anymore you know the at least to some extent we didn't have that anymore so there was little to no side effect at all so this is something that's nice to have you know as I said there's no code this is just fancy writing out there because you guys would love to see some line of code at all you know the pre tag out there so this is some code so we had components for the trade history it was clean you know it was just 6 or 7 lines of code to actually manage the whole trade history part happening we did a pusher road subscribe out there get the data through a pusher web socket yeah we moved to pusher by the way as part of the scaling because the action cable couldn't handle it we moved to pusher as well so the trade history channel is binding to a standard component and then you throw the trade history items into a dispatcher and then the dispatcher kind of takes care of it it presents it beautifully on the trade history page very nice this is what we got this is something that we did not have this is something that react gave us again the good part clean data data which is better handled there is a single storage of data so when it comes to mutation you don't have to worry that you have you know ugly states thrown around or ugly data throwing around it was at one point so if it's ugly it's only ugly at one place you don't have ugly data everywhere the one way data binding the hierarchy part is something that we love now you have that parent child approach so your perspective kind of improves itself on designing you know earlier when you had to build something you tend to build it as and when it happens you have no approach or a perspective on what to build and how to build you know you don't have that foresight you need a trade history table okay I'll just put a trade history table there it just works right nice nice so that's what it used to be but right now we'll just think where is this trade history actually being plugged into who's the parent of it you know who how is the parent gonna throw data into the child is it gonna be stuck there is a trade like the trade history table ever gonna push something back up the parent which you need to think about already is the props and promises doing work fine all those kind of thoughts came into the whole as well the last part you cannot accidentally pollute data so it's a good thing but I totally disregard that I'm a person who always choose freedom over some kind of a compulsory behavior because one of my friend had a react ML talk last time here so he was talking about variance in react ML you know so what he kind of pushed to everybody was that this is the only right way to do it and react is actually not gonna let you do it any other way and I was totally opposing that idea I'm not I'm not a developer or a program who likes that you know I should be the person making that choice what is the programming language telling me how to do right stuff and wrong stuff you know that's what it used to be till we had the problems I kind of tend to agree to him at least 50% he shouldn't be hearing this at least so you cannot accidentally pollute data data pollution is a total no go and that's the best part we had as well the invisible DOM so earlier what do you normally do document.getElement by ID you kind of kind of tend to manipulate it by hand you have jQuery you put the dollar out there and everything works right so the DOM suddenly became invisible to us we didn't touch it directly so that's a good part the declarative approach you know we coming from an imperative style of a language which is Ruby on Rails the declarative way was suddenly something new to us because we are stepping into functional as well the F sharp side of the story and to some extent react ML and OK ML so the declarative approach was something new to us you know you tend to forget or you tend to purposely ignore how to do things you know you don't think about how data flows anymore you don't think about what is the mutation that you need to accommodate you don't think about what data state you have to change so that you achieve the result you just think about what is it supposed to be there what is your customer going to see is he going to see the right-right history is he going to see the order book is he going to see a red and black color is he going to see the green color out there so that what a customer sees or what is the experience that he has to get that approach was something totally new that react gave us as well so this was something that F sharp was also trying to give us but this was most striking when react kind of forced it down you know the declarative way of doing things you do not directly touch the DOM anymore you know that's taken care of by the framework updates are bashed and automatic because earlier when I said that there is a trade history which is actually the decision logic for all the customers to make their you know decisions again so that was like 13 DOM updates now when a WebSocket data came in we had to throw 13 updates for all the elements because the price up there on the ticker that had to change the trade history summary had to change and order had to be removed from the sell order or buy order lot of stuff the graph had to change so there was 13 DOM updates which was happening for every new trade history that was coming in or a trade that happened this just happened to be magically one you know the dispatchers kind of took care of it all the 13 updates kind of went magically invisible and we didn't have that kind of a personal performance degradation anymore you know updates are bashed and automatic think about what and not how this is what I said earlier you know you kind of totally have a different perspective running in your head you forget or purposely forget how things are to be achieved you kind of think about only what to achieve rather than how to achieve lines of code came down this was clean you know peer review became easier and then your code review part became easier the CICD part became easier tests became easier you have no idea what like everything became easier and that was magical you know you have hundreds of lines of code coming to few component decision made code smaller so you have small components and then naturally you can reuse it naturally you write less code legacy JavaScript code wasn't reusable obviously it was cluttered it was ugly it was more like noodles out there there was no way to debug or test now test became much easier you could have small unit test and then you could have even bigger integration test out there and that was much easier as well it's decoupled and self handling you know self handling and self sustaining each component rates right now self handling and self sustaining earlier you had to kind of meddle with it and made sure that it worked right right now it just we just assume it works right because we write the right way and then it we just get it that it's working right MVC to pure API so when I say MVC and when I say pure API even API is MVC only we have the controller we have the view throwing the JSON data but you know the experience what a user sees or like a developer sees it's different functionality was extremely interval with view you know you tend to tell the developer use controllers properly you more use model properly but then again when you had to show things in view you know you had to have that helpers and all those elements which had to tightly couple into the business logic altogether so functionality was really interval with view single code base and hard to maintain you are writing lines and lines of code and then you or your developer kind of quits another guy comes up and then knowledge transfer you take three months of the first developer he's not going to agree for a three month notice period you have one month and of that one week he'll have some kind of an illness the rest three weeks he'll have laziness so your KT is going to be extremely delayed actually there is no KT altogether you just assume that the next developer comes up and figures it out magically again which doesn't ever work but that's what it is all these days anyway so that was easier you know you had smaller code base at least when all these troubles add up your new developer will kind of kind of assume to get it much faster than the old developer anyway transition to pure API everything returns data so this was good for us because it was good for testing as well we had a lot of testing framework out there so for all these testing frameworks a pure data testing is much easier than going through a selenium framework which used to test buttons and views and view elements you know actually assert that the data was right to assert a data is right you have to test the data right why are you testing views which we used to do right now we are just testing data we are not testing that whole view element anymore view it goes through an independent testing altogether you can be anything web or mobile this was good for us this was an added benefit it was a truly added benefit but it came along with it so view can be anything reactive so we haven't started using it yet when I say one year down the line this was the reason why we kind of this was probably the plus point that we gave to react compared to view no we haven't used it yet we have written the entire web and you know the android and iphone app it was objective c as always and it was java as always so we are thinking about using react native small companies these mistakes you always tend to make you assume that you can start using new stuff but you can't you don't have people working on it and you don't have the knowledge for that as well future apps in react native as we are just promising the stock might actually encourage my developers to actually agree on to that so future apps in react native pure api model compliments this approach this I'm certain you know you just don't have to worry about ugly stuffing of data along with functionality this is going to definitely compliment the approach frontend developers can actually collaborate earlier frontend developers were like some kind of an aliens out there sitting in the same company but had no clue what the back end guys were doing anymore they can collaborate well with the back end developers because the back end developers are just throwing data they have no clue what's happening in the front end earlier they had some level of control and that dominance over that front end developers the front end developers were just UX guys who used to build pretty UX they didn't have business knowledge they didn't know what is going to go where right so they were like keeping aside these aliens out there having some kind of a wall between those two guys and then there were two different teams all together all the egos coming in you know now it's not there you know you need your front end developers to do something you can't just present the raw JSON data to your customers they're not going to agree to that right so you need your front end developers there is some kind of a collaboration and that harmony that is coming in which is very good for a good engineering company UX and apps coming under an umbrella that's a yet another story right you have your app team which talks something totally different when you have a Ruby on Rails team which is actually talking all the magic out there which I totally hate but still Ruby on Rails giving all the magic out there your app team guys are still stuck with very legacy code base of Java and Objective-C right you have that verbosity coming along with it which nobody should talk you know totally my friend and engineers don't really want to talk on Java and Objective-C anymore you can probably supplement it or complement it with Kotlin and Swift still it's the same ugliness right so that's where React Native might actually help my app team will also come talk to my backend team and the front end team they are not aliens anymore you know I have around 30 people of that around 5 people as app developers front end is around 4 people and the rest is backend and all these 9 people they were aliens so far they are not aliens anymore they are coming and talking to the backend guys and the front end guys they are partying together they are going for meetups together so that's nice that's very very nice for the company benchmarking so you need proof right at the end of the day when I give an RCI to my boss the CEO out there I need to give him proof that I did something wonderful to actually improve the product I can't just say that okay you have to assume that everything is working good and better till the new customers come in and then have this whole scaling problem again I have to give him proof and also I have to give him proof to Zyna for example she wanted benchmark data so this is the funny benchmark data out there so we have Ruby on Rails with no optimization that was ugly 2.8 seconds for the page load and that is when customers wanted to make 10 trades in that 2.8 seconds I have no idea how they'll actually do it they wanted to actually they said high frequency trading, API calls and all those stuff all the fancy stuff they wanted to make 10 trades in 2.8 seconds they could only make 1 so that's 2.8 out there with back end optimization just the SQL and the Aurora and all the fancy caching we got 2.03 and with the react front end we just did this as an experiment we did have a lot of time so because of the RBA and the stuff cryptocurrency is kind of in a very bad state right now in India the grey area so we had a lot of time we don't have a lot of customers around with us we're hoping that will change in another month's time but still we had a lot of time so we just did ok we'll just throw away all the optimization just test how the react alone could do you know could handle it it was far better it was 1.8 seconds around 23 seconds comparatively lesser than a pure back end optimization so that is proof that is proof to actually give effort and put money into and put the bet into having good front end developers who can give you better products that's a guarantee that I'm giving to the company and along with all back end optimization and front end it was less than 50% each you know 1.07 seconds this is not good by the way this is not a credit for me it's really bad right now 1.07 is still bad but when you come down from 2.8 it's still a credit you know I can tell my engineers that I brought it down from 2.8 to 1.07 but the target is it should be less than a second always it should be 0.6 0.5 something around that so this is the benchmark the fancy figures unsolved issues so this is still what I'm struggling with you know virtual dome is at times slow I have no idea why it's slow because I'm not an expert in react nor are my engineers it's really slow so we are kinda hoping that it's problem with react not our problem that's one easy way to get out you know it's react's problem it's not my problem we are still trying to prove that with view I have absolutely no idea but we are just trying to prove it that you know view is offering a better virtual dome than react we are still experimenting with it we are not sure if it's gonna gain any result probably it will come and tell us that it's your problem again not my problem upgrading and updating is not easy as expected we assumed that when you have everything decoupled when you have everything that is in a component model when you have everything in a small small fashion you can put it into a box and just assume that when the box color changes from green to yellow react version X to Y it just worked it didn't for most of the parts it did for most of the parts as well so you don't know but to some extent it's still ugly to upgrade you assumed that everything is gonna happen automatically it did not it's a decent trade-off to go with you know even Ruby on Rails 4 to 5 was bad 5 to 5.2 is still bad so it's it's part of the game high memory consumption we have no idea why that's happening 16.3 MB this is the client side browser memory that's happening for a single page app which is just throwing data around 16.3 is a bad number we want to take it down to 5 6 so we are still figuring out what is wrong with it so this is also an unsolved issue slow startup time 219 milliseconds this is on top of the old client loading that happened and post that so 219 is not a good figure so this is also a trouble for us this is actually the whole pain point of the all 4 items you know the startup time because customers expect as soon as the page loads everything works it doesn't so there is another 290 millisecond which we really want to trim down to 50 or 45 or something like that so these are the unsolved issues right now the learnings you know after doing all this bad stuff to your developers and to your CEOs and to your COOs being the CTO out there of a 30 member company and plus hardly 5 members who are there in management you have that upper hand you know you have that upper hand that most people are doing stuff that you are telling them to do so this is the learnings you know this is something that I personally got scale is not a front end or a back end only problem you tend to assume that it's a back end and then kind of ignore the front end or you assume that it's a front end problem ignore the back end it's not it's a problem it's a holistic thing that you have to look at it's a problem of front end it's a problem of back end it's also your emotional problem because you are one of the component of scale you assume that code is a component of scale no you are also one of the component of scale if you are not in your right senses you are not going to scale good customers tolerate informed issues not final tools this is specifically for us by the way not for everybody because for some people if flipkart is down for some time and final tool is throwing you tend to go to amazon and shop your favorite mobile phone you know you don't kind of panic and then go here right you don't call your support numbers immediately and then we don't have support numbers but then again you don't do that stuff you know you don't call flipkart just because their site is down people will actually do that to us so customers already informed issues if we can at least put a front end out there and which says that something is going wrong we'll come back this was nice you know we did do this with HAProxy and all the magic of 500s being covered with fancy pages it really doesn't work you need customers trust all together so customers already informed issues developer happiness is extremely important I have to go back home and sleep you know I don't want my developers who call it call in the morning and say that I am having you know a bad tummy I'm having somebody some issues and then they are taking leaves because they're scared they're scared of JSX they're scared of I don't want that happening developer happiness is extremely extremely important for a company which is small to sustain you have to you really really have to hear them out you have to figure out what is troubling them and you have to try to fix it yourself that's your job so initial learning curve can be future productivity this is something that the developers and myself learned after going through the initial learning curve and the difficulties JSX is good now even if it was difficult in the early days it's good now but you can't always trust that that's so right sometimes initial learning curve is not going to pay off you have to bet on it to some extent you have to assume that your developers will also trust you you know that is where your credibility if you stay with them if you are a manager or if you are an architect or if you are a CTO if you stay with your developers and if you give them confidence that if they are going to suffer you are also going to suffer you know if they are going to have a tough time and have to stay back at 8 o'clock in the night you are going to stay back with them if you give that confidence it will pay back it will that's where you know the whole experience can be made better between a management and the engineers as well the takeaways rewriting code base isn't easy we did that we took around a year's time and we wrote the six month code in a year's time six months we took Ruby on Rails we took a year's time for React and Ruby on Rails so we did that we really went through that effort not all companies can actually have that luxury you know you don't have certain companies don't even have money to survey for three months or four months and it's a really really good thing we had we had to say that you know we had that one year time to take an effort and rewriting code base when you're forced to do it decide wisely you know we were forced to do it our stack was not good we had to do well so you had to decide wisely we did not decide wisely I'm saying we really did not decide wisely we just went with React because it was a hunch it was just a gut feeling to go with React we should have done much more exhaustive research on what is good what is bad but then again we didn't do that so that's a takeaway you know you have to do that take that effort that advantage to yourself to actually decide on what is the right tool for your whole ecosystem React is not a one-stop solution it was just a fit for us it was good for us you know if we had opted for view I think we would have gotten comparable experience now nothing more to say that React is bad or view is good or maybe the other way around it would have been comparable so React is a good choice for us because it was something like a single page app and it was front and heavy for the customer's experience but if you are right now having a website which is actually not in any of these domain or directions you really don't have to go with React you know you can still go with Ruby on Rails there's nothing wrong really nothing wrong you don't have to be that hi-fi mumbo jumbo guy sitting out there in one of these chairs and trying to say that hey we are also using React you don't have to do that it's okay to use your traditional stack you can try Java code it's fine it's fine as long as it's about delivering you know if you can give something back to the company or the organization or your team members or if you are a company which is just made of developers if you are going to give back to something to amongst yourselves at least it's all about delivering it's not about using fancy tools it's definitely not about using React or view or one or the other it's definitely about delivering and it's about the personal satisfaction that you get after delivering it you have a timeline you tend to always forget about it you have a deadline you always forget about it because you have people you know who's going to give you a call at night and say that hey you did not do the commit yesterday night that is going to happen that's going to be there for really really long time but it's all about delivering so if you do that you are successful it really doesn't matter what stack you use that's all guys thank you very much and my name is Srikanth GS that's fine Twitter handle and any questions please and I'm sorry to say that I'm not a tech wizard so I'm very deep into react I might not be able to answer so if you ask me about how to run a technology team I'll actually be able to answer better any questions great that's nice I'm actually free of all the worries I thought you guys might actually ask me JavaScript thank you thank you all guys have a nice day have a great evening Zana is coming down to wind up the day so can you just be seated for like two minutes thank you