IMO it really depends. There's a lot of big companies that have more than enough resources to be able to pay multiple dev teams to build and maintain apps across operating systems.
From a few years ago, Twitter and Facebook were famous examples. They pushed so hard to try and build their apps using web technology but kept running into performance issues (thanks to infinite scrolling). After spending fuck knows how much they finally admitted that maybe native components are better.
But this is Facebook, who have so much resources they can afford to build their own version of PHP three times over. I just don't understand why they put so much effort into trying to fit a square peg into a round hole instead of just going with native development.
But, I'm not an insider, I don't know the thought processes behind it. Long story short, IMO people overestimate how complex it is to build multiple native apps in parallel.
people overestimate how complex it is to build multiple native apps in parallel.
I agree, although there are now more platforms to deal with than back in the days when it was just Mac and Windows: add iOS, Android, desktop web, mobile web.
I think it also helps when it's easy to share code between platforms, which again, used to be easier when you were just targeting the desktop (just use C or C++).
Now it's a bit harder because there are no great languages that span all platforms easily without a bit of hacking. Most languages are managed and memory-safe now; that's a good thing, but it makes them more heavyweight and less portable. They generally want to drag in their own frameworks (e.g. Flutter, React Native) rather than letting you put your own UI layer on top.
I remember the days of Apple II, TSR-80, Commodore 64, Commodore 128, ZX Spectrum, ZX Spectrum 128K, ZX Spectrum 128K +2A, ZX Spectrum 128K +3A, Atari, Atari ST, Amiga 500, Amiga 600, Amiga 1200, PC CGA, PC EGA, PC VGA, PC PS2,.....
You’re right, of course! It’s amazing to think how many 8-bit and 16-bit games got ported to a whole bunch of different computers.
I was thinking mainly of the 90s and early 2000s, I guess, and for desktop apps where the main platform of interest was Windows, followed by a long tail of Mac, X-Windows, BeOS, etc... All those platforms could “easily” (i.e. with effort, but no rocket science required) be handled by a single C/C++ codebase with platform-specific #ifdefs.
I think the equivalent for today’s platforms would have to be Javascript. Unlike the C/C++ approach, you lose direct access to platform features.
> I just don't understand why they put so much effort into trying to fit a square peg into a round hole instead of just going with native development.
I think in the case of something like Facebook, the sheer complexity of their product drives a need for a singular code base. It would slow their engineering organization to a halt to ensure feature parity with largely seperate code bases.
This is only true if you're working with multiple completely separate teams each working in a silo to develop their own product and then post hoc some manager decides they have to have the same feature set. If they do it the right way around, specifying the common feature set comes first and then the dev teams do the app architecture on their separate platforms. As the features are developed and change requests inevitably arrive, the same sequence applies and you have an orderly process and the same app on two or more platforms without having to graft a third party dependency octopus onto your codebase.
It depends what you mean by “re-writing the same app”. In general you can have the core features written in C++, thus available everywhere, then write a platform specific layer on top of this. That’s a quite common approach, and if done correctly (that’s not a trivial task though) allow you to target any platform without too much effort. But yes, you still have to maintain a bunch of stuff for each platform:
- implementation of the platform specific layer, supporting all the quirks of the target platform
- testing setup
- build system (some platforms have a lot of weird details to take in account)
The cost-benefit can be ok or terrible depending on the project. But for example for games, where you will draw your own UI anyway, that’s very common, and as far as I know that’s also what Microsoft is doing for their Office applications: common core in C++, then platform specific C#/Java/Objectice-C UIs.
The expectation level for UIs on mobile devices has been set very high. There is a lot of detail to get right in order to deliver the experience that people expect. That UI specific work is very time consuming.
It doesn't really matter what else is going on in your app, if that work can be done more efficiently to produce a more consistent result, then that's the decision you make.
> work can be done more efficiently to produce a more consistent result
Often with frameworks like React Native or Flutter, it means inconsistent UX bugs on each platform. Why do you think Facebook and Instagram and Airbnb abandoned RN in all their primary interfaces?
The "more efficient" implementation might lead to consistency across platforms, but people are pretty tied to the phones they have. Things like dropped frames, slow scrolling, UI locks, all have a subtle effect on the user whether they can point it out or not, and you're more likely to have those problems by diving in to these frameworks without understanding the underlying platforms.
This isn't argument to share no code whatsoever. But so many people who immediately turn to these frameworks either want to ship something at the expense of UX/design, their app is so small that it doesn't matter, or they have no idea what they're getting into.
Only when one doesn't use a solution like having the common logic in a portable language like C++, with bindings to native UI elements.
A solution used by plenty of commercial desktop software as we moved from Assembly as main application language for desktop apps during the 16 bit days.
Agreed. Mixing business logic and UI works in simple applications, prototypes, or applications intended to ever work with one platform and UI paradigm. Outside of that, you're supposed to keep your "business logic" and UI separate (isn't this exactly why people invented MVC?).
Maintaining "5 different native UI applications" should involve one codebase with the whole internal logic, and 5 separate UI layers mediating between that logic and the platform it's being run on (including UI). It should not involve rewriting the same thing 5 times.
Often you can offload the business logic to the backend. That way you don’t have to implement it multiple times for each platform and you can change it “immediately” even if users don’t update their apps.
In such cases that same backend can send an XML (or JSON if you will) DSL payload that generates such UIs on the fly using the native widgets.
Pretty easy to create such framework in something like C++ or having a scripting language that drives the native UI widgets, something like JavaScript.
UI these days is often more complex than the underlying logic itself. App logic became, to me, even secondary. Most of those issues are solved problems (databases, sql, rest, xml, json) and are mindnumbingly stupid and boring to implement. Save data record.. query data record.. validate data record, yeah, yeah, really complex.
It’s great that there are a lot of cross platform solutions today. On the other hand it’s also the reason why we put up with shit apps like Slack’s desktop and mobile clients.
As a macOS and iOS user I’m sad because both platforms have a far superior native UI, but at the same time as a developer I’m glad I can quickly build things for multiple platforms because there is no way my customers would pay for separate native implementations.
> Some would say re-writing the same app 5 times (Windows, macOS, Linux, iOS, Android) and maintaining 5 codebases is a bad idea.
Yeah, that's true. I'm looking forwards to React Native (AFAIK it uses the native JS engine + native toolkits) and libui.
I'm also hoping for declarative UI frameworks like SwiftUI so that the underlying framework/runtime can generate the appropriate UI for the exact target platform.
I worked on Xamarin app and saw how things worked there. I also think that it's a logical conclusion from these conditions:
1. You want to support N native platforms.
2. Each of these platforms has it's own way of doing this, bugs, etc.
3. Each of these platforms is being actively developed.
4. There are differences between those platforms. One doesn't have guassian blur, the other one doesn't have right-to-left languages.
Right, but QT apps are QT apps -- they're not really native on any platform which is the same problem you run into with Flutter an Electron.
If you want an app that has platform semantics on every major platform then you need separate code bases. If you want an app that has the same semantics on every platform then you go with a cross-platform toolkit.
So you are arguing that no one "would say re-writing the same app 5 times and maintaining 5 codebases is a bad idea."?
That was my statement. You are saying it's not true. All the upvotes suggest some would say that. Therefore my statement is true.
I'm not sure why you're so confused here. This isn't at all applicable to what you are saying. You are talking about writing an app once and having one code base, which is exactly the opposite of what I was talking about. You have constructed a straw man and called it not true.
> draws everything from scratch is a bad idea.
> re-writing the same app 5 times (Windows, macOS, Linux, iOS, Android) and maintaining 5 codebases is a bad idea.
So probably React Native's approach (the approach itself, not React Native) is a really good idea, where you can:
1. Sharing code if you don't like re-writing n times.
2. Not sharing code if you want to have different native stuff for different platforms.
3. Mix 1 and 2 at any percentage as you wish. Typically reuse all the business logic, and separate view components.
I do get that, but one is bad for developers and the other is bad for users. It’s up to you to decide which is more important for your project. Most projects I’ve worked on, the user experience was more important to the business, in which case native apps are better.
I assume you also do custom code for each platform inside Flutter as we do to respect iOS and Android guidelines. Some things are different and need separate code. This is a pain too. I had much better experience coding only for the platform than using Flutter.
Qt is a really good solution, but I personally always failed to build something that works with it. I find their documentation and tools really difficult to grasp.
I don't understand the goal of 0% platform specific code (on a lower power device where UX is very important) or even further being able to make a whole app without having to learn about the platform, being aware of its conventions and limitations.
I've never finished a React Native app without native code. I've done a few now and I've come to believe it's not worth even trying to avoid it and sometimes worthwhile to look for places where a little native module can yield performance or UI wins. React Native is the glue or orchestration and it is, to me, extremely good glue.
I haven't seen many people beyond the tutorial level suggest otherwise. It provides a common structure (which is enormously useful), and some quick consistency wins for simple stuff like your About Us screen.
From a few years ago, Twitter and Facebook were famous examples. They pushed so hard to try and build their apps using web technology but kept running into performance issues (thanks to infinite scrolling). After spending fuck knows how much they finally admitted that maybe native components are better.
But this is Facebook, who have so much resources they can afford to build their own version of PHP three times over. I just don't understand why they put so much effort into trying to fit a square peg into a round hole instead of just going with native development.
But, I'm not an insider, I don't know the thought processes behind it. Long story short, IMO people overestimate how complex it is to build multiple native apps in parallel.