loading...

I've seen heaven. And it's written in JavaScript.

bitario profile image Mo Bitar Originally published at listed.standardnotes.org Updated on ・6 min read

Why React Native is the Future

I have a weird way of describing software. And you’ll either know what I mean, or you won’t. It’s sort of strange, but software interfaces feel like they have a weight. When I use an interface, it can feel heavy, or it can feel light. Neither is better than the other. It just sort of depends. Chrome is very light. Safari feels heavier. And Firefox feels the heaviest. It’s probably bullshit, but that’s the feeling I get.

One of the heaviest feeling experiences in my software development career has been using Swift in Xcode. Oh the pain. The delay. The Kanye-West compiler that never lets you finish. I’ve lived in this unwieldy world for the last several years, building applications the only way I knew how: raw, manual, single-platform code. Go native! Right?

When I learned about React Native, I was skeptic. Write code in JavaScript once and deploy native apps on both iOS and Android?–this has to suck. So I ignored it. And instead ended up writing two separate native apps, one in Swift for iOS, and the other in Java/Kotlin for Android. This was in addition to a web app written in JavaScript, and an Electron-based desktop app. (The app is an encrypted cross-platform notes app, so availability on every platform was key.)

This worked well enough for some time, but had its difficulties. I could manage writing the web app and iOS app, but I had no experience with Android whatsoever. In fact, I had never used an Android device my entire life for more than an hour. Luckily, a community contributor was happy to help in building the fundamentals, which allowed me to forego writing an app from scratch, and instead just maintaining it with incremental changes.

Any time a change needed to be made, or a feature added, I would need to journey into three separate code bases and write the same code, in three different languages. Being one person, this wasn’t always very efficient. It could take a week to make even the simplest cross-platform change. The result were apps that could never have nice things. For example, several users were asking for the ability to add a passcode and fingerprint lock to the application–a very reasonable request for a security-minded notes app. But the implementation of this was no triviality: first, a passcode setup interface in addition to an input interface was required. Then, encrypting offline user data with the passcode. Then, on mobile, specifying when the passcode or fingerprint should be requested (immediately or on app quit). The thought of writing all of that code in Swift, then Java, then JavaScript, was a nightmare. I couldn’t bring myself to do it.

There has to be a better way.

Enter React Native

I had to describe the context and emotion behind what it felt to have to maintain separate codebases for an application, so that you know the elation I felt when I began using React Native. For the first week of writing native applications in Atom (!), my mouth was agape. I could not believe how easy it was. No Xcode, no Swift, instant reloading of changes, writing in the ever-easy to use JavaScript–I was in heaven. I would put the iOS simulator and Android emulator side-by-side as I was writing code, and spent half the time in utter disbelief that everything just worked. I never had to wonder, well, this looks good on iOS, I wonder if it’ll work well on Android? For the most part, if it works on one platform, it’ll work on both, with little adjustment.

The most beautiful part? I WAS REUSING ENTIRE CLASSES FROM MY WEB APP! I was able to copy complex classes involving models, controllers, and encryption logic wholesale with very little change. The entire sync engine of the app? Copied right from the web app. Encryption and decryption? From the web app. Models and relationships? From the web app.

I was so, so happy not to be writing all this stuff from scratch. Sync is hard, and encrypted sync is no easier. The web/desktop codebase was our flagship, tested product, and the confidence of being able to reuse those components was magnificent.

One of the hardest parts of building native applications using native IDEs is the user interface. On iOS, it is so painstakingly time-consuming to develop interfaces. You can do it through code, but it will involve a lot of code. And managing dynamic layout constraints with code is more hellish than most tasks. You could use the interface builder, but, you lose the fine-grained control and flexibility code gives you. And good luck committing and collaborating on Interface Builder changes in git.

In React Native, dynamic interfaces are a breeze. You use CSS-like syntax to build the design of your dreams:

let containerStyles = {
    backgroundColor: “red”,
    display: “flex”,
    alignItems: “center”,
    width: “100%"
}

let childStyles = {
    fontSize: 14,
    color: “black”,
    fontWeight: “bold"
}

<View style={containerStyles}>
     <Text style={childStyles}>Hello, future.</Text>
</View>

This is the basis for building all interfaces in React Native. And it’s really as simple as it looks. And the bast part?

THEMING.

Essentially, your entire interface is a bunch of JSON properties. You’ve probably already noticed it wouldn’t be very hard to pull a JSON style blob from a server or file and completely change the appearance of the app. So that’s exactly what I did:

Do you know how hard this would have been in native code? My mind aches just thinking about it.

What's the catch?

During my journey through heaven, as I looked in every direction in utter amazement and wonder, I kept thinking, what’s the catch? It can’t be this easy to build native applications. It felt almost sinful.

Now, this is software, and a software development tool at that, so there is no such thing as perfect. React Native is still under active development, so you’ll experience some gotchas. My first few gotchas felt existential. “Shit! This is the end! I knew it. I knew it was too good to be true. This issue is going to completely blow up my project. Luckily, there was no issue that couldn’t be solved.

For example, one of the more annoying issues I experienced was that the TextInput component of React Native just didn’t work well enough on Android for a notes app. The scrolling was laggy, and anytime you scrolled to read the note, it would automatically bring up the keyboard. Extremely frustrating. I tried for several days to hack my way around the issue by somehow manipulating the JavaScript code to prevent both issues. But absolutely nothing worked. I learned however that this is not the end of your project. It is the beginning.

React Native allows you to easily build native components for anything your heart desires. A native component or module means you can write interface and business logic using native Swift/Objective-C or Java/Kotlin and easily create a JavaScript interface for controlling those modules. In my case, I wrote a custom textview module in Java that made scrolling much smoother, and wouldn’t focus the input on scroll. This was straight up Java written in Android Studio. I imported it in JavaScript, added it to the view hierarchy, and boom, a beautifully scrolling text input in React Native. Problem solved.

I used native modules for other things too, including the encryption module (separate modules for iOS and Android) and the fingerprint authentication module.

Should you use React Native?

Yes, yes, 100% yes. Even if you’re building a single-platform app, I would use React Native. It just feels like the better way to write apps. As new as Swift is, it feels ridiculously outdated and heavy compared to the nimbleness of writing apps in JavaScript. I really wish Apple focused on making it more accessible to write great applications, rather than introducing the most esoteric programming language I’ve encountered in some time. Xcode was built around Objective-C, and Swift still feels out of place inside.

I was able to re-use about 70-80% of the code from our web app in building the native mobile app. The rest is interface code that could not be re-used. I was even able to target lower versions of iOS and Android. Our original Swift Standard Notes app used the newest implementation of Core Data, so iOS 10 was required. The new React Native implementation works out of the box on iOS 8 and Android 5.

Want to see how a React Native app feels? You can download the finished product for iOS and Android. You can also check out the entire source code. If you have any questions on the React Native development process, please don’t hesitate to reach out on Twitter.

Discussion

pic
Editor guide
Collapse
ben profile image
Ben Halpern

I definitely feel you on the "feeling" thing. Software development can be visceral.

Collapse
bitario profile image
Mo Bitar Author

It's tricky because weight is the end result and as far as I can tell, cannot be controlled during development. Standard Notes feels very light on Desktop, and I'd actually like for it to feel a little heavier. But there doesn't seem to be any one thing I can change to take it towards that.

Collapse
ben profile image
Ben Halpern

I've started using Standard Notes (and will probably become a paying customer in the near future) so I'll be sure to provide feedback and/or code contributions.

Thread Thread
bitario profile image
Collapse
nadangergeo profile image
Collapse
a_reiterer profile image
Andreas Reiterer

This article literally made me want to create a React Native app 😀
Great Read! Thanks for that!

ben profile image
Ben Halpern

What do you think of the prospects of being an early Flutter adopter? I'm willing to play with it but I'm not sure how invested I want to be in an alpha project at this point.

Collapse
kayis profile image
K

Could you elaborate?

I read about Flutter, but while Dart seems superior to JS, it somehow didn't really catch on.

On the other hand, FB has re-written >50% of its Messenger in Reason, a language which is also superior to JS and not wide spread.

Collapse
slmyers profile image
Steven Myers

Determining language superiority sounds hard. How do you do it? /sarcasm

zoechi profile image
Günter Zöchbauer

Flutter seems to be about to go beta.
I'm working on a Flutter project since 09/2017 and it's working great and you get real native apps.

Collapse
twigman08 profile image
Chad Smith

Good article. The thing that keeps me from going all in with React Native, or really any other JavaScript application is the setup.

Set this congig file up, set this json file up, run this command. Make sure you have this set. But If use a totally different set of tech those configs and json files are totally different.

Example: I tried to get started learning react native on my windows machine. I have done plenty of mobile work before. Native Android, Xamarin, and even Flutter. In all 3 ways I was up and going pretty quickly. No issues. React Native on Windows? I have followed documentation from Facebook on Windows (horrible, and there are plenty of articles online about that) plus other articles on setting it up. Spent 8 hours on it to finally get a hello world app going on Android using Windows. It kept complaining that Android was not installed, yet Android Studio, Xamarin, Flutter, had zero issues finding the default installation directory. It also didn't seem to like the latest version of the JDK I had installed.

Honestly setup is a very important feature for a piece of tech or language. If it's frustrating I don't want to fight with it. I want to develop and solve actual programming issues.

Next time I try React Native out again, hopefully it won't take me 8 hours to get it setup and running and I can actually roll my sleeves up and spend time learning it. Until then I think I'll stick with Xamarin for my enterprise level apps and Flutter for experimenting.

Collapse
sahilakos profile image
Sahil Saini

Nice work Mo. I couldn’t agree more. We launched an iOS+Android App build on React Native within 10 weeks (including ideation and all pre-dev setup). There were challenges and seemingly moments of doom, but nothing that couldn’t be fixed with a little extra effort. We had considered using other frameworks or even separate code bases but with a tight timeline, budget and resources at hand, we took a chance on React Native without any prior experience in it. At the end, it worked out really well. Product was launched right on dot for both platforms and better yet, maintenance has been a breeze.

Collapse
bitario profile image
Mo Bitar Author

I did forget to mention that—maintenance is blissful! (So far)

Collapse
danielw profile image
Daniel Waller (he/him)

What are your thoughts on the whole ecosystem surrounding Javascript?
Personally the thing I find most off-putting about react native (and js projects in general) is that rarely anything just works right away and I spend a lot of time in config jsons using trial and error + copy&paste from the web with no real idea what I'm doing.

Collapse
bitario profile image
Mo Bitar Author

That wasn't really my experience. Everything just worked for me. I ran into obstacles, but nothing that eventually stopped me from shipping the product. The great part is you can always fall back on native code if it starts acting goofy.

Collapse
cmilr profile image
Cary Miller

Really nice write-up... while I don't find Swift particularly esoteric or difficult (it feels really intuitive to me,) I've been intrigued by React Native, and you've piqued my interest even more. Thanks!!

Collapse
sambenskin profile image
Sam Benskin

Great read, thanks for sharing your experience.

I totally get the light and heavy feeling. For me it's user interfaces in software. If it's hard to use, navigate or understand, it feels heavy and more like work. When it's clean, well designed, looks good and is properly architected it feels "light" and fun.

Definitely going to use React in future projects.

Collapse
richjdsmith profile image
Rich Smith

"Chrome is very light. Safari feels heavier. And Firefox feels the heaviest."

Haven't tried the new Firefox then, have you? Ever since the Quantum upgrade in November, it has become my daily driver. Chrome feels fat comparatively. Give it a whirl, it will likely surprise you.

Thanks for the great article though!

Collapse
bernhardwebstudio profile image
Bernhard Webstudio

Nice article, thank you for introducing me to react native. What would you name as arguments to use react native instead of Phonegap/Cordova?

Collapse
stecman profile image
Stephen Holdaway

We had a project that was originally written using PhoneGap/Cordova + React, and later rebuilt using React Native when Android support first came out. From that experience, I'd highly recommend staying away from Cordova for any serious projects.

The biggest pain with Cordova for a sufficiently complex app is that you end up fighting the same browser support battles as regular web dev, except it's much harder to support all the WebViews because there are so many variants and versions in use with their own feature support limitations, rendering bugs and behaviour quirks. You end up with a whole lot of targeted CSS to get roughly the same appearance on a range of devices (that you have to keep going back to each time a new inconsistency is spotted on a popular device), and rewriting behaviours in different ways to work around quirks on specific devices (Samsung devices with their Samsung browser were notorious for touch, input and rendering issues in our experience).

On top of this, even with decent lag-free touch handling like React-Tappable offers, the app still looks like a website stuffed in an app; unless you're targeting one device, not having physical units means the app always looks different on different devices due to different DPI.

Interfacing anything native with Cordova was also a bit unstable in our experience, but that's nothing compared to the maintenance hell it led us to.

React Native worked consistently and performantly across devices of all types and versions for us.

Collapse
bitario profile image
Mo Bitar Author

Not too familiar with either of those, but if I recall correctly, both of those are webview based wrappers, and not actual native code.

Collapse
danidee10 profile image
Osaetin Daniel

I think i understand what you mean by Heavy...Heavy == Smooth For me, Even though Chrome uses more RAM than Firefox, It still Manages to be smooth and Responsive.

Firefox can be very clunky sometimes (When multiple tabs are loading content)

Btw Nice Article :-)

Collapse
bitario profile image
Collapse
jpenuchot profile image
Jules Pénuchot

In 2018, having a bunch of React Native apps that take seconds to load with an SSD and an i7 when all they do is sending messages and editing text makes me feel like we've taken a few steps backwards.

Collapse
alejandrofdiaz profile image
Alejandro

how do you style your application for both Android/iOS? something like IONIC or Framwork 7?

Collapse
cassidoo profile image
Cassidy Williams

Fun read! Excited for you :)

Collapse
bitario profile image
Collapse
zoechi profile image
Günter Zöchbauer

I prefer Flutter with Dart by far

Collapse
adrian5692 profile image
adrian5692

There's also the Xamarin Forms alternative for .NET developers, but I found it pretty tricky to do certain cross functionalities. It compiles native too

Collapse
ryhenness profile image
Ryan

Great read! I’ve taken a glance at Electron before, and this article has definitely opened my curiosity back up for cross platform JS, thank you. :)

Collapse
bitario profile image
Collapse
avinasha profile image
Avinasha Shastry

I love the way you explain the light --> heavy application! I feel it too! Thanks for a great article! I am getting into React Native. Your source code is a great way to learn!

Collapse
bitario profile image
Mo Bitar Author

Glad it's useful!

Collapse
darshansharma profile image
Darshan Sharma

I am feeling light now. lol
Everything you had written, I can relate.

Collapse
danakachan profile image
Dana Kachan

Perfect title :)

Collapse
brunolm profile image
BrunoLM

I've had quite some issues to create unit tests and with the navigation component that doesn't work for some people.

Native feels way too beta...

Collapse
ezequielfalcon profile image
Ezequiel Falcón

I'm into Angular right now... and sometimes this feeling of never settling with one framework and going through all of it scares me.... but then I think... 'Never settle' ;)

I buy it

Collapse
musa profile image
Musa Barighzaai

Hi Mo,

Any recommendations for learning React Native for React DOM devs?

Collapse
bitario profile image
Mo Bitar Author

Hey, I've only dabbled briefly with React, so couldn't offer specialized advice. But, they're mighty similar, so you should feel right at home.