Sessions is temporarily moving to YouTube, check out all our new videos here.

6 in 1

Tasveer Singh speaking at Reactivate London in April, 2017
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

It's been a dream to support multiple platforms from one codebase, and to abstract their differences in UX to unify development. Taz has uncovered the holy grail of development for Web, Mac, Windows, Linux, iOS, and Android.


Taz S.: Thank you all very much. At this point I would usually ask if people can, at the back can hear me. But that's kind of a rhetorical question. That's kind of like asking a UDP joke, I'm not sure if you all will get it. Anyone? No? No? Not a whole lot of people got that one. But anyway, I'm Taz Singh, and this is the most hipster picture of me I could possibly find. For short, you can call me Taz. Spelled like that, not with like with an S or whatever. And I'm from Toronto, Canada. Where I've been writing various different types of software for the majority of my life. And one of the more relevant things I did over there was actually start up Toronto JS. [00:00:30] So of you're ever in town, check out one of our 35 events a year. We actually grew to be one of the largest developer communities in Canada. And few other guys from Pusher were actually there at one of our events so, good to be here in their office in London, right? Because we're kinda trading, they came to Toronto, I came to London. But anyway. Early this year I moved to London to work with a company called, Mainframe to build a next generation of communication software. And while I was talking to them back in Toronto, they told me that they actually build for a bunch of different platforms off the same code-base. And I'm like ... I'm a pretty sceptical guy, and I was pretty sceptical [00:01:00] whenever someone tells me that, I'm like, "Does it actually work? Like, is it any good?" Because whenever someone tells me something like that, I think of technologies like Java Spring, like Xamarin, like Flash, like Phonegap more recently. And they're all kind like this. They all kinda like this world-class rally SUV that can take on a harsh desert terrain. And at the next moment can take you through waist-deep muddy waters. And if that's not enough, it can plough road ahead of you with snow and even take you on that road. [00:01:30] And that's what they all kinda want to be, but in practise they end up being something like this. I mean, it's still technically and SUV, and they might be able to do some off-roading, but I don't think it can do any of the things I just mentioned, and is a kind of a shitty Pontiac Aztek. Certainly not a world-class rally vehicle. Sure it can take you from point A to point B, but it's not really a great experience while doing it. And if that wasn't making your eyes bleed enough, here's a high resolution side-view. So you can check out those sweet side-vented exhausts and like those chrome rims, and is that a rear tail diffuser I see? Is this thing [00:02:00] seriously generating enough down-force [inaudible 00:02:02] is actually be useful? I mean, whoever put this thing together must think this thing looks amazing, but for the rest of us, we're just laughing at them. And this is really a similar experience that I feel to those frameworks I just mentioned. I mean, whoever built those, whoever is using those, I'm sure whoever developed those thinks it's amazing, but for us users that actually using in them, it's just not quite right. And that's fundamentally because they're kind of these, "Write once, run anywhere" frameworks. What they want to do is, you basically write your code once, and the library itself will manage actually [00:02:30] targeting all the different platforms. And they generally don't quite do it in the right way. Sure they might give you some, "If, Else" statements or some sort of compiler macro so you can kinda drop down and tailor fit it for yourself. But overall, I haven't really been convinced with any of these, and I haven't really been using them myself. But that changed for me recently when I was introduced to React Native. So, React Native allows you to build apps for iOS and Android device using native APIs and UI elements, but is controlled via JavaScript and React. So some of the code, it might look like this, is a contrived [00:03:00] example, but I have a view with some styles on. I have some text with some styles on that, and it's a general React component but I'm not using divs and p-tags. I'm not using like HREFs and all that fancy HTML stuff. Views and text components and all of that type of stuff, these are the primitives of React native applications, not HTML DOM Nodes. And the style look something like this, so it's kinda similar to CSS in JS, but fundamentally it's using the Flexbox layout mode, not the Box layout mode that you might be used to in HTML. So [00:03:30] it's kinda similar but different at the end of the day. And if you're not familiar with Flexbox, a good friend of mine from Hamilton, Canada out together this series called, What the Flexbox. Definitely check it out. It was very useful for me when I was learning Flexbox. So check it out if you want to learn more about Flexbox. So now that we have a very basic understanding of React Native and kind of the primitives used to build React native applications. How does that actually handle multi=platform apps? I mean, how is this different than like, "Write once, run anywhere" frameworks that I've mentioned before? Well, it's a philosophical difference. I mean, with react Native you're kind [00:04:00] of expected to drop down and address the platforms individually. Like, you're not expect ... Like, React Native itself won't just handle all the multi-platform for you. You're kind of expected to do that on your own, you're kind of expected to know how that platform works and to address that platform individually. So it's not gonna just kinda cross compile. It's not some sort of shared library code. It's not gonna guess at what you want to do. It's up to you to explicitly do it on your own, and that's the difference between React Native and, "Write once, run anywhere" frameworks. And the way that it does this is by overloading simple modules with platform specific functionality. [00:04:30] And a very simple example of that is something like this where on iOS for example, you want the height to be 200 and everywhere else you want it to be 100, so we can pull in the platform API and if it's iOS we can say height being 200. So that's kind of a simple, "If, Else" statement that I kind of made fun of just now, but you can do that with React Native as well if you want to. A more complex example is something like this where we have different modules entirely for different platforms. So we can basically suffix the module itself with .iOS.js or .Android.js [00:05:00] and when we go and require that module, it will then load the appropriate file based on the platform that we're running on. We can take this one step further by saying just a generic bigbutton.js, so on iOS it'll load bigbutton.iOS.js everywhere else, so on Android it will load bigbutton.js. So we can kind of use the file naming to kind of target, which platform we want to ... We want that code to be shipping on and in this way we can target different platforms on React Native. In practise, we found that [00:05:30] very useful when developing our conversation view. I mean, this is a very complex view, and we started out with a React Native list view, but quickly found that list view wasn't really performing how we want it to perform. The scroll was all kinda screwed up for like a convo view. It's great if you want something to scroll top-down, but bottom-up it wasn't really performing. As a data changed behind the scenes, it was kind of like jumping all over the place. You want to be able to control that scroll in that view like ourselves. So what we did was we introduced endconvoscreen.iOS.js. We built an iOS [00:06:00] native component first and we can ship it just alongside the existing convoscreen.js. Then later on, we built one for Android as well, and we can just ship that on its own. But fundamentally, the caller doesn't have to care, its just loading a module at the end of the day. It doesn't care about if it's iOS or Android, it's just kinda loading a module. So cool. I just talked about iOS and Android. But if you just heard, [Ellie 00:06:22] just now, or in my talk description, I talked about all these six other platforms. So how are we actually doing that for all of these? How [00:06:30] are we actually targeting web, Mac, Windows, Linus, iOS, and Android? I mean, I'm sure you can imagine like those platform differences are absurd. I mean, the basic example is navigation, and on Android ... There's a hardware back button on iOS that's generally handled via software. But on web, there's a back button, there's a forward button, there's a refresh button, there's a URL bar, and there's a history drop-down. All right, so how are we handling those types of concerns from the same code-base? There are hardware differences. I mean, some devices might have different hardware than other devices. How are we handling that [00:07:00] within our code-base as well? There's user input differences. I mean, MacBook Pro has just introduced a touch bar. How are we handling that user input differently on some platforms but maybe other variations of user input on other platforms? And we haven't even talked about screen sizes yet. How are we creating the same experience for a mobile phone as we are for a large desktop display kinda like that one? That one's pretty big. And there's a whole myriad of other cross-platform issues such as linking. External linking, deep linking. Access to hardware which available everywhere but web. Notifications [00:07:30] which are implemented differently. I mean, there's a whole bunch of other issues, especially online, offline. Although might have a solution for that now, thanks to [Yani 00:07:36]. But it's obviously quite useful when you're ... It's quite important, sorry, when you're talking about mobile applications that are constantly changing their connectivity. And so you might be thinking, "Isn't React Native only for mobile? I mean, how are we ... Like, what? How are we doing this on anything else?" And yes, you are right. React Native is only for mobile, but React is super powerful. And [Sebastion Mark Beige 00:07:59] gave a [00:08:00] talk a little while back about Don being a second class citizen. So can we kind of use a constants he was talking about in that talk to bill something like React Native for everything else? Like, can't we just build that ourselves? Well, the good news is that we don't have to, because this guys, Nicolas Gallagher did it already. He built React Native Web. So what this does is it basically provides the same type of React Native primitives like views and text elements, and image tags, and all that fun stuff. And you can use that to build your app, but that will drop down to like divs, and p-tags, and all that fun stuff that we have [00:08:30] in HTML. And so you can technically create an entire experience using the same code-base that will just drop down whatever platform that you're building on. And like, I'm not sure about you, but I'm a sceptical guy, but when I heard about this, I'm like, "This guy was drinking or something when he came up this, because it must not be very stable." But it turns out that Nicolas actually works at Twitter. And is built off of these technologies. So if Twitter has enough confidence to ship this to production for their entire user base, it must be pretty solid, right? It must be pretty good. And so we thought we'd try [00:09:00] it out. At this point, I can see a few of you are a bit confused or a bit like, you don't really know what's going on, and like maybe not quite sure about all this. So lets just do a quick recap. So to recap, we started out with React. So, React is a library for the web, it was built for the web and they initially shipped it for the web. And then from that, we came up with React Native. So that's the mobile library, it was based off of a web library. So now we have React Native Web, which is a web library that's based off of a mobile library that was initially [00:09:30] based off a web library. All right? So, everyone with me so far? Okay, I see everyone kinda ... They're not confused anymore, I just cleared that up, which is great. Thank you. All right, so now that we kind of talked about the UI and how to tackle the UI part of this, how does this actually execute? Like, we know how to build the UI, but how do we actually run this thing in all these different platforms? I mean, it's a different environment on literally every single platform. How do we actually execute this? Well, the good news is for iOS [00:10:00] and Android, we can just use React Native. They have a great bundler, they have a great packager. We can just package everything up using React Native and kinda ship it like that. With web, we can use traditional tools such as React Native Web, React DOM and Webpack. And we can kinda use that to package our app for web. But there's no such thing as like MacOS Native, MacOS React Native or Windows React Native, or Linus React Native. There's nothing like that. So how do we actually run on these platforms? Well, the good news is that there's something called, Electron which basically just wraps [00:10:30] Chrome within a desktop window. So therefor we can target those platforms by basically just wrapping our code inside Chrome, which is already supported via Web, and shipping it for those platforms. And therefore, we can use React Native Web, ReactDOM and React Webpack again, on top of Electron to target those platforms. That how we can actually execute on all of these different platforms. So then, how do we handle the cross-platform specifics? I mean, I went over how React Native does it, but how do we handle that for all these other platforms where don't have React Native? [00:11:00] Well, the good news there again, is we can do it in a similar way to React Native. I mean, since we're using Webpack, and Webpack you can configure to do anything on the planet I'm convinced at this point. It has this resolve order. So, on MacOS, we can define a resolve or kinda like something like this, by saying, "macos.js. Look at .macos.js files first. Then look at .desktop.js files next. And then look at ordinary .js files." On Windows, you can do something similar but prefer .windows.js before desktop and ordinary .js files. And we can use this type of approach [00:11:30] to kind of address the whole myriad of platforms we want to address in all combinations and whatever modules you want to address, in whatever way. Because Webpack is super configurable as I mentioned. We can also then alias things like React Native Web to React Native. So when we go and require React Native, it's actually requiring React Native Web. And in that way, we can use literally the same code, just re-alias them and we can like ... Literally the same can then just require modules appropriately. And we can do this for any other platform dependent modules such as maybe, a notifications library or whatever. We [00:12:00] can just alias them appropriately to either no-ops or platform specific versions. So an example of this in practise, we can take ... Like, let's say, linking in React Native, which is used to link externally to like, URLs and stuff. Linking.js can just be a re-export of linking from react Native itself. For desktop, we might want to use Electron's external linkings. So basically just override the open URL function and open it externally via Electron. And on web, you might want to open that in a new tab. So we can do that with a linking.web.js and just open that separately [00:12:30] in a new tab. And what we found is that this is great for the bread and butter of our application. I mean, the vast majority of web developers, let's face it, we're building forums all day. We're putting data in lists all day. I mean, we aren't building like the world's most interactive, crazy OpenGL thing. We're just putting things in other places. That's basically what we're doing. And we don't really need native languages to do this. In practise, we found a lot of our time and energy goes into making these views, and on the surface level, they look kinda simple but underneath that, [00:13:00] they're kinda complex. There's a lot of business logic going into this. And since we're able to share code across platforms, we can write the logic once in React, which I love. And an immediate client impact across the board. I mean, basic JavaScript and components can solve this problem and address every single platform that we support. Would you rather build something in React, or build something in some MS Objective-C garbage? Or build something in some public, static void Java bullshit? I mean, really? I'd rather just write in React. I wouldn't want to drop down to any of those languages. [00:13:30] And so, cool. We've gone over how all this stuff works. I've kinda shown you the UI layer, how to physically execute it. Gone over kind of like how to link and like how to override certain modules and all that fun stuff. But a question I have is, why does this work? Why does this work on React, but didn't work for all those other like, "Write once, run anywhere" frameworks? I mean, surely they can just do kinda like some sort of module overloading thing as well? Why doesn't it work ... Why dies it not work for them? Well, one of [00:14:00] the reasons I think, is because of the React Component interface. And here's kind of a contrived example, but we have a platform specific mobile JS file, where we're doing something on mobile and then we're inserting that into like some sort of view. And here's some [inaudible 00:14:14] on the web or doing something on web and inserting that into a div. And fundamentally, those two things are doing like whatever is appropriate for their platform. Doing something very specific for their platform. But they're composed into our app. And our app doesn't have to care at all about what it's doing, all [00:14:30] it has to care about is where to put it inside our application. Right? I mean, like our app knows that that's another React component. It lives by the React lifecycle. It has a constructor, it has a component did-mount, component will-unmount, component will receive-props. It's receiving data in the same way that all other app ... All other components in our application are receiving data. It's getting handled through the same mechanisms as everything else in our app is getting handled. I mean, it's working just like any other React component, because it's the same interface as any other React component. And in this way, it's [00:15:00] immediately as composable in our application as any other React component is, because it is just a React component. And I think for this reason, this is why React and React Native has done it right, and why they done it in a way that I'm not really sceptical about, and I like to use, is because it's just another React component. So now that you know what to do. You can go ahead and do it for all the things. You can use React Native's dimensions API to kind of like measure the screen size and address the different screen sizes across the board. [00:15:30] You can use push notification libraries to kind of push different notifications to your front-end. Like, you can use a varied ... A various amounts of different libraries across the board by overloading each platform specifically, and abiding by the React component interface to kind of address them all and compose them all inside your application. And at Mainframe, we found is that, we've been able to share about 95% of the code on our platform by doing this. This has eased automated testing dramatically. I mean, we can just test one thing and that's basically it, right? [00:16:00] It's a way better developer experience. You don't have to have like a native team over there, and like a wall in between them, and like front-end JavaScript developers over here. Everyone's just part of the same team. We don't have to develop things like N-time is depending on how many teams we have. We develop it once, and then we ship it once. We can hire a few developers to accomplish the same result. I mean, would you rather work with a small dedicated team, or a bunch of project managers? Right? And faster development time means faster time to market. [00:16:30] So we can actually ship faster, we can get this stuff in the hands of our clients faster. And speaking about clients, they have the ability to pick up anyone of our devices and have the exact same experience. So they can pick up an iPhone, they can go on their Mac, or they can go on their Windows machine, and they have the exact same set of features that work in the exact same way. And all behave exactly how they were expected to behave. So our customers love it as well. But if anyone tells you that everything is great and amazing, there no downsides, you call them a liar. So heres [00:17:00] all the caveats for this approach. Basically what we found was that manually testing this as a developer is a bit time consuming. So basically, I build for one platform, test if it works on every single platform, right? If I build something for web, I need to test iOS and Android. And let's admit it, no one like opening up an Android simulator. So it's a pain. And Windows and ... Like, I need to test all the platforms, that's kind of a pain whenever I ship something anywhere. I need to ensure that it works across the board and of course, we're lazy. We just leave the QA team to do it. But it's the reality of this type of approach, is we're [00:17:30] changing literally every single platform whenever we make a code change. And we can't really ship a feature until it works across all those platforms, all right? If it break something on one platform, we'd have to fix it on that platform before we can ship this feature. What I notice is that, Reactive Native Web isn't quite a 100% compatible with React Native. There are small API differences between these libraries, and when you're building apps that kind of rely on how these thing function, those small differences can add up. It's okay in our experience, because we can just drop down [00:18:00] and write a platform specific variant, and just kind of avoid all this. So we can get around it that way, but I thought I'd mention it anyway. One of the things I'd recently ... I'm working on, is that React Native 43 just released a flat list and virtualized list which is a much better list view. But React Web doesn't have it yet. So I'm working on an actual contribution to React Native [inaudible 00:18:19] to bring that back to React Native Web. And then we'll have feature parity so then we can upgrade. So that's another downside of this approach is that we're kinda limited by our tools at the end of day. And then lastly, but certainly not least is that Flexbox [00:18:30] has issues on some browsers. I mean, older versions of IE have issues with Flexbox. And, interesting question, why do they call it IE? Crowd: [inaudible 00:18:39]. Taz S.: Because that's the sound developers make when they have to work on it. And so because of this ... Like, we can't really ship Flexbox to those browsers of course. I mean, the good news is that modern versions of IE, or Edge, or whatever it's called now, and everything else basically supports Flexbox. So we can have feature parity across the board, [00:19:00] but older browsers, they don't really support ... Or there's some issues, or some work arounds. But then you'd have to test every single platform again. So these are some of the issues with this approach. So at Mainframe, what we did was we focused on the platforms that our consumer want the most. What we found is the biggest consumer impact, we done on iOS, Android, Mac and Windows. And so we've kind of limited our amount of platforms to those, because those had the biggest client impact. And it also creates happy developers. We don't have to test across every single thing every time. [inaudible 00:19:29] test across [00:19:30] Chrome and Safari, and Firefox, and iOS, and Android. We can just test across like, this constraint set. Perfect. Well, thank you very much. Speaker 2: Questions? Speaker 3: Yes, hey. How do you deal with the platform specific libraries or features like service [inaudible 00:19:40]? Taz S.: How do we deal with platform specific libraries [00:20:00] such as service workers? Speaker 3: No, how do you use ... How do you get your platform specific libraries or, how do you use [inaudible 00:20:05] environment kind of features like [inaudible 00:20:08]? Taz S.: So, its like service workers already exist in the JavaScript environment, right? So like, you basically just pull that into your module as you would with anything else. And then you would just overload for those specific platforms that have it. You would then introduce basically, certain modules for those specific platforms, pull it in there. Platforms that don't have any might, or use something else in order to kind of mimic a service worker-like API. But since you're able to just overload, you can just kind say, "I want it on ... [00:20:30] I want the native implementation on those platforms. I want my own implementation on these platforms." Or, "I want it to do nothing on those." So in that way, we can just pull it in whenever we want. In the example I gave earlier about the conversation view, we just literally wrote like native components. We just wrote like native functionality for that convo screen on iOS and Android. And we can just wrap that within React Component and just pull that right into our React app. So in that way, we can just kinda target each platform individually. Yes? Mr. Lorenzo. Speaker 4: [00:21:00] One of the things I saw in your slides, is like you're already using Webpacks for two of your like, inputs, or like [inaudible 00:21:11]. But now [inaudible 00:21:12] like, to have one single Webpack config that's gonna work for everything? Taz S.: I, so ... Like with [Hall 00:21:22], can we have a single like, holy shrine of Webpack config, that we don't have to configure ... Or have to configure once and can magically work. I think, [00:21:30] yes and no. So I think, "Yes" because with Hall, you can ... You will be able to share parts of a Webpack config. But we can't share all the Webpack config. So we can definitely kina reuse parts of it, so such as actual resolve order, or such as things like the aliasing are things that we can possibly reuse. One thing that drives me nuts on React Native without Hall right now, is kind like the [dot, dot, slash 00:21:53] [dot, dot, slash 00:21:53] [dot, dot, slash 00:21:54], and like I have no idea where I am in life anymore. So like kinda just having it to go like, [00:22:00] you know, like front-up would be great. So just having Hall for just that would be amazing, because I have it everywhere else. But fundamentally to answer your question, I think we can share parts of the configuration with Hall, but we can't share all of it with Hall. But Hall would definitely help unify things. Yani. Yani: [inaudible 00:22:19] either [inaudible 00:22:20] internally developed in good abstraction for like, app [inaudible 00:22:24]. Like using Flexbox and React is great for creating UIs to work across [00:22:30] the different platforms. [inaudible 00:22:31] that you actually want the UIs to be different. So you could either go ahead and do like, entirely different component trees, or you could have like the active layer in [inaudible 00:22:37]. Do we have something for that? Taz S.: Yes. So we do have something for that across mobile and desktop right now. Because on mobile, obviously it's a small constrain screen, on desktop it's a larger screen. And on things like tablets, it's also kind of a larger screen. So we do have kind of a layer that kind of ... Like, measures the screen size and then will display different kind of layout, depending on the screen size. It is all using the same technologies [00:23:00] under the hood. It is all using React and Flexbox, and React Native, and React Native Web. So they're using the same technologies, just the actual rendered output is different. And we do that just by measuring the screen size. Yani: Cool. Taz S.: Thanks. Yes? Speaker 5: How many developers do you have and like, do you have like a each ... Do you have like a specific person for each platform? Or is it kind of like, the whole team shares responsibility for ... ? Taz S.: Yeah, that's a great question, actually. So how many developers do we have working on this, and [00:23:30] is there certain like ... Is there a certain developer for each platform that kind of like targets each platform? So, how many developers do we have right now? We have like, I think, ten developers total. Some back-end, some front-end. It's about 50/50 split between them. And there is definitely platform expertise amongst the front-end. Like there's one developer that we did previously working on native code, and then native iOS code, and then he switched over now since we're using this framework, this type of approach now. So [00:24:00] like, he'll work on iOS specific native UIs and stuff. And then we have someone on Android, working on Android specific things. And there's nobody in our office that uses Windows, so hey, whatever. And so, we do have platform expertise in that way, that if there is kind of, native code, they'll work on it. But again, as I mentioned before, like 95% of our code-base is shared, and it's JavaScript. So I mean, like ... When they'll go and then actually do something on the native side, it's like slim to none. And we don't have that much [00:24:30] native code for it to really be like, we have one person dedicated on this, because a lot of it's shared. Yeah? Speaker 6: Do you notice any inconsistencies between [inaudible 00:24:43] and different environments? Like, between like, Linux, Windows? Taz S.: So have you noticed inconsistencies between ... In Electron between environments? Not really, to be honest with you. It's been pretty consistent. I mean, yeah, I'm not sure what more to say there. It's [00:25:00] worked for us. Like, we're not the heaviest users of Electron, you know? Like, we aren't using every which individual deep API there is, so I'm sure someone that is, might find some inconsistencies there. Like we're using in we're using in a relatively light way, but for us, we haven't run into any issues. Yes? Speaker 7: Do you use Pusher for push notifications? Taz S.: Do we use Pusher for push notifications? Well, I'm afraid we do not. Our back-end is actually [00:25:30] using Elixir Erlang. And we've done a lot of effort into creating a full real-time API because our app is fundamentally a communications app. So it has to be real-time, it has to be snappy. So since we have an entirely Erlang-based Elixir back-end, everything's a websocket API, we jut built it ourselves. Yes? Speaker 10: What do you use for routing and navigation? Taz S.: What do we use for routing and navigation? That's a great question. And there's a lot of different options on the market right [00:26:00] now. Right now, we're using a mix between a custom forked of ... Like, navigation experimental for React Native, and then we re-implemented that for desktop. But we might want to throw it all out and just put in React Router. But there's some debate about using React navigation. And so honestly, it's kind of ... We're navigating that right now, and I don't know [inaudible 00:26:22] where to go. Yeah, my preference is React Router. But everyone has their own, so yeah, [00:26:30] we're not sure yet. Yes? Speaker 11: Do you have any tips for integrations [inaudible 00:26:35], end-to-end testing? Taz S.: End-to-end testing, that's a great question. Yeah, I mean, end-to-end testing is kinda difficult. Like what we found is that because we have a mix of JavaScript code, and we have a mix of native code, our best end-to-end testers are just people. It's a terrible answer, but that's what I found in practise. It hasn't been the case just for Mainframe. In [00:27:00] the previous companies as well, it's been people are the best end-to-end testers. We have automated testing for the vast majority of things, so we can kind of catch issues before it gets to them. But at the end of the day, they'll be able to find all those edge cases, and they'll be able to type in like, "Negative 3.1486." In something that should only be positive integers, like, great. You know, like they're the people that can do that. In practise, that's what I found. Speaker 11: So, [inaudible 00:27:24] are uni-tests then? Taz S.: A majority of our tests are uni-tests, yeah, yeah. [00:27:30] And by majority you mean all of our tests, yes. Speaker 11: Thanks. Taz S.: No worries. Any other questions? Yes? Speaker 12: So, React Native Web has a certain set of primitives, what ... Could you ... Do you extend that? Like, did you add new [inaudible 00:27:49] on top of that? So, [inaudible 00:27:52] how much work was involved [crosstalk 00:27:54]? Taz S.: Yeah, so React Native Web provides some primitives, and like it's not complete [00:28:00] feature parity with React. Like ... Sorry, React Native Web isn't complete feature parity with React Native. And so there's like a ... It was kind of a difference there. The way that we look at it, is that in order to build for these platforms, we're gonna have to build it anyway. So if we can just build that and share it across platforms, it's till in that game. I mean, we're still not building it like end times for each and every platform. Sure, we might have to do some additional work to kind of build it to basically extend React Native Web's feature set to be a bit more in parity with React Native. But we still see it as a net gain, because [00:28:30] we can share that code across different platforms. Yeah, like flat lists and virtualized lists is a perfect example, right? I mean, like there we had to extend it. Like, I'm literally writing ... Like, my day is literally writing tests on flat lists and virtualized lists for React Native Web so we can have parity there. But again, it's still in that gain and implementing it end times across every platform. Yes? Yani: Do you actually need a flat listing implementation for web? [inaudible 00:28:57] use like, just to have your [inaudible 00:28:59] implementation that just [inaudible 00:29:00] virtualized [00:29:00] on web, and then wraps like, you know, flat list [inaudible 00:29:04]. Like, do you need to bring that [inaudible 00:29:07]? Taz S.: That's a great question, Yani. Do we have to ... Do I have to do what I'm doing right now? Or can I spend my days drinking with Yani? While I would love to grab a drink with you, Yani. Maybe we can do that after this. But basically, as I mentioned before, we had to kind of build our own list view implementation for the convo screens. And the main reason there, was kind of unique [00:29:30] to us. And that was because a lot of these list view implementations, they're kind of powered from the top-down. And every single messaging app you use, is bottom-up. I mean, you type a message and you don't kinda like, [jankily 00:29:42] re-scroll your entire view, it's just there. And so this is just one reason why we kinda had to build our own list view implementation. Another few reasons, I did evaluate React Virtualized. And React Virtualized is fantastic, and I'm sure if you can use it, great. But [00:30:00] one thing I noticed was that it really want you to give all the heights up-front. And if you don't know what the heights of your things are up-front, if you don't have like a perfectly grid list, if you have like a freeform list where views take however much [inaudible 00:30:13] space you want to take up, doesn't work so great. And something else I found was like, the scrolling ... Like, the scroll points in React Virtualized wasn't that fantastic either. It could be improved. So the implementation that I have improves on those things. It still has a way [00:30:30] to go to really match performance of React Virtualized and all that fun stuff. But I'm focusing on the features at first, and then performance and all those things later. But I guess, going back to answer your core question, is kind of it doesn't work that well for us. And so for us, we have to build this anyway and so we may as well build it in a way that can work for React Native as well, and we can just kinda share code again. Yes? Ellie: Do you have any open source software? Taz S.: Do we have any open source software? Well, let me tell you about that, Ellie. [00:31:00] As my next talk ... So I recently just open sourced Relay compiler Webpack plug-in, so that will compile all your relay modern queries inside Webpack. Flat list and virtualized list, I'll be open sourcing that as well. Of course on React Native Web. There's a few other things I've open sourced, and we've open sourced as Mainframe. So I guess, yeah, check out Taz Singh on GitHub and things, and you'll see it all in there. Does that answer your question? Ellie: Yes. Taz S.: Cool. There was a question back here. Yeah? Speaker 14: Yeah, I just [00:31:30] want to say that, like if [inaudible 00:31:32] virtualized doesn't work, [inaudible 00:31:33] React. And sometimes he just wants to like, hang on React Virtualized [inaudible 00:31:44]. Taz S.: Just align the issues that with React Virtualized. Yeah, you're probably right. And I think we did take a look at React Virtualized and the issue tree. And it wasn't part of the philosophy of React Virtualized as [inaudible 00:31:56] types of issues. But we did look at that first, yeah. [00:32:00] Yes? Speaker 15: Do you have any problems supporting different versions? So, React Native has a kind of faster version cycle, so it depends on [inaudible 00:32:16], React 16 Alpha 4 or something. [inaudible 00:32:17] depends on [inaudible 00:32:20], so is there any issues around that? Taz S.: It's a fantastic question. I don't think I'm the best guy to answer that, but what we did ... What we've done is ... Well, first of all, [00:32:30] the first thing I tried to do was upgrade React Native Web to 16. And that was a pile of tears. I mean, it just didn't work out very well. React 16 isn't ready for that yet, in my opinion. So next thing we did, was we looked at the parts of React Native that we cared about. In particular flat list and virtualized list. The good news there is that it's pure JavaScript implementations, so we can just port back to React Native 42. So the one that doesn't have 16, and kinda use it in there until the [00:33:00] entire JavaScript ecosystem ... So the problem wasn't React Native Web in particular. Problem was things like Enzyme, there's no test utils currently in 16 based on when I last checked. So therefore, Enzyme is kind of broken. So you'd have to built a custom React 16 with custom ... With your own test utils, and then get that to work within Enzyme. And then Enzyme breaks, because it's not ready for 16. So it's just until the ecosystem is kinda ready, then I think React Native Web will be able to upgrade to 16. But what we just did was just back-port to things, and yeah, that worked. [00:33:30] Cool, I'm gonna ... I should probably be cut-off soon, otherwise I'll be [inaudible 00:33:33]. Like, all night. Ellie: So yeah, hang out. [inaudible 00:33:37].