A New Wave
Over the past year, there's been a consistent growth in the number of videos, walk-throughs, and supportive articles regarding the use of cross-platform frameworks to build applications with. Heck, even I've written a couple articles touting the ease-of-use of cross-platform frameworks...namely React Native and it's popular Expo framework for mobile app development, and the Rust-powered Tauri framework for building desktop applications.
These frameworks have become powerhouses in the app-dev sphere, and are go-to's for rapid project development for both teams and individual developers alike! One could reasonably argue that the success of these cross-platform frameworks leaves other native platform languages out in the cold with no real purpose...but I'm not so convinced!
The (Not So Simple) Answer
I've begun to notice a growing trend as of late, and I'm sure many of you have as well:
Everywhere you turn, there's another new article or Youtube video touting that Native app development is dead, and that everyone should just come to grips with that, and start building their applications with some cool cross-platform framework such as Flutter...
At first glance, seeing so many people promoting these frameworks might make you think it's a no-brainer to make the switch! Personally, even I found myself drawn to checking out expo as a means of shifting my mobile development to a more cross-platform scheme...and it worked out great!
But here's a newsflash: cross-platform frameworks haven't all of a sudden become the end-all-be-all solution to app development!
I know, I know, I can hear many of you screaming it out already:
"Why would you say something like that?! Don't you know how awesome Flutter is?? It allows you to have the same codebase for all the different platforms! There's literally no reason to waste time learning multiple native languages when you've got Flutter!"
The same thing could be said for Expo, which I DO still use for some of my mobile app development. The important thing that many developers need to realize, is that while a number of these (truly impressive) frameworks have a legitimate use in building many different applications, they are not (and should not) be the only way to do so!
Frameworks such as Expo and Flutter offer an excellent alternative for creating applications for iOS and Android without having to spend time building separate codebases. Heck, they can even use the same code for building desktop versions of the app! The thing is, there's always a catch...
First things first, let's revisit why one might prefer to choose a cross-platform framework like Expo to prototype and develop their mobile app:
Uses JavaScript and React: If you have experience with JavaScript and React, React Native is a perfect fit, allowing you to leverage the same skills to build both impressive UI's and backend functionality.
Rich Ecosystem: The extensive library of third-party plugins and components accelerates development, and provides just about everything you would need to build a fully-functional production app (though it may take some configuring).
So, there are certainly a number of intriguing reasons to lean towards using something like Expo to build and release an Android application...but as I said previously, nothing is without a downside. I've had the unfortunate first-hand experience recently to deal with this myself:
Bloated Binaries: While having the ability to write both UI and backend code in JavaScript is a wonderful thing for experienced web developers, it brings with it the need for a translation layer that adds to the overall app binary size, and has the potential to impact overall performance
Dependency Hell: Node Modules have the ability to be a jumbled mess as-is sometimes, but all that aside, the constant dependency changes can regularly cause issues building your application from one version to the next...especially if core dependencies require a NodeJS version upgrade that by itself can break other modules
Native Module Nightmares: If you're looking to incorporate some kind of native Android functionality, in my case widgets, you're required to "eject" or generate native code to write these features. This requires additional work adding compatibility layers for it to work. It's a great feeling once it's all together, but once the NodeJS version gets bumped, instability may soon follow and require re-writes
With all this in mind, I've reached the following conclusion (and I think many of you would as well):
If you want to have a completely managed project using Expo, and have no plans for additional fancy bells and whistles, you have an absolutely fantastic set of tools at your fingertips using React Native and the Expo framework! By all means, check it out and see what magic you can write.
If you want something more, however, like the raw power and speed of a purely native application...keep reading!
Revisiting Native Development
For years, the one and only language that typically came to mind when thinking of Android app development was Java. It's a powerful and performant language, but requires a heck of a lot of boilerplate code to put everything together! Not only that: While Java powered the backend of these applications, XML markup files handled the user interface (UI).
I'm not sure what all of your opinions are of writing UI's using XML, but I'll tell you right now...it's definitely not my preferred option!
No worries, though! As is the case with iOS apps as well, Android development has shifted in recent years to utilize a declarative approach to building user interfaces, as well as handling app logic. The Android approach to this involves the use of a popular type-safe language developed by JetBrains called Kotlin, in conjunction with a newly revamped UI framework called Jetpack Compose.
A couple key features include:
Declarative UI: Allows developers to describe the UI in a straightforward manner, reducing code confusion and overlap thanks to more reusable components
Interoperability: Jetpack Compose can coexist with traditional Android Views, allowing for gradual migration in existing Java-based apps.
So not only do you get an application that runs at full native speeds, you're equipped with a flexible UI framework that doesn't require you to write any compatibility layers to work smoothly. Like I said earlier, though, nothing is without downsides. If you're not familiar with writing code in Kotlin, there can be a learning curve especially if coming from web development using JavaScript (perhaps not as much with TypeScript).
Drawing Conclusions
While there are clearly a number of popular and impressive cross-platform frameworks out there supporting mobile development, it should go without saying that by no means is native development dead...quite the contrary! The native landscape has continued to evolve and grow to become an extremely enticing option for those looking to get the most out of their applications, and in the smallest of packages. Android has Jetpack Compose and iOS has SwitUI, both of which offer an exceptional experience for both developers and application users...which is really what it all boils down to.
The sheer number of options can be dizzying at times, but I implore you, take the time to review what you're looking for in your app and make your framework choice accordingly.
Cross-platform options have come a long ways the past few years, which is truly a welcome reprieve for those looking for other ways to get involved in mobile development. And while that may be true, they're not the only option.
Some may not care to admit it, but native app development isn't going anywhere...anytime soon!