
Hybrid Mobile Development
The state of the art
You know that classic conversation when someone appears out of nowhere and says "I had an idea for an app"? Well, besides trying to escape that big problem which often turns out to be somewhat unorthodox ideas, we also have to think about which technologies to use in mobile development. And today the hybrid world is much more interesting than it used to be.
The current landscape: React Native, Flutter, and Expo on the front line
When we look at the current market, three names completely dominate the hybrid development scene. React Native remains very strong, especially in markets like Portugal, where most hybrid projects you see around still rely on this technology. And it's no coincidence - if you have a team that already masters JavaScript, it makes perfect sense to leverage that knowledge.
Flutter is also gaining a lot of ground, mainly among developers coming from more varied backgrounds. For those with experience in C#, Kotlin, or Java, the Dart language ends up having a smoother learning curve. And the truth is, we're seeing more and more job openings for Flutter, including for juniors, which was a novelty until recently.
But one of the big surprises has been Expo. Remember when everyone said Expo was going to die around 2019? Well, not only did it not die, but the official React Native documentation itself now recommends starting new projects with Expo. It's like a layer that removes a lot of the complexity of traditional React Native.
The performance revolution: Bridgeless and Impeller
One of the things that impresses me most is how the performance issue, which was the Achilles' heel of hybrid development, is much more resolved. Remember the days of PhoneGap and Cordova? There was a brutal difference between hybrid and native. Nowadays, that difference is much smaller.
In React Native, the big change was the new bridgeless architecture. Before, whenever you needed to communicate with something native, it had to go through a bridge that translated one thing to another, and that was synchronous. Now, the JavaScript code goes there and talks directly to the native code. The performance difference is no longer that big compared to native.
On the Flutter side, they had an interesting evolution with the rendering engine. They started with Skia, then switched to Impeller to achieve smoother animations. Flutter can deliver a maximum of 60 frames per second, which brings animations much closer to the native experience.
The challenge of device fragmentation
Now, let's not pretend it's all a bed of roses. One of the things that most puts people off the mobile world is device fragmentation. If we take an iPhone, it's just one operating system, all good, but we have several iPhones, each with its own performance. On Android, the situation expands much more - not only do we have many different versions of Android but also many flavors of systems customized by manufacturers.
I've had some pretty complicated experiences with this. Once I had a bug on a specific client who used some LG device, and the keyboard didn't work the same way as on other devices. Debugging it was a bit of a hassle because there's no specific emulator for LG.
Xiaomi, for example, spent a long time with a bug where when you took a screenshot, the screen would darken because the screen recording happened a few microseconds later, when the animation was darkening. So the screenshots always came out a bit darker.
Fortunately, today we have tools like BrowserStack, which is paid and online. You can upload your APK or IPA and it gives you a range of real devices that you can test online. It helps a lot when working on projects that are used on both tablets and various devices.
Design Systems: iOS vs Android
One interesting thing is how Apple has that historical obsession with consistency. Everything has to have an "Apple look". And you see an evolution in the design systems of the two operating systems that has reached a level of maturity where, generally speaking, the Android apps you run look like Android, and the iOS apps look like iOS.
The difference lies in the approach. React Native compiles React components into actual native components. That is, if it's pulling the native component, when there's an update to iOS or Android, it continues to pull from the native. You gain that "look and feel" closer to the operating system.
Flutter, on the other hand, has a different premise because it works with Canvas - it draws the components on the screen instead of pulling the native component. When an operating system update comes out, you have to keep an eye on the Flutter documentation to know when the new version of Material Design for Android and Cupertino for iOS will be available.
These are different premises. If you want to always be on the latest version of the operating system's design, React Native doesn't suffer from that. But if you want to create a unique company identity, less tied to the operating system, Flutter can help you a lot in that direction.
Expo: From ugly duckling to official recommendation
One of the coolest things to follow is the evolution of Expo. There was a time when, if you wanted to do something more complex, you had to "eject" from Expo because it couldn't handle it. Now it's not like that anymore. You'll probably be able to keep it for a long time without needing to eject.
Expo abstracted a lot of the complexity of very useful things. Before, if you wanted to put a font in React Native, you had to do several steps to install a simple font, which is something you'll have in every project. Expo abstracts that beautifully. Today it has many ready-to-use libraries for Firebase, Stripe, authentication with Apple and Google, cameras, gyroscope, Bluetooth...
And one thing many people don't know: the official React Native documentation itself now says that if you want to start a project, you should start with Expo. It seems they really want to replace the traditional CLI.
Job market: Different realities
When we look at the job market, we see very different realities depending on the region. In Portugal, for example, there is a much greater proximity to React Native. You see quite a few React Native vacancies, and for people coming from the web, it makes sense - they already know JavaScript.
In Brazil, for example, there is an interesting growth of Flutter. People with a backend background, who come from C#, Java, or Kotlin, find the Dart learning curve more accessible.
One interesting thing is that we are seeing more and more vacancies for junior Flutter developers, which was a novelty. Previously, companies always wanted someone with experience, but now there is space for those who are starting out.
Alternative stores: A new reality
One thing that is shaking up the ecosystem is non-exclusive app stores. On iOS, this is already a reality in Europe because of the Digital Markets Act. On Android, there have always been several stores, but now on iOS we are also starting to see alternatives.
For those who develop and submit to the stores, in terms of code nothing changes because in the end you will generate a package (IPA, APK) and the operating system knows how to handle that. But where there can be implications is in the development and distribution cycle.
Apple has always been more restrictive - that whole procession to submit an app, back and forth, it gets rejected, resubmitted... But that also ensures that someone is looking to make sure what is going to be published doesn't have anything malicious.
The Dart ecosystem: More than just Flutter
One interesting thing is to see how the Dart ecosystem is growing beyond Flutter. There are initiatives like Shelf, which is a library for building web services, and Serverpod, which is a backend built in Dart primarily for Flutter.
The idea is simple: if you have a Flutter specialist, why on earth would you learn Dart just to build an app? Normally, when that happens, the app is not the main product - it's to meet a specific market demand.
But if you're starting a startup or a new technology, and someone on the team already knows Flutter, it can be as good a choice as any other. It has its trade-offs, but it also has its advantages.
Capacitor: The successor to Cordova
Another interesting change is the transition from Cordova to Capacitor. Ionic, which used to use Cordova under the hood, now uses Capacitor by default. Capacitor's premise is to be an "improved Cordova" - a different version that takes on the responsibilities of communicating with native code, but more efficiently.
Xamarin RIP, MAUI Hello
And since we're talking about frameworks that died, we can't forget Xamarin. Some were very happy and had that Viking funeral, but now Microsoft has come with MAUI (Multi-platform App UI) to replace it.
MAUI is a natural evolution of Xamarin. The main change is in the architecture - instead of having a separate project for each platform, now it's a single project where each folder has its specific target. A lot has changed under the hood, and it now uses modern .NET to run.
Animations: The mobile obsession
One thing anyone working with mobile quickly realizes is the obsession this world has with animations and transitions. If you don't have fluid animations, the user will feel that the application is less responsive or is having problems.
Both React Native and Flutter have made huge investments in this area. React Native implemented game engines to create smoother animations, and Flutter has that 60 frames per second perspective to bring animations more consistent with native usage.
Linx: The Chinese innovation
An interesting novelty comes from China with Linx, developed by ByteDance (the company behind TikTok). It came as a "revolution" in the React Native universe, focused on converting web developers to mobile and optimized for "instant first frame," meaning the moment you click on the application, it should be instantaneous.
Considerations for framework choice
When it comes to choosing a framework, it all depends on the context. If you have a team that already knows JavaScript, why on earth would you learn Dart to build an app? Normally, when that happens, the app is not the main product - it's to meet a specific market demand.
But if you're starting a startup or a new technology, and someone on the team already knows Flutter, it can be as good a choice as any other. It has its trade-offs, but it also has its advantages.
Tips for different profiles
For those who haven't entered the market yet, the advice is to focus heavily on the basics: programming logic, HTML/CSS (even if you don't focus on web, it will serve you well), and the language you choose - be it JavaScript, Dart, or another.
For those who already develop but don't have mobile experience, the path is to take the language you already master and see if it has any options for mobile. If you are a C# or Java developer, look at Flutter. If you come from the web with JavaScript, React Native makes sense.
And for those who are already at a more advanced point in their career? Just say "it depends" and talk about trade-offs. That's the reality - there is no perfect solution for all cases.
The future of hybrid development
Hybrid development has reached an impressive level of maturity. The performance difference with native is getting smaller and smaller, the tools are more mature, and the ecosystem is richer.
The choice between frameworks is no longer so much about which is technically superior, but rather about which best suits the context of the team, the project, and the objectives. And that's a good thing - it means we have solid options for practically any scenario.
In the end, as any experienced developer would say: it depends. But at least now we have quality dependencies to choose from.