 Hello everyone, okay Hi, my name is Amin and like I'd like to tell you a story about what we were what we were doing About a year ago in Azerbaijan and the reason I want to tell a story is because When we choose a technology there is all sorts of kind of choices that we need to make all sorts of frameworks all sorts of toolboxes all sorts of languages and If you look at their websites all of them got a great tutorials, they've got documentation and List of big companies using those same tools to build their product But what what's missing quite often is something in the middle What's missing is story not from the Google's Facebook's and apples of the world who can build Anything in any language through unlimited resources a story from a company That is constrained by budget by time by by by the market a story that you can relate to That is very similar to where you're coming from a story from someone who can convince you Oh, if that's worked for them, maybe this is something that would work for us and this is the kind of story I'd like to talk about and Hopefully I will be able to show what worked for us and maybe this will help you drive your technology decisions so to set the scene I will just quickly go through who I am and What were the challenges that we have faced and how we solve them? so I live in Azerbaijan and it's a small post-Soviet country it's about six times smaller than Spain and Like most post-Soviet countries we went from going from almost no technology in late 90s to a lot of technology In last five to ten years You've got all sorts of high-speed internet ubiquitous 3g and now 4g smartphone revolution everything that we all know and love and On top of that rapid growth of techno rapid adoption of technology Mobile services and web services have also seen a great adoption So everyone is using using Facebook using Instagram using YouTube Google plus well, maybe not this one and this adoption of global services led to rise of the local services and we have found ourselves at the forefront of that growth and in our country we run a Classified service and depending on where you come from you probably have heard of a veto or a leaks or Craigslist and There are others other players in this market but basically this is a way for people to buy and sell stuff online and If and what we have found found is that on top of that technology gross We have been seeing this massive gross. We went in 18 months as almost grew from 300,000 monthly users to a million and a half and We had to manage all this growth But we were still very limited had very limited resources a small team and we really had to pick our battles At the same time What we have seen is already because of what happens when you rapidly adapt the technology You tend to jump over a few generations So what happened is mobile revolution probably started even earlier in Azerbaijan than globally I think from 2014 We have seen on our all of our projects almost 70% of mobile Almost almost 70% of the users coming from mobile devices not counting tablets iPads and this was the case for this project and 70% were using the mobile website and for a long time. We've thought that's alright. We've got a desktop website We've got a mobile website We focus a lot on mobile experience making sure it works fast and on every device But also we realized at some point as I think that point for us was when we've been reaching a million users is that People start to expect you to have a mobile app to At that some stage it's almost demand you to have an app because they open up the app store They look up for your applications They don't find you and this also leaves a space for competition to come in and capture your market By being there where you are not so we understood that we have to do something about it but at the same time we still really had to make it very efficiently and We had a few criteria that We had we had to adopt if we were able to pull it off and obviously we are doing web development We love to deploy many times a day We want to be able launch and iterate quickly But we don't have anyone on the team who has got previous mobile experience not at all No one knows objective see no one knows Java No one knows the specifics of building an apps for iOS and Android and we really wanted to avoid that We don't want to build separate teams one team for us one team or Android one team for the web Then you have to synchronize all of the deployments and changes and everything support multiple products But we also wanted to have the access to all of the native features and have if we were able to do it fast and Fluid experience on all platforms so we started looking at our options and if you look at the mobile Landscape between going doing a website and building a full-blown native app. There are all sorts of different possibilities in between Hybrid apps for the purpose of this talk. I'm calling anything that is not a native app a hybrid and It's impossible to Obviously look at all of those options So we will look at three main types of things one is very first very simple You just wrap a website call it a day and You have something on the screens on the phone screens of the customers They can use it and if the website is good then probably the application is also good enough, but what we have found out is Expectations are different when you use a mobile when you use a mobile app And if you provide the same level of experience on a web mobile website and your mobile app It will have the perceived perceived experience will be worse and But at the same time it shouldn't be underestimated because it's easier for us geeks to add a bookmark and access a website But for many people putting this icon on the on the phone screen Maybe the easiest way to access your service and even if it's a less Lesser experience than your mobile website. You may want to do that while developing your native app looking back I think we should have done it second option was is to go semi native if you like and this is the best option when you have a lot of different screens and It was particularly suitable for us because we use Ruby on rails on the back on the back end and Folks from base camp have created this product called turbo links where you build a native shell in A native language, but everything else is loaded as a web view and it works quite quite well Still it required us to to go for this option We needed to have some experience even if relatively small with objective C and Java it's still slower than native apps and It still requires you in many cases to go to the app stores to update your app so with that we arrived at the third option which is Using a number of tool kits that will allow you to create Applications that act and feel like native but are not without using actually using the native language and There are a bunch of tools just within these options, but we only we started directly with react native and I'll tell you why right now. So we have in the past Used already react on the web. We read about it We found that it got both good support for both iOS and Android has got a mature ecosystem It's very easy to start. So we decided just give it a try just see How it works and what it can do to us and it turns out that starting is really really easy Assuming you've got the dependency installed assuming you've got you have your system in place So you just run those four commands and in five minutes You have something running on your device or an emulator in this case And while it kind of you can look at what the big deal was that it is kind of a big deal because if you think about it By this time you have never touched any mobile app development. You don't know anything You don't know where to start. You don't know what to do. You don't know the platforms yet You already have something running on your device Something they teach and tweak and something they teach an easy lab date in the language You already know this is very important point. It felt like so satisfying to have something up and running It almost reminded the very early days of when I first Stumbled up on HTML and this VB script and you put a loop and you generate a bunch of tags And you have something you have a website and it's like wow I have something up and running It was the same feeling like you already have something and you can work with it and if you look under the hood this is This is what it generates. It's got a bunch of conflicts and dependencies But the essence is in this file and as you can see it's got a bunch of imports and then there are two main blocks one is using a something resembling style sheets to define your app and visuals of your app and The second block is a component and if you notice What it has it? It renders a block off which contains view and without within this view There is a text component and this is really important And now if you know a bit of JavaScript, you probably can read it You probably can understand what it does so you create a container which renders a text But the important part is despite this being a JavaScript despite this being not a native language This those are real native components. So what you do with JavaScript you define how you want to How you want components to look you define how you want them to behave basically you orchestrate the whole environment, but you do that in your language in the language that you that you already know and This this this was great. This was great for us and Even if I stop here for for people who love JavaScript This is Kind of a short introduction that you can which you can do with the react native, but for us it wasn't enough Because I'm not sure how many people in this room love and breath JavaScript But for us coming from the Ruby background on the server Every time we needed to touch Front-end code on our websites going to JavaScript It was kind of a mess all of those quicks and rats and lack of standard library and a lot of issues and When we face this problem first in web world we Started looking for alternatives of what we can do what we can use instead of JavaScript and We ended up assess after assessing all of the alternative choosing closure script I won't go too much in detail of why specifically closure script, but it's a great language it's got all of the things that we cared about and It allowed us to work. It works great with react specifically its paradigms are fit very nicely so we adopted it for all of our web development where we use react and I Highly recommend this talk closure script for skeptics, which is Describes it goes in depth as to why you may we want to choose it instead of JavaScript why it may not be as crazy as it may seem When you first at least look at the closure script code for the first time so which else closure script and When you just to show an example of how it works. This is example from the web development. This is Like reagent wrapper for react component for the web and even if you you probably can make out What it is about it renders a div which and it I show you how it shows How it renders in the low part of the screen? It shows renders a div with a couple of paragraphs and it was a formatting but the important part here is We don't have any custom objects. We don't have any classes. It's basically a function That's called simple component that returns an array or vector as we call it in closure world And this is the common theme in closure world. It's a function that manipulate data structures so instead of having all sorts of different objects you try to Work with data structures, and then you can apply all of the power of the language to work with it and Let's say more involved example this one uses It's got global states and again if you ever worked with react, you know that basically your UI is a function of a state and in this case the state is number of clicks it's called click count and We initialize it to zero but the important part is in the counter component in the bottom there is a non-click event and when you Click the button it calls a swap function which increments the click counter and everything else is done transparently You don't need to do anything else you update the global state and any component that that refers that Atom we called atom the global state will be automatically Rerender it so you don't need to worry about flows. You don't need to worry about anything else You just update the state and your UI or renders automatically It turns out that this simple concept is all you need to know To actually go ahead and develop mobile app using closure script and react native I'll show it in a minute, but before I do this may look unfamiliar I mean, what is it parents in the beginning a bunch of parents at the end and different types of parents but I just wanted to make a note that Just because it's unfamiliar doesn't mean that it's complex actually quite often people confuse Concepts of simple and easiness for instance for me Spanish is hard I don't know Spanish for many people in this room You probably able to speak it fluently since you went since when you were a kid So it doesn't mean Spanish simple or complicated by itself for you It's easy for me. It's hard But if you want to objectively assess its complexity you have to look at the grammar rules inflections all sorts of things To see which language is simpler which one is more complex So the closure script while it's unfamiliar It's actually a much simpler language very clear and concise language much simpler than JavaScript by the way So once you go beyond that point of unfamiliarity You start to look at it differently and I highly recommend this talk Even if you don't develop mobile apps Even if you don't do any closure script or even JavaScript this talk that makes it clear What is simple and what is easy is I highly recommend it. It will make you a better developer So let's see how we get how we do that in closure script almost the same four commands like in react-native world and again, after five minutes of you already have something up and running a little bit more advanced than the react-native version and Again for me, this was the moment that was sort of a liberating experience when I understood that we can actually build it I can open this closure script code I can change a bunch of things and immediately I can see it on my device I connect my iOS device. I connect my Android device and I can see that it's working It gave me a confidence coming from the web Development background that we will be able to actually pull it off without building a huge team We can't do something that any on that anyone on the team will understand So let's come just to see how closure script compares to JavaScript let's I dumped it down to the standards react native version and this is what you see and Again, just like in JavaScript version. You've got a bunch of imports and Then you have two blocks one defined styles and one defines Component and if you notice in the JavaScript version you had a stylesheet class in here. We just have a hash or map That contains styles The components the view itself also is a function that returns a ray the vector The only difference with the web version is that instead of diffs and paragraphs you work with views and text and the dozens of other native controls But you never have to think about anything else. You just manipulate those data structures with your favorite programming language and Let's see how it compares. So this is the same piece of code from JavaScript version and below is a closure script version and If you notice in the JavaScript world, you have class listings that extends component Which has got to render function which returns JSX which is then transformed to native code and as I said in closure script version is just a function which returns a vector Which is that's that's a kind of simplicity that we talk about That it's may not be familiar, but it's very simple just a function and data structure So with that we built a prototype we decide we decided it's good enough To start experimenting we built a prototype in couple of weeks and we've sought. Yes, we can do it so we hired a full-time engineer to work just on this project on both iOS and androids and Android and In three months of work We including mock-ups including back-end API design including Markup of the Up itself we have been able to Develop and launch our app to not a bet not a better version, but actually production version of our app it was about 5,000 lines of code including all of the styles and It had nothing no native code at all except some configuration, which I can't really Say that it's a code and This is what we were able to I hope it plays To develop. Yep So it's got a bunch of features like endless scroll of listings search and filter per category fields Detailed view for the galleries with zoom swipe to back both on iOS and Android native share functionality bookmarks ability to post your listings It's works in two language. So it's got internalization built in I mean it's not a huge app but it's not very basic and As you can hopefully see it's very fast and fluid and the experience is the same on both Ios and Android. So if there is just one take away from This talk is that you can actually this is type of thing you can build with react native with or without closure script hopefully with closure script and It will work pretty well. It certainly worked very well for us and While I cannot obviously show the whole Number of issues we had to face when developing making it fast and fluid I would like to focus on couple of specific examples that demonstrate the amount of effort you need to put in to make it work well because When you think about it, there was nothing stopping us from launching it in a month We actually did develop first version in less than months What it what did take time is ironing out all of issues and this is a specific example. I see it very often It's not a rocket science, but it's so much so many Developers for some reason don't do that that I decided to bring it up as an example Probably it's because when you work locally you have a local database or you have a fast connection to your production version You have a listings of product when you click on it You fire a request and you load the full product description and again as I say where you work locally It's very fast. It's instantaneous and you don't Think about it But when you are putting it to end users, they may be on a larger 3g connection. They may have Slower device that which requires kind of every request counts and it's much less fluid experience But if you think about it when we show the listing Listing of all the products we already have Title we already have a first picture. We already have a price We already have some other data like date and location and because it's a react world It's very easy instead of just firing a request to so we're waiting it for it to come back You can render what you have you can render that picture can render a title and then fire a request and get everything else So that it loads and as it loads you just set the state just like in a counter example You just update the state as it arrives from the server and it gets progressively rendered So this will be a much better Experience that it will be an improvement, but we can do even better Because when you think about it a little bit more the amount of data that shown on this screen is Incremental very small. It's just a short description a couple of attributes and maybe a couple of additional data Like phone number and anything. So it's just a few hundred bytes per listing So instead of firing a request every time you open it open the product You can load all of this data while loading the list of products. Yes, you increase the payload Obviously, it's a little bit bigger, but after you zip it after you Once you zip it basically you just have an incremental maybe of a few kilobytes of data and Compared to one image less than one image size. It's so much better experience We still fire that's what we do. We still fire a request for additional data That is below default some like related products other data by this customer something like that But you never notice that as far as you are concerned you clicked and it's immediate You can't get faster than that You only bounded by animation time. I think another example is also It's in a similar way The same type of effect basically you open the category when you click on it You open a subcategory and again quite often what I see is on every level that you go You get a small delay while you get data from the server But if you take the whole tree the whole tree of categories was all of its properties with all of its data It's just a few kilobytes of data Nothing stops you in the very first time when you launch this when you launch the app to download the whole tree And update in any background Updating background when customer doesn't notice it's a data that doesn't update frequently You don't need to update it every minute each and update it once a day once an hour Whatever fits your schedule, but as far as customers concerned. It's immediate. You don't ever need to go anywhere And it's always up to date at the same time so we're important details and we had a lot of details like that and Though that's that's what takes most of the time So be aware of just creating and launching it without working out all of those small nuances That's makes a difference between a good and great app in my opinion at least Okay, so we have created an app and It's needs to get the data from the server and needs to interact with the server and you can say Okay, we've got a json for that and you would be right You can use json json is good json works everyone knows is but it's not great And if you ever had to pass a date or a flawed or a set to work with that in json You will know what I'm talking about you have to go through the hoops to just to kind of wrap it and unwrap it on the sending and receiving side and Transit format it's developed by the same company that develops closure It works just like closure works on JVM and closure script was on top of JavaScript Transit works on top of json and message pack if you work with binary formats It supports any of that now any data type it can have arbitrary keys not just rings It's completely language agnostic There are a bunch of official implementations and there are unofficial implementations in every almost every language so you can use transit format to Say connect your angular app to your Django back end. I mean it's not related to closure script at all and Because it's built on top of existing platform. It's got a very high efficient parser and it's also has built-in compression and teaching for even more faster transmission times and and parsing time so highly recommend using transit format and again just like with Previous examples, I would like to give a specific example of when it helps on the back end We use Ruby and if you use Ruby, you will know that idiomatic Ruby uses symbols as a keys for hash So instead of using string you would use a symbol and the same happens to be the case in closure world and it's It's called keyboard and if we were using json to send our hash from back end to front end We would we have a future two choices either we have to downgrade to lowest common denominator and use string as a key Or we have to find some sort of way to pass and to encode and decode the Symbol from symbol to keyword house by ourselves We don't need to worry about that in transit format any of the standard data types are supported from for each language If there is a match between your two languages, they will be transparently linked Basically the way I like to think about it is it's got all of the benefits of json without all of its drawbacks So I highly recommend it to you to use wherever you would you would use otherwise json Especially if you struggle with those problems with dates floats or string the skis So we build an app we created a back end so back end API and Now the time comes and we want to update it everyone does and If you think about the first version of an app that I suggested is like website wrapper Whenever we update it whenever you update your website. It's immediately up to date on the customer's device Not so much with a native app. Obviously you have to go through the app stores You have to wait for a few days until it until it gets reviewed at least in the Apple world You lose all of the reviews by the way Because by default Apple shows only the latest revision and Basically, it just doesn't have enough of velocity and feedback loops that we are all used to in the web world but Since here we also use JavaScript We use standard assets like images and style sheets. Oh JavaScript mostly There is nothing stopping us from doing the same as if it was a website and update it over the air now a little bit more steps are involved you have to use some third-party servers to send notification and we use Code push that's a service by Microsoft by the way. It's free for now. It's probably will be paid eventually What it allows you to do is obviously you register and integrate into your app, but then Whenever you are ready to update you push your commit your updated version to the code push servers and all of your apps Get a notification You can schedule it whenever you want you may want to check it every minute on the launch whenever you want and You can download this new JavaScript bundle and apply it on the customer's device without them ever updating doing anything manually and you can do it As involved as you want to you may want to show another do you want to upgrade you may want to update in the background When we started we did it in a really stupid way We just downloaded it immediately and applied it immediately So you would be in the middle of your flow and then war application will reload now. We're doing it a little bit more Clever we downloaded it as soon as it's available Then we went for a period of inactivity like 10 or 15 minutes and when you come back You already see a new version so this worked very well for us because Most features don't require you to upgrade like ask for new permissions which requires updating binary You don't need to upgrade react native every month. You don't need to Include any custom libraries every month So most features are just fix hands a little bit feature here some text updates and you field Update to API and things like that so what you can do you can apply those change immediately and then accumulate them and Every once in a while you do proper release which has got all of those features Included for people who downloaded for the first time, but otherwise everyone else who is actively using your app We already have all of those features So it's very simple. You just have a bunch of commands your list that allow you to list all of your deployments You release your application and then you can roll back if something goes wrong And then you can also watch the adoption how many people are on which version of your app Basically, you get a full control of what you want to send to customers and Let's see the results that we were able to get So in we launched about a year ago a little bit more than a year ago We were supporting Ios 8 and Android 4.1 and above we by now we have about 200,000 installs and we've got about 20% of the daily sessions from the mobile app Apparently mobile apps users are more happy because they install the app and they're more active So you get a high percentage of the sessions and our average rating average rating is 4.7 from 3000 reviews and while obviously part of it is because of the service that we provide We like to think that some of it is because the application itself works quite well Speaking of crash-free sessions when we started it was about 80% So the first better version, so we had to debug and find Reasons for why why it was caused it's mostly about out of memory errors If you don't take if you don't control how much data you try to process at one particular moment and A number of bugs in react native itself But we were able within amounts to lead to bring it up I think to 99% when we launched and now 99.8, which is think five times more reliable than 99 So we still strive to get three nines Hopefully at actual nios. We were able already to get three nines on Android it's still 99.8 and So yeah average rating as I said is 4.7 and there was one review that I wanted to share with you today It was like I didn't like the app, but I'll give you five star for the effort Not every day. Do you get a custom customers who are conscious of the effort? That you pulled that you put into developing and up other reviews are promise. I'm really happy about that. So Thank you anonymous Reviewer and thank you for listening to me today Thank you. I mean, that was a really awesome and inspiring story. I think you should have that Comment like at the top review in your app So we had we got a bunch of questions from the audience How much code is shared between the iOS and Android apps? I think it's more than 99% I can't give you the more precise figure, but basically almost everything that we do Is platform agnostic the only thing sent when we had to Access do different functions is for instance when you want to get a device ID unique device ID to send to the server to the API The methods to call it are different on iOS and Android So you create two different functions and then you have a wrapper function that depending on the device calls one of those But those are far and few in between mostly. It's just like pure closure script without any ifs And conditions for the platform so it's more than 99% nice How do you debug crashes that could potentially happen on app submit to the Apple store? That's a very good one It's difficult. It is difficult. Unfortunately. There is no easy answer. Basically. We use crashly ticks service to monitor the errors and when we see When someone something an app crashes we get a report with a stack trace Unfortunate of this stock trace is a little bit hard to read as because you've got a react native stack and on top of it You've got a closure script compiled closure script stack, so It's a bit hard, but usually you can make out what is happening by their safe It's out of memory error or some library crashed or something. So we were using that to debug It wasn't the easiest part of the experience, but we were able as I said to get to 99.8. Very impressive We have a question about building local tech communities. Is there a big closure script community in Azerbaijan? How do you find and develop closure script talent? Yeah, the short answer is no there is no big community. I think there is almost no community at all actually The we we work remotely all of our teams work remotely, so we don't constrain ourselves to local market and So that's how we find developers basically looking at at it globally Unfortunately, I'm yet to see any activity in closure script community in Azerbaijan Using frameworks like react native animations are often a problem. Did you encounter any and how did you tackle them? It's very important. It's a very good question because animation is quite often is a source of lags In your UI because you've got two threads basically the main thread the UI thread and the JavaScript thread that controls the UI So if you do a lot of work during animation Because animation is controlled by JavaScript thread. It may become laggy So you really have to take care of not to do not to do a lot of work while you animate So there are built-in features that you built in components and the fact that you can use But you really have to be careful And we had that problem in the first version of our app. It was that you click it moves But sometime because something is happening in background it starts lagging So we drill down into all of those issues and made sure we don't do an extra work while the animation is Going working doing kids nice If you were to build tap as over again knowing what now what you what you know Would you develop the back-end enclosure instead of Ruby the back-end app? I guess if it's instead of Ruby then yes, well, actually we do plan to move to closure on the back-end We started building this up a few years ago So and we all of our apps are also in Ruby and the good part of about it is Because we use transit format once we upgrade or change or shouldn't use what I'm going to change from Ruby to closure We don't have to change the interface because if it was if we were using JSON and we would now change from Ruby to closure It would be like having closure and closure script Working with Jason format instead of speaking in a more rich format. So we completely avoid that problem So eventually once we change all of our clients will be able to work with exactly the same API because it will be speaking the same Language it's the same format transit format nice For the live updates, what's the status of Apple's guidelines about pushing code over the network? Is the code push method allowed or is it still a gray area? It was a gray area for a long time as the latest I have read was quite a while ago because Apple changed their terms and services and they allowed this type of update Basically, I don't remember the details, but I remember very well that these kind of applications are fine They are not a gray area anymore. There are some cases where you cannot do update over the air, but they are not related to this kind of cross compilation and downloading of the JavaScript over the web Awesome one last question before we break What challenges did you face when implementing platform specific design? For example, Android's material design versus Apple's human interface design Well, we completely avoided that problem because we didn't use follow any of the guidelines you may Because we what we try to do we try to replicate our mobile experience So the design looks the same both on mobile website and on mobile app So which means we didn't try to follow the guidelines of how to do selects how to do forms So we don't have that problem, but if you use native components for say inputs They will behave depending on the platform They will behave a little bit differently following the guidelines of the local platform. Obviously, you don't have to consider the design issues and maybe add additional conditionals To make them work exactly the same, but we didn't have this problem So I can't really be the best person to answer that nice. I got one last comment Someone said I didn't really like your talk, but I give you five stars for the effort. I'm just kidding Thank you so much. I mean that was fantastic