I initially had a similar thought, but I don't think that applies here.
With Electron, you don't write a cross-platform base and then write all the platform-specific goo on top of it. You just write your app using web technologies, press the build button, and ship it on all the platforms you want to support.
Since web technologies are popular, you don't end up with the same issues hiring and training developers like you do when you need to teach a new hire about your bespoke cross-platform mobile solution.
With Electron, essentially your users pay for all of this by being forced to adopt a resource-hungry platform, while the development team gets a mostly-free pass.
Having worked in multiple places that ship iOS and Android, the real thing to focus on is cross-platform requirements, not code.
Writing mobile apps is fairly trivial - writing good requirement documents is black magic I have yet to see in the real world.
Trying to share code is like trying scratch your left foot when your right foot itches. The issue with two codebases that are supposed to do the same thing is keeping them in sync over time. The only way to do that is by having actual requirement documents.
This made me think: I've found it hard enough to share code effectively on the backend, even when we're all using the same language and frameworks.
And people think it'll be easy to share code when you're targeting two completely different platforms with completely different frameworks in completely different languages?
> Even before the core group moved on, mobile engineers were generally not interested in learning C++, so finding people to train was a big issue
Yeah, I probably wouldn't be super interested in mastering the arcane details of one company's bespoke stack; that knowledge would be really difficult to leverage elsewhere. Most places that need mobile engineers won't care about the bespoke C++ stuff, and most places that want people to write C++ wouldn't know what to do with someone who wrote C++ for a mobile app.
It's funny that they have a hard time hiring experienced senior C++ devs even though the language has been around so long. Presumably it would have been easier to find someone really good at something newer like, say, Vue.
I recently had to use a bit of Scala for some load-testing, I've never had so much trouble doing something seemingly so trivial; in this case, sending a JSON HTTP request. It was honestly a matter of hours. Pretty humbling experience!
I used to maintain a couple of systems that between them were around 4 million lines of C++. Initially, in 2004, it would take about 16 hours to do a clean build. By the time I left that job, due to better hardware, precompiled headers and reduced dependencies, and smaller code for same functionality, clean build was down to 45 minutes.
The biggest winner, in my experience, was reducing dependencies in headers. Use forword declarations, etc. Precompiled headers helped a lot on Windows, but less so on Linux for the same code (but it still helped).
Incremental builds were fairly snappy, a minute or two (pretty good for a large C++ project).
Yeah, I have 15 years of C++ experience, but not since 2012. So with C++11 and C++17 (and soon C++20) my skills have not aged well, even though I can still write C++03 just fine. It's no wonder 'senior' devs prefer to use plain C, where even C11 is not that different from C99.
I don't think that's necessarily the case. C++'s famed backwards compatibility, source of so many issues, is also a fabulous strength. There's nothing stopping one from writing C++03, while gradually adapting C++11 and beyond as time/circumstances permit (which is what I'm doing at my job, maintaining a massive legacy codebase while stymied by slow uptake on newer compilers by my corporate overlords...)
> It's no wonder 'senior' devs prefer to use plain C
Not this senior (in years, at least :)) dev. I've tasted RAII and I can't go back...
The problem from Dropbox's perspective is that they're not merely hiring someone to create a solo greenfield C++ codebase, but to contribute quickly to a codebase written in whatever arbitrary subset of C++ they blessed.
Funny, I too stopped using C++ around 2011. Recently I had to delve into Swift and learn it with great urgency... then my project changed direction toward C++ and Qt.
I find the '14 and '17 additions vastly improve C++ and in fact added things that I had just come to appreciate in Swift. So don't be too put off; learning the new stuff will help you if you need to adopt a more-recent language too.
> it became increasingly difficult to hire replacement senior engineers with relevant C++ experience who would be interested in mobile development.
It's not just familiarity with the language, it's being willing and able to develop within the mobile development context, which as stated in the article is a whole other beast
Let's be clear that senior C++ developers are masters of their domains because they enjoy solving a particular set of problems that a low overhead systems language requires.
However, in the mobile world, from my experience, hiring good senior mobile engineers means they come with a specific skillsets already. They can take a view, animate it a certain way, and then respond to touches. Those are things that are entirely platform specific domains. So they will come from Swift/Kotlin or ObjC/Java backgrounds. The ultimate problem here is those same engineers are typically turned off by C++ nor have the desire to learn it.
You can throw C++ engineers at the problem, but they will most likely be turned off by having to solve animation timing issues or custom navigation stack designs.
If you have a venn diagram of the two sets, there would probably be very little overlap.
This matches my experience - most C++ engineers I know have little desire to work on C++ for mobile after having tried it once. Most mobile developers tend to be specialized on mobile and don't focus so much on generalist C++ stuff. Some good ones do both and don't have problems finding work. :)
Mobile is getting crappier, so I can see why C++ developers would be reluctant to partake.
Google and Apple keep piling feature on top, so mobile has the 2nd biggest churn after front-end. Recently even the preferred programming language changed on both platforms.
It's under pressure from web-applications, which although of inferior quality are easier to develop.
Most apps aren't anything special and require mostly UI and UI framework skills (animations, platform-specific APIs, etc).
The overhead of C++ adoption actually prevented us from ever moving fully in this direction.
Today, unlike in 2013 when they started, there are other options.
For others considering code-sharing, another option not mentioned in their article is Rust for the core with Swift and Kotlin. Between bindgen, futures, serde_json and non-nullable pointers in Rust, those would satisfy their stated subcategories today.
Companion templates are explained here: (January 2019)
Medium.com/visly/rust-on-ios-39f799b3c1dd
Medium.com/visly/rust-on-android-19f34a2fb43
(No affiliation other than starting to proceed down this path myself.)
For Common Lisp heads, there's also MOCL, which seemed quite reasonable when I explored it years ago: wukix.com/mocl
I don't know enough details to say for sure, but some possibilities:
1. People may be more willing to learn Rust. I much prefer the language itself, but also it's clearly on the rise, so it may feel like a better learning investment.
2. The standard library is broader and the package ecosystem is easier to work with, so you might be able to have a more standard stack with fewer proprietary bits.
3. One complication with integrating multiple languages is making different memory management strategies coexist. Rust's type system seems to have ways of making that easier, e.g. neon-bindings.com
It is really easy to make a blunder in c++ that will require a lot of effort to find. Debugging that on mobile platforms is not fun. Like they mention a deadlocking issue that was difficult to solve.
Rust is built for memory and thread safety. Also the much better build system and open source ecosystem.
Its pretty evident from things they said in this blog post that they want to stay firmly in mainstream. They mentioned C/C++ is the only compiler supported by both platform vendors, which is important due to a "whole host of other issues" that they didn't specify. So using a compiler developed by a company that doesn't even sell commercial support would be a non-starter. Still there are commercially supported platforms that are quite mature at this point, such as Xamarin.
This reminds me of LLD’s approach of sharing an architecture but having separate ELF, COFF and Mach-O implementations. This made it much faster than gold which wasn’t actually slow.
Apparently sharing code isn’t necessarily a great idea.
I'm somewhat disappointed that this didn't work out, as I have usually promoted a C++ core along with a thin native wrapper as the solution for those looking to share code across platforms. At least they moved to native development, though, instead of some poor facsimile that was "easier"…
Curious about how well having that C++ core to share code has worked out for you in the past. Apart from low-level contained code that doesn't require access to too many OS interfaces (user I/O, network, threading, GPS etc) I can't imagine it would be easy or useful to have a C++ core.
Usually C++ runs core logic that cannot go on the server (that's things like your own custom client-side crypto, parsing, or other "pure computation") and then you make the user interface in Swift or Java depending on your platform.
I have come to this same conclusion after many years. It's not cost-effective to have any bespoke business logic (models, controllers, etc.) shared between the two mobile platforms (don't get me started on sharing UI code). If you have some incredibly tricky low-level algorithm/library and/or need for speed, think database, crypto, intense graphics, etc., then fine, you may be able to swing a shared module in C++ or something. Other than that, it's almost like the collective consciousnesses of Google and Apple conspire to make cost-effective code-sharing of typical CRUD apps almost impossible.
Here's a fine alternative to code-sharing: well first and foremost you need to have a good requirements spec. After that, implement it on one platform first in a platform agnostic way. So heavy use of delegates/interfaces/injections to handle platform-specific functionality, even for one-liners like getting current system time. So the code should be pure, boring, plain old Java, Kotlin, Swift, whatever. Minimal use of fancy language features that may not port cleanly. After one platform has the module in place and well-tested, do a copy/paste port to the other platform. You will find that the copy/paste port will actually uncover bugs, optimizations, edge cases, etc., that can then be ported back to the original platform. Things you would not have found if you were only writing the code once. It's like the most intense kind of PR code review you can get.
So I've found that copy/paste-port-based code sharing between platforms is not just a lesser evil, but actually a strategy that has its own unique benefits. If you get into a groove you can build up a set of regexes to give you a sloppy transpiler that does most of the tedious porting for you.
Basically the same process as when you first started. Implement the changes on Platform A, get it stable, port it over to Platform B, get it stable, port back any refinements to platform A. Platform changes themselves should ideally be quarantined behind said abstractions/injections, so your actual ported code is very simple and "timeless": no fancy language features, no preprocessor magic, no annotations, no excessive syntactic sugar.
Approaches like this could increase the second-class-platform effect. Where, for example, Android gets updates long after IOS. (Unless both releases are synchronized.)
In theory the shared code approach means platforms could be tested in parallel.
The whole point of the post here is that the theory doesn't apply very well to modern mobile development, and trying to share code effectively slowed them way down.
The article says it all - they chose the wrong language with no community support for the trail they were blazing and that technical debt destroyed their productivity.
I achieved 90+% code share in Xamarin including UI across windows - ios - andriod. 100% buisness logic shared. You can write cross-platform UIs, and swap out to native code on a widget by widget basis. Threading is seemless. Sure it has its own set of issues, but everything is a trade-off. Look at your use case, and define what trade-offs you are happy with.
The drop-box use-case is also an outlier - to achieve high levels of responsiveness, it must integrate with low level platform specific APIs to the point their entire app may be some kind OS specific service. Look at blogs about their desktop apps and you see my point.
If you going to drink cool-aid from companies just because they are dominant in an area, atleast drink the cool-aid of a startup which was created for the purpose of building cross-platform apps.
It was years ago, but Rdio went the Xamarin route, regretted it, and then did exactly what Dropbox just did and went full native.
The reasons for regretting it were similar: lack of available engineers on the market, incompatibilities between runtimes, and lagging support for platform features (although in the Xamarin case it's not even in your hands to fix it)
Xamarin is indeed the closest there is to the holy grail of cross-mobile development. I too had some success with it for a small project at first, but just like the theme of the blog post, the challenge is in the long-term maintenance being cost-effective, not just the initial development. Especially in the face of these adversarial platforms constantly changing things underfoot. For example in Android recently I've been forced to switch to the AndroidX library, and iOS has Dark Mode coming out. Will Xamarin support both of those platform changes cleanly? Maybe, but it's a risk.
I'd be happy to hear if the project you worked on has been cost-effective to maintain in the long term. Then at least someone has seen the mountain top!
there is a difference between Xamarin and Xamarin.Forms, one thing is just C# => ObjC binding / C# => Java binding (C# to AOT native shared libraries and binds it into the native things), which basically SUPPORTS ALL of the native features.
so basically you can either have one application on top of a custom ui framework (xamarin.forms) or you can only share business logic, and write controllers, which feels native in c# or the native language.
i.e. without forms you can build a controller with objc or you can have the implementation in c#, and call into a shared business logic library.
unfortunatly the docs are really really weak when you consider what you really can do with xamarin.
with forms you can build a ui that works on both platforms so basically you have 100% shared code.
Xamarin on paper seems like the holy Grail, but the fact that Microsoft itself chose to use react native instead of its own solution for Skype made it seem like I should not expect long term commitment to xamarin from MS.
I would be careful to attribute framework decision making to careful thought. This is more the regular organizational dysfunctionality. Either:
- The entire organization uses a single framework (and improves on it), which will lead to a bunch of teams grumbling that "We are only using X because of organizational pressure, while Y is much better"
- You leave freedom to the org to pick their technology, and hope/steer people towards certain parts. But you will have to accept some divergence from the norm
I prefer the second org, and luckily I am in such a place where we can use Go while the team next to us is on Scala, and we weigh in-house developed technology against publicly available technology on ROI.
Office also has to make sure that things work on the web given they also support all the Office.com O365 versions of their apps. That's another reason they'd prefer React Native (for React Native Web) to Xamarin.
But the Office team is also a right tool for each job group and has both Xamarin and React Native apps and telling the difference between them is getting tougher to do. You can already integrate React Native components inside a Xamarin app and vice versa because they each can look like native components to each other, and it's not entirely an either/or decision.
I took a look at Xamarin recently to see how far it had come, and the tooling is really impressive. They seem to do a great job of keeping up to date with iOS/Android SDK changes, too.
But when trying to find an example of a native-feeling Xamarin-based app for iOS, I was really underwhelmed. I tried to find one that was (a) well-known and (b) third-party (not developed by Xamarin or Microsoft). The 4 contenders were:
- UPS - 1/4 stars - All views of the app are awkward embedded web views. Every page has a full screen modal spinner.
- Outback Steakhouse - 1/4 stars - Not updated for modern iPhones, so the whole app is letterboxed. UI is completely custom, so didn't attempt to feel native. Crashed as soon as it tried to get my location.
- Alaska Airlines - 3/4 stars - Feels native-ish, nice "vanilla" design. Mix of native forms and web views. All UI related to searching flights & buying tickets is a web view. Every tap on the tab bar causes a full screen modal spinner.
- FOX Sports - 4/4 stars - Wow, impressive. Lots of native-feeling views with their own branded styling. The custom widgets feel native.
It was great to find one "hero" app for Xamarin (FOX Sports), but the fact that it's an outlier is a little concerning.
I think there is a little bit of bias here. Companies that are prioritize look and feel over cost probably are going native. And companies that prioritize cost over look feel are free are going xamarin.
They specifically mentioned when I was interviewing there that the reason their Xamarin apps are so good is because they already know how to make good native iOS apps.
Also, I specifically asked about whether or not they would be using more technologies like Xamarin in the future and they didn't seem too keen on it.
According to them, making a truly native seeming app in Xamarin isn't much less work than making two separate native apps.
Thats the same experience with us except instead of Xamarin we used more popular cross platform mobile framework Flutter from google. Given most of business logic is maintained in back-end. Fron-end client be it mobile or web based needs UI and state management with some local data for offline storage. We thought it will be easy to share code across platform and we were so wrong.
Given advances in mobile platform and Native SDK a company like Google, Microsoft or Facebook will not be able to keep up with native SDK and will be one or two generations behind. You can see the result in issues on flutter project. Also given Swift has Python like syntax and ease of use with powerful toolchain and Kotlin with nice syntax with functional programming efforts are not that different working with native SDK.
Obviously this cross platform mobile framework are ok for simple crud apps. But when it comes to building a mobile app using modern vision, audio, keyboard, touch and gesture input along with modern sensors in the platform and provide a consistent UX is a big challenge. Also UI and UX have enough subtle differences across iOS and Android the code written to manage them is also substantial. So its nice to go native SDK route for mobile apps.
Many businesses go with Xamarin because some guy in a management mandates it because he feels it will be a silver bullet that will let them get around having to hire skilled native mobile developers.
The reality is that to do Xamarin well you’ll have to wander outside out Xamarin Forms, and to do that well not only do you need native mobile developers but you need far higher caliber native mobile devs who are able to mentally translate swift/objc and android calls into their C# equivalent, and who have an idea of what’s going on the os when there’s a crash at a level lower than the .NET runtime caused by a native part that’s not apparent in the crappy Xamarin stack trace.
Xamarin really only makes sense if your company has a mountain of existing complicated .NET code with priceless business logic that you absolutely have to reuse.
I used to work for them. Great company, great technical talent. If anyone wants to move to Charlottesville or Durham I encourage you to apply! I live in CVille and I love it.
The Xamarin folks are native platform engineers first. Xamarin teams comprise Android experts and iOS experts who did then went on to learn Xamarin on top.
This is a fascinating idea, and reminds me of the dreaded [1] rewrite, where you rewrite the application because the new system will always be better in the new framework...
But this is different, if you write things simply, so the code can be ported easily. Then you're essentially making the code easier to share, without tightly coupling it to a specific platform... seems like a big win to me
Agreed that it is both fascinating, and from the experience I’ve had with the approach, it has turned out to be quite an effective way to build very maintainable software.
I think that kills a lot of interesting projects right there. If I could write a solid spec, that would mean I believe I wouldn't learn much from shipping the product. And also that my competitors aren't learning or advancing.
Whatever you first create has some kind of vision behind it. Even if that vision is a rough spec, it might be precisely the little bit of spec that’s necessary to get things started.
A good requirements spec doesn’t mean it has to be heavyweight with all the corners and edges figured out. Instead, it can be just lightweight enough to get things moving in the proper direction... but some little direction is certainly needed.
Nobody says you have to write the spec beforehand.
As long as you don’t blurt a lazy “use the source Luke” and take the effort to document and edit the spec during or right after implementing something, it’s ok.
Nah, it’s just this whole manichean polemic between two grotesque caricatures of processes; agile improvisation vs upfront waterfall planning à la nazi wehrmacht going to Russia.
One just has to have an idea where to go before starting, and a good description where one went when you’re done.
Years ago I wrote a programming language a bit like Haxe, except that it let you 'inject' snippets of your target language wherever you wanted. So you could keep your major architecture in one common language and still implement specific cases on the spot (ie you don't have to go to other files, and the various implementations for different target languages were right next to each other, making it easier to keep them in sync).
I implemented targets for JS, php and C++. It worked okayish but in the end it was more work to maintain the separate language than just write everything 3 times with some help of a simple macro/template language. I still sometimes wonder if the concept would be developed further, with a proper team and good tooling etc, if it would be a practical way of doing large scale cross platform software development.
There's quite a few places that are still dealing with 4 codebases with varying degrees of shared code. Desktop, mobile web, native Android, native iOS.
A shame, since many of them don't really need more than one responsive web codebase. Native apps do add value for many use cases, but not all.
They add value in all cases by not needing 200mb memory to run what would be a 20mb app for native. It's crazy how my phone runs perfectly fine on 2gb ram but my laptop is swapping with 16gb just because slack, vscode and whatever else election app is running.
I just launched (like, an hour ago: https://news.ycombinator.com/item?id=20700196) a cross-platform app that is almost all shared code. In my case, the solution is a web app with very lightweight native wrappers, and I'm quite happy with it. Obviously that wouldn't be the perfect fit for all apps, but none of Dropbox's "(not so) hidden costs" are relevant in my case, and I suspect many apps would be a good fit for the architecture I went with.
Nope, that's not accurate at all. The native apps support push notifications, in-app payments, native UI elements, proper lifecycle management (storing in-progress doodles across the app being killed in the background, or the device being restarted, for example), and more offline support than would be possible with the website. Among other things.
The things that are in the native wrappers are things that would be iOS-specific or Android-specific regardless of zero shared code or maximum shared code. In my case, the bulk of the app is shared -- everything that can be a common code base is a common code base.
According to GitHub's rough metrics, that's:
Go 44.7% Dart 32.8% Java 7.1% JavaScript 6.9% Swift 6.6%
Most cross-platform solutions are great in the beginning and then the problems start to come to surface as teams grow, requirements change, bugs are harder to track down, code needs to be updated, the next hot cross-platform framework comes along with new promises, etc.
Sure but, these issues come to surface much quicker.
Every time I've started a new iOS project in the past ~2 years, I've reached out to a handful of developers and managers on how cross-platform is going for them. None have been completely sold on it. The ones that are, are the ones that have been doing it for a few months. I've come back around to talk to them months later and they aren't so confident in the decision anymore.
Recently worked at a company doing similar to this to support Windows and macOS.
To add to the difficulty, they used Chromium as a UI front end much like Electron. All built in house though.
They hired me as a JS/HTML/CSS dev, but same as the article states, the C++ work was the true bottleneck.
They knew I had some C++ chops and set me to work doing C++ with a sprinkle of JS here and there.
Due to incompatibilities in the compilers, there was a rats nest of dependencies, thousands of #ifdef’s to cover differing OS implementations, and we had to use some of the oldest versions of C++ to be compatible with both XCode and Visual Studio.
As the article states, we had custom background job libraries and debugging them was a nightmare.
Also similar to the article, we spent more time than one ever should setting up builds to handle our ludicrously complicated build configurations.
And lastly, as the article stated, we had a hard time finding new talent to cover the growing amount of work required to deliver our product. There just aren’t many C++/JS devs out there.
> And lastly, as the article stated, we had a hard time finding new talent to cover the growing amount of work required to deliver our product. There just aren’t many C++/JS devs out there.
Reading the article and now this, I really can't grok this perception. There are plenty of us out here, I think, it's just we're buried in the heap caused by mass resume farming, aka modern recruiting. Recruiters and hiring managers don't think of me as a senior dev with 15 years writing software and delivering value to end-users... I'm just YA candidate who doesn't have any experience in the latest JS framework du jour, so I might as well not exist.
> Due to incompatibilities in the compilers, there was a rats nest of dependencies, thousands of #ifdef’s to cover differing OS implementations, and we had to use some of the oldest versions of C++ to be compatible with both XCode and Visual Studio.
My current work has me on a single C++ code-base for Linux, Windows and MacOS (not electron though, just native). You can avoid a lot of headaches by avoiding the platform specific tools and instead cross compile using clang with a build system that works on all platforms (eg. ninja + meson).
+1 for Clang. It integrates with everything. But like most open source options, it plays second fiddle to each company’s primary languages, and so thee’s no one IDE so perfectly integrated into these mobile dev C++ use cases as to make it easy to work with, the way, say, you can be productive on .NET framework with either C# or C++. Google and Apple are both C++ compatible, or have native bindings, but... they target their examples and ease of use at the languages that best integrate with the respective IDEs. (Swift for Xcode, Kotlin for Android Studio) The end result is possible, but it’s like picking Cordova/PhoneGap/Electron for your native app. You’re going to struggle to use native technologies at some point, and there are few examples to follow. Allowing for the realization that 80% of your app code is likely platform-specific even if the UI doesn’t vary much means you can adopt new approaches and native UI conventions faster. It’s like the difference in programming speed when you simply target Chrome for your web development vs when you’re trying to write code that runs on Internet Explorer also. It’s getting to the point where platform functionality diverges so much that writing it but from the same design/spec/data model is faster than trying to maintain compatibility. Especially if you need to support multiple versions of iOS and Android in a backwards compatible way and with different UI conventions in different OS releases. Native is native, nothing else looks or feels like native, when that’s what you need, and there’s more hand-holding for apps when they follow the latest spec from the platform, rather than try to chase it with their custom bindings/implementation...
Note re. targeting a platform — often learning and reading some C++ is inescapable. For me, reading Chrome source code makes it easier to work with Puppeteer in JS, or deliver a better web app because I know how things work under the hood and it’s easier to read the C++ than the read the web standards themselves. Similarly, C++ really is portable and fast, so it shows up in many places. But on mobile, the mix of C++ to Swift/Kotlin should be 90%-platform native if your app is a traditional CRUD app that deeply integrates with the platform. If it’s simpler than that, build a website, or if it’s a game engine or some custom UI, use that, sure, but if you want to benefit the most from Apple and Google implementations, native (with shared spec/data models) is the way to go...
I agree you can avoid a lot of headaches by not using platform specific tools.
Unfortunately, once you get into users wanting OS specific feature support, all that goes out the window.
You now are forced to maintain multiple versions of your product that differ greatly per operating system.
Pair that with the fact the codebase was almost 20 years old, you get some fun legacy code support issues that a lot of C++ projects naturally have due to the fact that C++ is not a new language.
I'm currently working on some code that is for VS/Windows, Clang/macOS, and GCC/Linux. I'm just setting the std to C++17 on all of them with no extensions. I have had some warnings that have sprung up on some platforms, but not others. But I haven't run into any show-stopping incompatibilities for vanilla C++17. What should I be looking out for? Or was this a matter of using different standards on different compilers?
First of all, agree with your decision to use C++17. Great idea!
However, in our case (like with many C++ code bases) the code was almost 20 years old. Even with the Herculean efforts made by the teams to keep the code base up to date and refactored, you run into issues of backwards compatibility with older libraries.
C++17 is definitely the go to for new projects! However, I've never personally worked on a pure green field project written in C++ that didn't have to latch onto some older libraries that require older C++ std versions.
This is precisely the experience of my startup trying to rely on flutter. It's a constant battle. Moreover Android and iOS are different implementation with different capability with constantly evolving API. It's hard to keep cross platform code in sync many #ifdef with edge cases.
Moreover with REST API architecture majority of the common code is in back-end. So building in Swift and kotlin for respective platform is not as tedious.
If I use swift I get all the code examples and tons of documentation from Apple itself. In flutter I need to rely on some package which might not be supported, if my team takes over it's double the job fix the package bugs and also change the resulting changed in code, compile and test individually on iOS and Android.
Could you explain what you think of the pros and cons of flutter VS IONIC?
I think flutter and it's astonishing number of issues on github + their lack of manpower + their lack of major features + the presence of major performance and behavior bugs + the extremely small lib ecosystem (dart) is a major, useless risk for a startup for the benefit of tech hype.
(just my point of view, don't take it personally)
I haven't tried Ionic myself, but I have tried both React Native and Flutter for a small project and found Flutter to be more enjoyable and productive.
I build a small ionic app when it was based on angularjs with dependency on Cordova and later moved to webview. I didn't like the experience and personally I still prefer Python syntax over Javascript, so that was another factor. Now I think IONIC has moved to web components using stencil.js as the base. Web Components is still an evolving standard and will still take time to gain traction, moreover the available documentation and help is limited.
So if you compare ionic vs flutter I will still go with flutter given it generate binary app store package file by compiling dart code into native platform code. But given choice between native vs flutter I think except few use cases native still makes more sense.
Ionic lets me build a web app and publish it to any device pretty easily. I don't have to use their components either... in fact after using Ionic, you may not use Ionic anymore at all. All you need is Capacitor to publish it.
Flutter is it's own rendering engine, non-standard web language (Dart), and ecosystem. Ionic is just a CLI and collection of web components. Capacitor is Ionic's version of Cordova. It gives you access to device capabilities such as storage, camera, etc with very little code. So you can build a website, ask if it's Native on a device, and do more cool things if it is. Then push it to Android, iOS, and the Web.
Ionic supports Angular, React (now in RC0), and Vue (Beta). This allows you to learn popular frameworks while still developing with one code base.
Lastly, Ionic's Web Components are built using standard-compliant Web Components generated by a tool they made called StencilJS. So, now you can build a component in Stencil and publish it for simply the Web (No framework) or have them work with Angular, Vue or React. Larger corporations have started using StencilJS to manage their components when they use many frameworks. I use it because I don't know which framework I'll use next, or if I'll even use one.
Cordova is time tested and has a large community behind it. I choose Capacitor if it's available and then go to Cordova if it's not. Ionic has a collection of easy to use Cordova plugins (https://ionicframework.com/docs/native/overview). I have honestly found they they are not that well maintained. I ran into enough issues that I avoid them if I can. To be fair, the contributors are people contributing on their own free time with no financial incentive. Hence, I choose Capacitor when I can. They have a financial incentive (Ionic is open about this https://ionicframework.com/blog/ionic-2019-business-update/)
I joined when Capacitor was in beta and figured I'd use the up and coming. From research, it appeared there was a good reason Ionic created their own product. They didn't do it to simply stop using a tried and true product.
Also to be clear, Cordova is not an Ionic product. It was a great community thing for a while to talk to native devices.
I get the API differences on these platforms but at least in terms of the UI Flutter seems like a good choice. I'd imagine it'd still be easier to stick to Flutter than write two separate native apps in most cases, it seems to have gotten tooling right.
So I'm also interested in hearing more elaboration on how Flutter has been a struggle for you.
That's my point, subtle difference in UX like gesture, swipe and touch controls in iOS results in additional UI code in dart to account for each platform. Not much help except for simple mobile apps doing simple crud operations.
I've been building a Flutter app and it has been fantastic. I'm using one shared library flutter_barcode and while it isn't perfect, but it shows how easy it is to create native solutions for both platforms and marry them within Dart/Flutter itself.
I can't see how duplicating code in Swift/Kotlin would be any better than just writing it once in Dart. Dart is also quite a nice language to work in. Easy to get up to speed and a nice mix of static/dynamic typing. The optional Provider api make state management a breeze, no more Stateful widgets.
I've also switched from REST to GraphQL. I was a long time hold out there, but now I really see the advantages.
Anyway, just throwing this out there as another data point.
I thought exactly like you and was my view, until I tried to make a small app in Flutter. My startup was trying to build something like Google Lens with AR, and no way to do it in flutter without native code easily.
I like dart lang and done some small apps in it. It's Javaesque with similar style and learning curve. But still prefer Swift which is closer to python (we use python for back-end development) and Kotlin which has some nice functional programming primitives.
Also UX and guidelines are not uniform across mobile platforms. Android and iOS works in their own way to integrate different input like voice, visual and keyboard. Also mobile platforms on Android and iPhone are constantly evolving with new sensors, capabilities. Keeping native SDK itself is a gigantic task not sure how to manage cross platform SDK's. I am sure cross platform SDK can work for some use cases, but I feel it will still be way behind native SDK.
If back-end can take care of all the business logic and front-end manages UI and states with small necessary local data for offline, the efforts spend to develop cross platform app using flutter or natively in Swift and Kotlin won't be very different.
I still prefer REST over GraphQL because I like predictable performance in query and standard interface. Zen of Python PEP-20, explicit is better than implicit.
GraphQL is a solution to a problem of trying to manage business logic on client side so that it can manage ad-hoc query and get ad-hoc results from back-end. It was designed for a problem faced by Facebook. I have seen enough GraphQL code and still stay with REST Architecture, sometimes use protocol buffers for performance intensive parts.
You are right. I've done a lot of development in AIR myself and it is super impressive. Easy TypeScript like language. The Flex SDK is mature with all the standard stylable controls you need. Dedicated IDE that just works great. Easy deployment. I was able to build a cross platform (iOS/Android/Web/Desktop) video chat application with it and it looked and worked great everywhere. Someone dropped the ball somewhere with AIR.. I'm amazed they're still updating it.. that's something at least.
It baffles me that people think duplicating application code for every device is the way to go. Cross platform can be done correctly. I'm working on a stack that can natively target Windows, Mac, Linux, Android, iOS, MacOS, and Web. I couldn't imagine duplicating my code for each one of these devices. If something special needs to be done, I write an extension.
I have a feeling posts like these get upvoted because developers who make the native apps want to keep their jobs.
But those developers will always be needed for the native bridges, just not as many of them.
I took this as an argument for a thin, or at least thinner, client. If something is complicated and costly to maintain - shouldn't it move to the server? What complicated processes are you doing on-device that couldn't be done somewhere else & fronted by an API?
Done correctly != react native. I've had to shut down and migrate 3 RN projects because of how much of a mess it is. It's not even 1.0 and is a horrible choice for important apps.
There's a lot of valid points from native advocates though. Like differences in touch features, various sensor APIs, Firebase etc. These may not be serious considerations in simple apps but they make major difference to both the end user as well as the codebase/developer in larger scale / more serious apps.
That said, myself I still write Flutter too, having jumped ship from React Native.
But on React Native there are major platform differences that you also have to bridge. Moreover, as the platform essentially uses each platform's native components through that JSON serialized bridge you'll have UI inconsistencies between platforms when sharing code.
I'm very much in the cross platform is a bad idea camp. It's fine for sharing business logic and other non-UI code, but having tried several cross platform UI kits I've never found it to work well. Cross platform UI always ends up compromising on the native UIs strengths and uniqueness resulting in poor UX, poor accessibility, unaccceptable resource usage, bloated binary size etc. Just a few concrete examples:
- Non standard UI/UX is super common because cross platform UI targets the lowest common denominator. Flutter is the quintessential example of this, it throws away all native UI support and renders everything from scratch with low level graphics. In React Native I've observed several cases where iOS UI has been re-implemented, poorly, in Javascript and shipped on Android and iOS.
- Poor accessibility. Native iOS apps get a lot of accessibility for free because Apple has done a great job, with RN and especially Flutter you don't get this benefit.
- Resource consumption. Electron is terrible in this regard as is the common meme. React Native runs a JS VM for every app which surely has a negative impact on both battery and performance.
- Binary size. A basic Flutter/RN app easily pushes you past 20MB in app size on iOS, whereas a complex and complete app like Tweetbot is ~7MB.
It's certainly possible to build great UX with cross platform UI frameworks, but the amount of work required to do it well starts to get into the territory where you are better of just doing it natively in the first place.
React Native can wrap any native component and bridge it into your app. If you had bad experience with a 3rd party component, that's not RN's fault, build your own extensions you need, but for the most part you just need the core. It's still easier than rebuilding your app X times.
- React Native you most certainly do get accessibility.
- Running a JS VM isn't that bad, but it is a tradeoff. Imo it's completely worth it to prevent having to learn X different languages for each platform.
- The app size evens out, but yes the minimal is higher. However many apps are much larger than 20MB, it's better than other cross platform solutions
In no way are any of these things so bad where I would duplicate my code 6 times and then maintain them throughout the life of the project. That's just crazy.
> React Native can wrap any native component and bridge it into your app. If you had bad experience with a 3rd party component, that's not RN's fault, build your own extensions you need, but for the most part you just need the core. It's still easier than rebuilding your app X times.
Yes a great strength of React Native is that it still leverages the native UI kits and makes it possible to do so when building custom components. My comment wasn't about my experience, in fact I've built numerous bridged components in RN, but and observation about the react native community. In fact one of the most crucial lessons I've gathered when working with RN is that you must have both iOS and Android experts in your team to build good apps with RN successfully.
Here's just a few examples of popular 3rd party components(from awesome-react-native[0]) that are problematic in my eyes:
- react-native-swiper[1]. Completely custom JS implementation with a "iOS"y look. 8k stars
- react-native-gifted-chat[2]. Large completely custom JS implementation of chat UI. 8k stars
- react-native-slider[3]: A pure JS implementation of a slider. 1k stars
> - React Native you most certainly do get accessibility.
My point wasn't that it can't be done, but that it requires significantly more work that, let's face it, most developers will not do. With native UI you get a lot more for free which results in a better user experience for everyone.
> - Running a JS VM isn't that bad, but it is a tradeoff. Imo it's completely worth it to prevent having to learn X different languages for each platform.
I agree it's a tradeoff and to be fair I don't have more than a hunch that running a JS VM is bad for energy and resource usage. The tradeoff is distinctively on the user's expense in favour of the developers. As developers shouldn't we be making tradeoffs that benefit our users instead?
> - The app size evens out, but yes the minimal is higher. However many apps are much larger than 20MB, it's better than other cross platform solutions
Yes many native apps do grow quite large too, my point is the default. The most basic RN, but especially Flutter, app is much larger than the native counterpart. Again a distinct tradeoff on the user's experience in favour of the developer.
Some of your statements are partially correct, but a few of these assertions are flat out false for React Native. Let's look at them:
> - Binary size. A basic Flutter/RN app easily pushes you past 20MB in app size on iOS, whereas a complex and complete app like Tweetbot is ~7MB.
I have working examples of fairly complex production applications that are <=10 MB on iOS.
> - Poor accessibility. Native iOS apps get a lot of accessibility for free because Apple has done a great job, with RN and especially Flutter you don't get this benefit.
False statement. React Native provides you with ability to tag elements so you can use accessibility-tools to navigate the app. I have recently tested this with a RN app running on iOS 13 using the new voice control feature. Several testing frameworks also rely on these features being available.
> I have working examples of fairly complex production applications that are <=10 MB on iOS.
Fair, the problem isn't as bad for RN, for Flutter it's still very bad though.
> False statement. React Native provides you with ability to tag elements so you can use accessibility-tools to navigate the app. I have recently tested this with a RN app running on iOS 13 using the new voice control feature. Several testing frameworks also rely on these features being available.
The ability to tag elements is only a very simple basic requirment to get accessibility right. My point was more that if you use UIKit you get significant levels of accessibility for free.
Just as a quick example I did a quick ddg search for "react native how to create custom button" and all 5-7 top results that I looked at failed to set the appropriate accessibility roles so the button actually appears as button to a user with the screen reader. Yes you can still do accessibility right with RN, but it's not the easy to get it right be default and most app developers will not do this on their own.
> failed to set the appropriate accessibility roles so the button actually appears as button to a user with the screen reader
Appreciate that you looked into it. On iOS and you do not need to set anything to become screen reader friendly _in React Native_. The default TouchableOpacity with a simple piece of text inside of it will become focusable and iOS will read the text aloud for you. This works because RN uses native elements unlike Flutter, Electron, and others.
In fact, I took you up on the claim that it wouldn't read correctly. I used my app just now which has never been tested or optimized for accessibility. Covered my eyes and began navigating. It works just fine! All tappable elements are indeed read aloud. I was able to navigate through the app settings, change them, go back, and reload other screens, navigate to the updated content, and perform actions on the new content.
Please do not put RN in the same bucket as Flutter or Electron. They are fundamentally differently.
I've been considering building a pwa and using a webview as a pseudo native app I know iOS support isn't great but it seems to be improving and iOS push notifications could be built separately in the meantime. How's anyone tried this approach?
While PWA’s largely work, they provide a poor installation experience and little device integration. Most people use Apache Cordova, PhoneGap, or Ionic as wrappers to their mobile web app, providing expected installation experiences through app stores and common device integrations.
Are you really asking if someone has tried putting their website inside a webview and call it an “app”?
Have you heard of Electron, Cordova and tons of other crapware that help produce so much garbage “apps” every year, it would put to shame even the most toxic enterprises in an unregulated Republican dream?
I shudder to think how many people will read this headline and immediately takeaway that React Native/Flutter/Electron are terrible cross platform solutions.
I'm hoping more people will read this headline and at least take away that RN/Flutter/Electron should be approached with caution and care rather than "slap it in an Electron shell and it'll run great everywhere and everyone will love it," which is the implicit attitude that makes so many people, uh, not love it.
React Native, Flutter, and Electron have a lot of problems in between them. They are fairly good cross platform solutions, whether cross platform UI is actually a good idea is much more dubious, I lean towards no it's not.
I'm more excited about leveraging native platform UI with shared code in a common language like Rust. C++ as described in the blog is problematic for this.
TLDR - it's too hard to find senior C++ mobile devs.
I'm more intrigued by AirBNB moving away from React Native - the linked article says "RN was too small a component to bother supporting, and the developer experience wasn't up to par", but I'd like more detail than that.
I've been working with Flutter for the past 6 months, and it would definitely be my "go-to" for any mobile application.
To be fair, I did spend 2 weeks going down a rabbit-hole to get Flutter talking to a .NET assembly by embedding Mono and invoking via JNI/Obj C, so I know the pain of native interop. If you're mostly doing work at the native platform level, then I can imagine why you'd stay away from a cross-platform VM.
In my case, I ended up with a brittle project that was clearly going to be a PITA to maintain & automate builds for, so I just rewrote the component in question in Dart.
AirBnB has a series of in depth blog posts about their decision to abandon RN. In particular this quote seemed extremely worrying to me:
> While debugging, React Native attaches to a Chrome Developer Tools instance. This is great because it is a powerful debugger. However, once the debugger is attached, all JavaScript runs within Chrome’s V8 engine. This is fine 99.9% of the time. However, in one instance, we got bit when toLocaleString worked on iOS but only worked on Android while debugging. It turns out that the Android JSC doesn’t include it and it was silently failing unless you were debugging in which case it was using V8 which does. Without knowing technical details like this, it can lead to days of painful debugging for product engineers.
Having been bitten by this exact issue one or two times, meh. Par for the course in the life of a Javascript dev, really.
RN would definitely still be my go to tool for the majority of green-field mobile apps. If I'd already invested in learning flutter/Dart I'd probably feel the same about that, but certainly feel no urgent need to go out and learn it. As in, I don't think there's a significant difference in what I'd be able to accomplish, and my time is probably better invested elsewhere.
That's great from a dev perspective. Not so much from a product perspective, particularly if you operate at AirBNB scale and your issue could be costing lots of money for every second of failed debugging.
The best is when the app runs faster while debugging than it does on the phone because of this exact issue. I found it nearly impossible to profile sanely
Is flutter actually a good choice for a production app right now? I've heard really bad things about its bugs, but I admit it does look great to use and develop with.
It depends. If you want to write nice looking material design app, then yes, it works really well. As iOS developer I can say that flutter is much more pleasant than storyboards & UIKit (which is probably why Apple is working on SwiftUI).
It's a different story if you want to use native features. Plugins provided by community offer only basic functionality, and are often very buggy: you will encounter iOS bugs, Android bugs, Flutter bugs and plugin bugs, all in one package. Anyway, it sort of works if you plugins provide stuff that you need. If they don't, you are forced to fork the plugin and add ad those features, learning Android or iOS during the process, and writing a lot of boilerplate for communication.
Would like to see an analysis of the costs and benefits of two separate codebases after they are done with that and have given it time to prove itself... especially with the more complex code.
1.5 years ago Dropbox was looking into rewriting their shared mobile codebase in Rust. It's a shame this blog post doesn't touch upon that at all, instead focusing on C++.
> That being said, C/C++ are the only languages with a compiler supported by both Google and Apple, so using a different language would have created a whole host of other problems to deal with.
Likely too much friction. Native environments benefit from using the expected IDE and tooling integration to build UI apps on respective platform. C or C++ is the best common supported language, and they didn't even like that.
Also the UI frameworks are being written in said preferred language these days, eg SwiftUI, and adding one additional language could be perceived as a pain.
Apple ships a C++ compiler but you can't use C++ with Apple's platform SDKs. IF you want to use C++ you need to write Obj-C++ glue code to access most of the system frameworks, including UI code.
I would look at it differently, i.e, obj-c++ is a valid supported language environment, that makes interopt with C++ pleasant at least compared to other interopt choices. Developers may choose to target Obj-C++ even out of preference.
Metal shaders != Metal API. Metal API is Obj-C. Metal shaders are written in MSL (Metal Shading Language). C++ is still not involved, though MSL is admittedly based on C++.
"The Metal programming language is a C++14-based Specification with extensions and
restrictions. Refer to the C++14 Specification (also known as the ISO/IEC JTC1/SC22/WG21
N4431 Language Specification) for a detailed description of the language grammar.
This section and its subsections describe the modifications and restrictions to the C++14
language supported in Metal."
Also, the MSL and Objective-C compilers are built on top of LLVM, written in C++.
I don't know what point you're trying to make. MSL doesn't link with the rest of your program. No matter what language you use for your program, the shaders are written in MSL. For my program if I use Rust or C++ or Obj-C or Swift or a microscopic magnet and a very careful hand, I write my Metal shaders in MSL.
The fact that Metal itself requires the existence of C++ really has nothing to do with this topic though, which is whether there's any downside to writing your app in a language that Apple doesn't ship a compiler for. The fact that Metal shaders are written in a language based on C++ is irrelevant to this question, because it doesn't matter what language you pick for the rest of your app as Metal shaders don't link with your app. Swift has zero integration with C++ and yet I can write a Metal app using Swift, because the fact that the shaders are written in MSL has no impact on the fact that the app uses Swift.
And the language for writing drivers in is even more irrelevant because we're not talking about writing drivers. You can't write drivers in Swift either.
1st tier tooling supported by the platform won't break yearly on every new OS version and you don't have to wait until your 2nd tier tooling developers gets around to fixing it.
The platform developers will do their best to keep 1st tier tooling working and fix it when it breaks.
Code reuse on anything that is too complex will usually give you these issues as reuse doesn’t scale unless is very simple and function is super well defined and focused. Programmers will turn it into a monster as it evolves, usually
Add more fuel to the "write once, run anywhere" dumpster fire. Let's peek in there - I see C, C++, Java, JavaScript, stored procedures, wxWidgets, RubyMotion, GTK, QT, object oriented programming, functional programming, PhoneGap, React Native, Flutter, ... It is getting full in there.
What's that about the definition of insanity? Doing the same thing over and over and expecting a different result?
Sever side rendered HTML is the closest we've come, but that's not cool anymore.
wxWidgets does actually get close to that mark. But regardless of the library/programming environment, there will always be platform-specific code you have to deal with.
I don't think wxWidgets is a strong example for cross-platform success. While admittedly I haven't touched wxWidgets in years, back when I used it, I marvelled that it worked at all, as the source code was such an utter mess. For example, I found a bug where a class constructor would raise lifecycle change events before the constructor even finished, and the issue was brushed away on the mailing list. Argh.
If the user interface is usable and snappy, it is probably fine that it consumes twice as many resources as a similar native app would require for the same result.
Example: Slack.app is a huge memory hog (though not as bad as it was before their rewrite), but it fits decently into OS X and does not lag on me.
I have lots of RAM, so the extra consumption is fine.
Sure, it annoys some programmers that it could be more efficient, but other than them, who cares? Those guys are probably using Emacs or a CLI program as their client anyway.
(I must be a rare breed, since I do email, writing, and programming in Emacs, but not chat)
I think it's a bit of an unfair characterization. I don't use emac or CLI as my client, I enjoy a beautiful UI as much as the next guy but electron is a real bother to me.
I switched from Sublime to VS Code and went from 20MB of RAM usage to 500. Add slack, add discord, you now have GBs of RAM getting eaten up just for the UIs. Most mid-range laptops still only have 8GB of RAM, add a browser to the mix and it's a constant battle to have everything running smoothly, the programs frequently crash due to memory issues.
It's a real problem and not solely programmer efficiency-OCD.
While it's fair to assume most Electron apps are probably running old Electron (and thus Chromium), Electron itself has done a bunch of work to get caught up. Their 6.0 release was the first release to be shipped on the same day as the equivalent Chrome release https://electronjs.org/blog/electron-6-0 their plan is to stay at most one version behind https://electronjs.org/blog/12-week-cadence
My laptop has 8 gigs of RAM, and I run many programs simultaneously (usually including several codebase analysis servers behind Emacs, a VirtualBox VM or two, Slack, and of course tens of Chrome tabs, several in development mode), but I don't have anything like the problems you describe. I do use The Great Suspender aggressively in Chrome and that does help a lot.
My Emacs instance itself is extremely tricked out with extensions and usually weighs in between 100 and 200 MB of RAM. Maybe that's the difference - sounds like VS Code eats a lot more.
I'm on a MacBook Pro from 2015 at work, if memory serves.
What setup are you running that handles your needs so poorly?
I'm impressed you can run all that especially multiple VMs on 8gb, I have to close Firefox when I need VMs.
I'm on windows 7, on a Dell Inspiron with a RAM and disk upgrade, no special configuration or software. I didn't think to look for an addon to do that, that's pretty cool, I downloaded the Firefox equivalent, might do the trick!
God I wish it was only twice the memory. Twice would be acceptable. Discord by itself likes to push to a full gigabyte to show me 50 lines of text with avatars and 0-5 thumbnails of images.
Even worse it's using significant amounts of video card memory, and I have a tenth as much of that.
Not if it results in only this one application feeling snappy and everything else hanging because of resource consumption. That's especially annoying when you work on a shared server. I used to work in a C++ team where many people used CLion (on a shared development server) and it made us all miserable, because the server would hang from time to time, because all the CLions ate all the RAM (sometimes just one instance could consume more than 50GB). Similar things happened with Eclipse, but a lot less often.
And then the IDE of another guy does its indexing really fast zillions of times per second, great, but then another guy sits there waiting for "git status" to complete for several minutes.
I really despise Electron apps. They always seem bloated and antagonistic toward the native user experience on my platform (eg. inferior keyboard support, hard to integrate with custom tooling like AutoHotkey, etc.). Have I just not used the right ones?
I'm not a fan of them, but they do make desktop linux a bit more viable insofar as you will have desktop binaries for a lot more services than you otherwise would without electron
You've listed a lot of technologies that people have used to create successful products with long life-cycles. In particular C, C++, Java, JavaScript, Qt, OOP... if anything is notably missing from your dumpster it's probably Adobe AIR.
Nothing in this industry lasts forever. I'd certainly rather inherit a Java/Swing or Qt app from the early '00s than an MFC or Carbon dinosaur.
I hated Swing the bit that I worked with it.. but I'm always blown away when I see the Jetbrains IDE's in the wild (I'm a VS Code guy but a few people I work with prefer the Jetbrains stuff). They managed to make a really slick, and pretty performant (if you ignore startup time) app with it.
I guess you could say VS Code is a similar exception to the rule in Electron land.
I had the opposite experience with Flutter personally, the problem is that Dart is a niche language with limited exposure (Flutter is basically the only big project in Dart realistically) and it's also a new project as well, it makes a bad combination.
Could you describe your experience more in details? What exactly didn't work out? I would like to know to understand whether it makes sense for me to invest my time in Flutter/Dart instead of a more mature solution like React Native.
Actually, I don't think we should consider React Native more mature. It's been around for longer sure, but it's significantly more fragile, keeps releasing with regressions, has poor tooling around it except for as far as React is concerned etc.
I don't know what you are trying to build on mobile but I'd definitely learn Flutter instead of RN, which I have. Others here have said you should just go full native instead, and they're probably right.
I wasn't aware of the fact that react native is fragile - it seems I did the right choice by learning Flutter. I hope it evolves even better, and also the criticism to Dart for me is so far quite irrelevant, as there are already tons of libraries and it's really easy to learn.
May I ask what kind of stuff are you developing with it? I've been working on a WebRTC app myself with it, basically porting my app from RN to Flutter. So far I've encountered no major obstacles, just a little friction which is a part of the learning curve.
What specifically isn't elegant about Dart in your opinion? Seems like a perfectly good language to me, and although it's nothing fancy, it does have a bit of sugar, and a solid standard library. I also like how codegen and static analysis are so accessible through the build libraries.
It's evolving pretty quickly, too. Non-nullable by default is coming up, along with extension methods, FFI. Possibly implicit conversions.
I've been working with Flutter/Dart for the past 8 months or so, and I have to say...I'm pretty into it.
wow! I didn't know that. I am currently learning Flutter, because I think it has a strong potential to unify mobile and desktop development, however, I didn't know that React Native was "so bad".
This has been exactly my experience. I don't particularly like Dart, but as an SDK Flutter is clearly ahead of RN. RN just keeps feeling too fragile. And the tooling is simply not there whereas Flutter has excellent tooling considering how new it is.
The nice thing about React Native compared to Flutter is that RN uses native UI widgets whereas Flutter implements its own rendering system. Flutter engineers basically reinvent a large portion of the work already done by Apple and Google in their UI kits and ultimately you have to rely on them to keep doing that work whenever changes are introduced to iOS and Android UI kits. Since RN uses native widgets they get those updates "for free". There is also the Flutter "uncanny valley" where very subtle but still perceptible differences between the Flutter engine and the native UI kit cause Flutter apps to sometimes feel slightly off. I have especially noticed this on lower end phones where the FPS in Flutter apps sometimes drops and causes the whole UI to feel sluggish in a way that native UI widgets do not.
In my experience it generally does, but on older devices, especially older androids, when the FPS does drop, the entire UI appears to be affected, whereas native widgets seem to perform better, or at least, don't seem to drag down the performance of the entire app UI if one widget is misbehaving.
I like doing projects with ionic, which have the great advantage to be ported to the web and also packaged as desktop apps. From all the apps i have developed with web tech or even i know of no users are complaining about lower performance or similar. Why developers have this opinion?
The flutter approach is interesting, however i tried really hard to become friend with dart, which seems impossible to me... I only hope somebody is building a transpiler or something.
Dropbox was able to ship two mobile applications for 5-6 years using this strategy, so it's premature to dismiss it.
Furthermore, it looks like their team changed a lot and they were unable to retain the C++ talent that implemented the original strategy, nor were they able to find interested developers.
The mobile landscape has also changed enormously during those 5 years, even the official programming languages have changed.
Unless you need something very specific for the display UI. Try cordova (open source version of PhoneGap), and stuff like ionic, framework7.io, mithril.js will mostly get your most apps done needed while still sharing the code via JavaScript, HTML5/CSS. for anything native you can always write your own cordova-plugin if it doesn't already exist.
We've had a mostly different (positive) experience doing a similar thing at FullStory for mobile instrumentation, though I think I know where some of the key differences are.
Our core "business logic" lives in Rust. This is a shared bit of code between Android & iOS that mainly deals with orchestration, serialization, and server communication. We managed to extract ~1/2 of each platform's native code into this shared orchestration. What's left on each platform is more like a platform driver.
I fully admit that things are different for us because we're not dealing with a bunch of UI that we manage (instead we're dealing with UI that our customers have written in Java/Swift/Objective-C/etc), but I think that there's a few places where we've made this work in a better way:
- We've chosen flatbuffers to serialize most (not all) of the data between the platform drivers and the shared library.
- We're using a language that's a little more hip. It's still not very easy to hire Rust developers, but developers interested in Rust are _very_ interested.
- We built tooling early on to make this pretty seamless. Our Rust code builds in XCode and gradle, so there's no real friction to a developer getting up and running.
Our team is about a year in on this transition to Rust and so far it's helped us move far quicker, especially given the size of our team.
Uh oh. So immediately you do understand that you have taken on the risk of potentially being unable to find any good(or bad) Rust engineers in the future, correct? Also they won’t be cheap as there won’t be many of them.
A smarter, business-friendly, future-proof approach would be to have done that in Java. Future you will want you to have done that in Java, but if you’re trying to retain good engineers maybe I get the Rust thing.
I think many of the best programmers would jump at the opportunity to work with Rust. That might change if the language de jour changes but working with rust is a positive for many of the best people right now.
I see you got downvoted here, but I think it is worth replying. We evaluated using Java on both iOS + Android (transpiled to iOS in some form), but what tipped the scales towards Rust was the "fearless concurrency" (that turned out to match the marketing) and the risk around the current state of transpilers.
I was a fan of Java for a very long time. It was my language of choice from early 2000s to mid 2010s. It does _amazing_ things with keeping memory management out of mind (while still giving you the the "backdoors" to make things work well if you need a non-gc approach), but thread safety continues to be a glaring hole.
From a former Java super-fan, I honestly think the future is Go + Rust.
FWIW we also evaluated Go as a shared language, but there were risks around integrating our Go shared library with apps that may include some pre-existing Go code.
I'm planning on learning and writing mobile apps in Rust. I remember reading that some things aren't supported on Android and iOS. Has that caused you any issues?
So far we haven't hit any roadblocks with the platforms being unsupported. I'm not sure exactly what others referred to, but in our case, our Rust code is effectively "headless".
Under the hood, Android is very much a Linux-looking system and iOS is very much a Darwin/OSX-looking system, so as long as you avoid moving too far into the UI layers, they'll behave exactly as you expect.
Oh yeah! Thanks for linking that. You are correct that Android/iOS are second tier, but TBH we have never seen anything to suggest that the stdlib is anything but 100% stable on those platforms.
I did run into a bug with the rand crate running out of randomness on Android, but that's a different story. :)
That’s super interesting. I really like Rust, definitely my favourite language recently. I’ve been thinking a lot about the pattern you are using with Rust for the shared layer. Have you got an engineering blog or something with more details?
There is a FullStory engineering blog, but as we've been pretty much heads down for a while on our product we've been unable to write up some of our internal discoveries. I'm hoping that we can open-source some of the mobile<->Rust glue (iOS + Android), and write up what we believe is effective sharing of business logic between platforms.
I would love GitHub to have a way to publish "example" code that is for reading, but not for using or branching.
I have code that contains useful parts that are worth publishing, but it also contains horrorshow code and library/tooling specific dependencies that are useless to anyone else.
I don't want to make the code useful for others, but I would remove comments/keys/PI, and parts of the code would remain useful to others to copy or use as a reference for how to do something.
The main issue is avoiding getting roasted by some random dev blogger for some of the technical debt (the embarrassing code you remove or fix if publishing properly). Maybe a click-through agreement before you can read the code?
As someone with plenty of C++ knowledge on mobile, I would expect there to be more C++ devs available with good mobile skills than there are rust devs?
Maybe my own viewpoint is twisting the amount of devs I think are available, but I don't think the choice dropbox originally made was crazy. C++ is a great way to share complex code over multiple platforms (i.e. desktop + mobile) if you're running a relatively small engineering team with limited resources.
Now, if you have semi unlimited resources, it makes sense to rebuild things natively for each platform in many cases. But Dropbox might not have been around, had they not maken the choice to share part of their codebase cross platforms.
As a first approximation, there are no C++ developers available. You're probably right that there are more of them than there are Rust devs, but filling a team with either one is going to be a very hard problem.
334 comments
[ 2.8 ms ] story [ 266 ms ] threadWith Electron, you don't write a cross-platform base and then write all the platform-specific goo on top of it. You just write your app using web technologies, press the build button, and ship it on all the platforms you want to support.
Since web technologies are popular, you don't end up with the same issues hiring and training developers like you do when you need to teach a new hire about your bespoke cross-platform mobile solution.
With Electron, essentially your users pay for all of this by being forced to adopt a resource-hungry platform, while the development team gets a mostly-free pass.
Especially if your business (like so many nowadays) has way more users on mobile than it does on the desktop.
Writing mobile apps is fairly trivial - writing good requirement documents is black magic I have yet to see in the real world.
Trying to share code is like trying scratch your left foot when your right foot itches. The issue with two codebases that are supposed to do the same thing is keeping them in sync over time. The only way to do that is by having actual requirement documents.
And people think it'll be easy to share code when you're targeting two completely different platforms with completely different frameworks in completely different languages?
Yeah, I probably wouldn't be super interested in mastering the arcane details of one company's bespoke stack; that knowledge would be really difficult to leverage elsewhere. Most places that need mobile engineers won't care about the bespoke C++ stuff, and most places that want people to write C++ wouldn't know what to do with someone who wrote C++ for a mobile app.
Compilation was incredibly slow. Maybe when C++ modules finally arrive things will improve.
I like the language, but the compiler is painful.
https://github.com/melling/scala
I actually like the language but stopped using it because it was so slow to compile. I hear that it has gotten better so I’ve been revisiting it.
Worksheets seem to help with development.
http://appstore.com/h4labs
The biggest winner, in my experience, was reducing dependencies in headers. Use forword declarations, etc. Precompiled headers helped a lot on Windows, but less so on Linux for the same code (but it still helped).
Incremental builds were fairly snappy, a minute or two (pretty good for a large C++ project).
I don't think that's necessarily the case. C++'s famed backwards compatibility, source of so many issues, is also a fabulous strength. There's nothing stopping one from writing C++03, while gradually adapting C++11 and beyond as time/circumstances permit (which is what I'm doing at my job, maintaining a massive legacy codebase while stymied by slow uptake on newer compilers by my corporate overlords...)
> It's no wonder 'senior' devs prefer to use plain C
Not this senior (in years, at least :)) dev. I've tasted RAII and I can't go back...
I find the '14 and '17 additions vastly improve C++ and in fact added things that I had just come to appreciate in Swift. So don't be too put off; learning the new stuff will help you if you need to adopt a more-recent language too.
There are plenty of C++ devs out there (myself among them) that will jump ship for the right offer.
It's not just familiarity with the language, it's being willing and able to develop within the mobile development context, which as stated in the article is a whole other beast
However, in the mobile world, from my experience, hiring good senior mobile engineers means they come with a specific skillsets already. They can take a view, animate it a certain way, and then respond to touches. Those are things that are entirely platform specific domains. So they will come from Swift/Kotlin or ObjC/Java backgrounds. The ultimate problem here is those same engineers are typically turned off by C++ nor have the desire to learn it.
You can throw C++ engineers at the problem, but they will most likely be turned off by having to solve animation timing issues or custom navigation stack designs.
If you have a venn diagram of the two sets, there would probably be very little overlap.
Google and Apple keep piling feature on top, so mobile has the 2nd biggest churn after front-end. Recently even the preferred programming language changed on both platforms.
It's under pressure from web-applications, which although of inferior quality are easier to develop.
Most apps aren't anything special and require mostly UI and UI framework skills (animations, platform-specific APIs, etc).
Today, unlike in 2013 when they started, there are other options.
For others considering code-sharing, another option not mentioned in their article is Rust for the core with Swift and Kotlin. Between bindgen, futures, serde_json and non-nullable pointers in Rust, those would satisfy their stated subcategories today.
Companion templates are explained here: (January 2019)
Medium.com/visly/rust-on-ios-39f799b3c1dd
Medium.com/visly/rust-on-android-19f34a2fb43
(No affiliation other than starting to proceed down this path myself.)
For Common Lisp heads, there's also MOCL, which seemed quite reasonable when I explored it years ago: wukix.com/mocl
1. People may be more willing to learn Rust. I much prefer the language itself, but also it's clearly on the rise, so it may feel like a better learning investment.
2. The standard library is broader and the package ecosystem is easier to work with, so you might be able to have a more standard stack with fewer proprietary bits.
3. One complication with integrating multiple languages is making different memory management strategies coexist. Rust's type system seems to have ways of making that easier, e.g. neon-bindings.com
Rust is built for memory and thread safety. Also the much better build system and open source ecosystem.
That's debatable ;)
Apparently sharing code isn’t necessarily a great idea.
Here's a fine alternative to code-sharing: well first and foremost you need to have a good requirements spec. After that, implement it on one platform first in a platform agnostic way. So heavy use of delegates/interfaces/injections to handle platform-specific functionality, even for one-liners like getting current system time. So the code should be pure, boring, plain old Java, Kotlin, Swift, whatever. Minimal use of fancy language features that may not port cleanly. After one platform has the module in place and well-tested, do a copy/paste port to the other platform. You will find that the copy/paste port will actually uncover bugs, optimizations, edge cases, etc., that can then be ported back to the original platform. Things you would not have found if you were only writing the code once. It's like the most intense kind of PR code review you can get.
So I've found that copy/paste-port-based code sharing between platforms is not just a lesser evil, but actually a strategy that has its own unique benefits. If you get into a groove you can build up a set of regexes to give you a sloppy transpiler that does most of the tedious porting for you.
In theory the shared code approach means platforms could be tested in parallel.
I achieved 90+% code share in Xamarin including UI across windows - ios - andriod. 100% buisness logic shared. You can write cross-platform UIs, and swap out to native code on a widget by widget basis. Threading is seemless. Sure it has its own set of issues, but everything is a trade-off. Look at your use case, and define what trade-offs you are happy with.
The drop-box use-case is also an outlier - to achieve high levels of responsiveness, it must integrate with low level platform specific APIs to the point their entire app may be some kind OS specific service. Look at blogs about their desktop apps and you see my point.
If you going to drink cool-aid from companies just because they are dominant in an area, atleast drink the cool-aid of a startup which was created for the purpose of building cross-platform apps.
The reasons for regretting it were similar: lack of available engineers on the market, incompatibilities between runtimes, and lagging support for platform features (although in the Xamarin case it's not even in your hands to fix it)
I'd be happy to hear if the project you worked on has been cost-effective to maintain in the long term. Then at least someone has seen the mountain top!
You can directly access native apis within your js/ts code. And they provide good cross platform defaults for widgets.
so basically you can either have one application on top of a custom ui framework (xamarin.forms) or you can only share business logic, and write controllers, which feels native in c# or the native language.
i.e. without forms you can build a controller with objc or you can have the implementation in c#, and call into a shared business logic library. unfortunatly the docs are really really weak when you consider what you really can do with xamarin.
with forms you can build a ui that works on both platforms so basically you have 100% shared code.
And the same problem with using C++, you have to build the app around it, rather than using the best arch for android and ios.
- The entire organization uses a single framework (and improves on it), which will lead to a bunch of teams grumbling that "We are only using X because of organizational pressure, while Y is much better"
- You leave freedom to the org to pick their technology, and hope/steer people towards certain parts. But you will have to accept some divergence from the norm
I prefer the second org, and luckily I am in such a place where we can use Go while the team next to us is on Scala, and we weigh in-house developed technology against publicly available technology on ROI.
https://news.ycombinator.com/item?id=20413046
Other article talking about it:
https://blog.appfigures.com/microsoft-goes-all-in-on-react-n...
Xamarin for .NET devs, React Native for C++ devs (a bit like QML/Qt).
Office naturally fits the C++ devs way.
But the Office team is also a right tool for each job group and has both Xamarin and React Native apps and telling the difference between them is getting tougher to do. You can already integrate React Native components inside a Xamarin app and vice versa because they each can look like native components to each other, and it's not entirely an either/or decision.
But when trying to find an example of a native-feeling Xamarin-based app for iOS, I was really underwhelmed. I tried to find one that was (a) well-known and (b) third-party (not developed by Xamarin or Microsoft). The 4 contenders were:
- UPS - 1/4 stars - All views of the app are awkward embedded web views. Every page has a full screen modal spinner.
- Outback Steakhouse - 1/4 stars - Not updated for modern iPhones, so the whole app is letterboxed. UI is completely custom, so didn't attempt to feel native. Crashed as soon as it tried to get my location.
- Alaska Airlines - 3/4 stars - Feels native-ish, nice "vanilla" design. Mix of native forms and web views. All UI related to searching flights & buying tickets is a web view. Every tap on the tab bar causes a full screen modal spinner.
- FOX Sports - 4/4 stars - Wow, impressive. Lots of native-feeling views with their own branded styling. The custom widgets feel native.
It was great to find one "hero" app for Xamarin (FOX Sports), but the fact that it's an outlier is a little concerning.
https://willowtreeapps.com/company
They specifically mentioned when I was interviewing there that the reason their Xamarin apps are so good is because they already know how to make good native iOS apps.
Also, I specifically asked about whether or not they would be using more technologies like Xamarin in the future and they didn't seem too keen on it.
According to them, making a truly native seeming app in Xamarin isn't much less work than making two separate native apps.
Given advances in mobile platform and Native SDK a company like Google, Microsoft or Facebook will not be able to keep up with native SDK and will be one or two generations behind. You can see the result in issues on flutter project. Also given Swift has Python like syntax and ease of use with powerful toolchain and Kotlin with nice syntax with functional programming efforts are not that different working with native SDK.
Obviously this cross platform mobile framework are ok for simple crud apps. But when it comes to building a mobile app using modern vision, audio, keyboard, touch and gesture input along with modern sensors in the platform and provide a consistent UX is a big challenge. Also UI and UX have enough subtle differences across iOS and Android the code written to manage them is also substantial. So its nice to go native SDK route for mobile apps.
The reality is that to do Xamarin well you’ll have to wander outside out Xamarin Forms, and to do that well not only do you need native mobile developers but you need far higher caliber native mobile devs who are able to mentally translate swift/objc and android calls into their C# equivalent, and who have an idea of what’s going on the os when there’s a crash at a level lower than the .NET runtime caused by a native part that’s not apparent in the crappy Xamarin stack trace.
Xamarin really only makes sense if your company has a mountain of existing complicated .NET code with priceless business logic that you absolutely have to reuse.
The Xamarin folks are native platform engineers first. Xamarin teams comprise Android experts and iOS experts who did then went on to learn Xamarin on top.
But this is different, if you write things simply, so the code can be ported easily. Then you're essentially making the code easier to share, without tightly coupling it to a specific platform... seems like a big win to me
[1] http://wiki.c2.com/?RewriteCodeFromScratch
This also has the benefits of:
- Being easier to on-board new developers, as the architecture is generally language agnostic.
- Easier to add new OS clients, as the system is easily portable
Downsides:
- Harder to incorporate language specific dependencies, as they are much harder to find in multiple languages.
- Code duplication...
Always important to weigh up the trade-off's
I think that kills a lot of interesting projects right there. If I could write a solid spec, that would mean I believe I wouldn't learn much from shipping the product. And also that my competitors aren't learning or advancing.
A good requirements spec doesn’t mean it has to be heavyweight with all the corners and edges figured out. Instead, it can be just lightweight enough to get things moving in the proper direction... but some little direction is certainly needed.
It's fine.
As long as you don’t blurt a lazy “use the source Luke” and take the effort to document and edit the spec during or right after implementing something, it’s ok.
What's the point of writing the spec after? At best, it's duplicative. At worst, it diverges, making it incorrect.
One just has to have an idea where to go before starting, and a good description where one went when you’re done.
I implemented targets for JS, php and C++. It worked okayish but in the end it was more work to maintain the separate language than just write everything 3 times with some help of a simple macro/template language. I still sometimes wonder if the concept would be developed further, with a proper team and good tooling etc, if it would be a practical way of doing large scale cross platform software development.
If I understand you correctly, this feature is available in Haxe : https://haxe.org/manual/target-syntax.html
It targets js, php, C++, has a proper team and good tooling.. so you might be interested in giving it a try.
A shame, since many of them don't really need more than one responsive web codebase. Native apps do add value for many use cases, but not all.
and I think you meant masochist
The things that are in the native wrappers are things that would be iOS-specific or Android-specific regardless of zero shared code or maximum shared code. In my case, the bulk of the app is shared -- everything that can be a common code base is a common code base.
According to GitHub's rough metrics, that's: Go 44.7% Dart 32.8% Java 7.1% JavaScript 6.9% Swift 6.6%
Every time I've started a new iOS project in the past ~2 years, I've reached out to a handful of developers and managers on how cross-platform is going for them. None have been completely sold on it. The ones that are, are the ones that have been doing it for a few months. I've come back around to talk to them months later and they aren't so confident in the decision anymore.
To add to the difficulty, they used Chromium as a UI front end much like Electron. All built in house though.
They hired me as a JS/HTML/CSS dev, but same as the article states, the C++ work was the true bottleneck.
They knew I had some C++ chops and set me to work doing C++ with a sprinkle of JS here and there.
Due to incompatibilities in the compilers, there was a rats nest of dependencies, thousands of #ifdef’s to cover differing OS implementations, and we had to use some of the oldest versions of C++ to be compatible with both XCode and Visual Studio.
As the article states, we had custom background job libraries and debugging them was a nightmare.
Also similar to the article, we spent more time than one ever should setting up builds to handle our ludicrously complicated build configurations.
And lastly, as the article stated, we had a hard time finding new talent to cover the growing amount of work required to deliver our product. There just aren’t many C++/JS devs out there.
Reading the article and now this, I really can't grok this perception. There are plenty of us out here, I think, it's just we're buried in the heap caused by mass resume farming, aka modern recruiting. Recruiters and hiring managers don't think of me as a senior dev with 15 years writing software and delivering value to end-users... I'm just YA candidate who doesn't have any experience in the latest JS framework du jour, so I might as well not exist.
As for finding people like yourself, all I kept hearing was that they had trouble finding new people to fit their specific needs.
I agree with you though, there is likely a lot of missed opportunities due to the resume farming going on and bad filters.
My current work has me on a single C++ code-base for Linux, Windows and MacOS (not electron though, just native). You can avoid a lot of headaches by avoiding the platform specific tools and instead cross compile using clang with a build system that works on all platforms (eg. ninja + meson).
Note re. targeting a platform — often learning and reading some C++ is inescapable. For me, reading Chrome source code makes it easier to work with Puppeteer in JS, or deliver a better web app because I know how things work under the hood and it’s easier to read the C++ than the read the web standards themselves. Similarly, C++ really is portable and fast, so it shows up in many places. But on mobile, the mix of C++ to Swift/Kotlin should be 90%-platform native if your app is a traditional CRUD app that deeply integrates with the platform. If it’s simpler than that, build a website, or if it’s a game engine or some custom UI, use that, sure, but if you want to benefit the most from Apple and Google implementations, native (with shared spec/data models) is the way to go...
Unfortunately, once you get into users wanting OS specific feature support, all that goes out the window.
You now are forced to maintain multiple versions of your product that differ greatly per operating system.
Pair that with the fact the codebase was almost 20 years old, you get some fun legacy code support issues that a lot of C++ projects naturally have due to the fact that C++ is not a new language.
However, in our case (like with many C++ code bases) the code was almost 20 years old. Even with the Herculean efforts made by the teams to keep the code base up to date and refactored, you run into issues of backwards compatibility with older libraries.
C++17 is definitely the go to for new projects! However, I've never personally worked on a pure green field project written in C++ that didn't have to latch onto some older libraries that require older C++ std versions.
Moreover with REST API architecture majority of the common code is in back-end. So building in Swift and kotlin for respective platform is not as tedious.
If I use swift I get all the code examples and tons of documentation from Apple itself. In flutter I need to rely on some package which might not be supported, if my team takes over it's double the job fix the package bugs and also change the resulting changed in code, compile and test individually on iOS and Android.
Another one https://pub.dev/packages/sensors#-changelog-tab- And there are many such issues.
I haven't tried Ionic myself, but I have tried both React Native and Flutter for a small project and found Flutter to be more enjoyable and productive.
So if you compare ionic vs flutter I will still go with flutter given it generate binary app store package file by compiling dart code into native platform code. But given choice between native vs flutter I think except few use cases native still makes more sense.
Ionic lets me build a web app and publish it to any device pretty easily. I don't have to use their components either... in fact after using Ionic, you may not use Ionic anymore at all. All you need is Capacitor to publish it.
Flutter is it's own rendering engine, non-standard web language (Dart), and ecosystem. Ionic is just a CLI and collection of web components. Capacitor is Ionic's version of Cordova. It gives you access to device capabilities such as storage, camera, etc with very little code. So you can build a website, ask if it's Native on a device, and do more cool things if it is. Then push it to Android, iOS, and the Web.
Ionic supports Angular, React (now in RC0), and Vue (Beta). This allows you to learn popular frameworks while still developing with one code base.
Lastly, Ionic's Web Components are built using standard-compliant Web Components generated by a tool they made called StencilJS. So, now you can build a component in Stencil and publish it for simply the Web (No framework) or have them work with Angular, Vue or React. Larger corporations have started using StencilJS to manage their components when they use many frameworks. I use it because I don't know which framework I'll use next, or if I'll even use one.
I joined when Capacitor was in beta and figured I'd use the up and coming. From research, it appeared there was a good reason Ionic created their own product. They didn't do it to simply stop using a tried and true product.
Also to be clear, Cordova is not an Ionic product. It was a great community thing for a while to talk to native devices.
So I'm also interested in hearing more elaboration on how Flutter has been a struggle for you.
I can't see how duplicating code in Swift/Kotlin would be any better than just writing it once in Dart. Dart is also quite a nice language to work in. Easy to get up to speed and a nice mix of static/dynamic typing. The optional Provider api make state management a breeze, no more Stateful widgets.
I've also switched from REST to GraphQL. I was a long time hold out there, but now I really see the advantages.
Anyway, just throwing this out there as another data point.
I like dart lang and done some small apps in it. It's Javaesque with similar style and learning curve. But still prefer Swift which is closer to python (we use python for back-end development) and Kotlin which has some nice functional programming primitives.
Also UX and guidelines are not uniform across mobile platforms. Android and iOS works in their own way to integrate different input like voice, visual and keyboard. Also mobile platforms on Android and iPhone are constantly evolving with new sensors, capabilities. Keeping native SDK itself is a gigantic task not sure how to manage cross platform SDK's. I am sure cross platform SDK can work for some use cases, but I feel it will still be way behind native SDK.
If back-end can take care of all the business logic and front-end manages UI and states with small necessary local data for offline, the efforts spend to develop cross platform app using flutter or natively in Swift and Kotlin won't be very different.
I still prefer REST over GraphQL because I like predictable performance in query and standard interface. Zen of Python PEP-20, explicit is better than implicit.
GraphQL is a solution to a problem of trying to manage business logic on client side so that it can manage ad-hoc query and get ad-hoc results from back-end. It was designed for a problem faced by Facebook. I have seen enough GraphQL code and still stay with REST Architecture, sometimes use protocol buffers for performance intensive parts.
in 2013, AIR was v3.6, now in 2019, AIR is v33.0
not only you share code via ActionScript 3 (something like TypeScript just available 10+ years ago)
but you can also develop ActionScript Native Extension (ANE) in C, C++, Objective-C, Java, C#, Swift, etc.
and it does not only publish to mobile it also publish to desktop
but that's OK, keep ignoring it
I guess it lives on here? https://github.com/apache/royale-asjs Still looks active..
Here's a demo https://royale.apache.org/tourdejewel
Adobe AIR is a compiler and a runtime
for iOS it compile AOT, for other platforms: Android, Windows, macOS, (and Linux) it compile JIT
the runtimes share the AVM2 (ActionScript Virtual Machine) and the Flash Platform API, which allow to share a lot between platforms
I agree that ActionScript was a pretty decent language to work in.
I investigated Haxe briefly but found the community wasn't very big and the community that did exist was really fragmented.
imagine if you could write command-line tools and server-side apps with it, that would be the dream
I have a feeling posts like these get upvoted because developers who make the native apps want to keep their jobs. But those developers will always be needed for the native bridges, just not as many of them.
That said, myself I still write Flutter too, having jumped ship from React Native.
But yes, there can be differences, but that doesn't mean give up and write the application code 6x.
- Non standard UI/UX is super common because cross platform UI targets the lowest common denominator. Flutter is the quintessential example of this, it throws away all native UI support and renders everything from scratch with low level graphics. In React Native I've observed several cases where iOS UI has been re-implemented, poorly, in Javascript and shipped on Android and iOS.
- Poor accessibility. Native iOS apps get a lot of accessibility for free because Apple has done a great job, with RN and especially Flutter you don't get this benefit.
- Resource consumption. Electron is terrible in this regard as is the common meme. React Native runs a JS VM for every app which surely has a negative impact on both battery and performance.
- Binary size. A basic Flutter/RN app easily pushes you past 20MB in app size on iOS, whereas a complex and complete app like Tweetbot is ~7MB.
It's certainly possible to build great UX with cross platform UI frameworks, but the amount of work required to do it well starts to get into the territory where you are better of just doing it natively in the first place.
- React Native you most certainly do get accessibility.
- Running a JS VM isn't that bad, but it is a tradeoff. Imo it's completely worth it to prevent having to learn X different languages for each platform.
- The app size evens out, but yes the minimal is higher. However many apps are much larger than 20MB, it's better than other cross platform solutions
In no way are any of these things so bad where I would duplicate my code 6 times and then maintain them throughout the life of the project. That's just crazy.
Yes a great strength of React Native is that it still leverages the native UI kits and makes it possible to do so when building custom components. My comment wasn't about my experience, in fact I've built numerous bridged components in RN, but and observation about the react native community. In fact one of the most crucial lessons I've gathered when working with RN is that you must have both iOS and Android experts in your team to build good apps with RN successfully.
Here's just a few examples of popular 3rd party components(from awesome-react-native[0]) that are problematic in my eyes:
- react-native-swiper[1]. Completely custom JS implementation with a "iOS"y look. 8k stars
- react-native-gifted-chat[2]. Large completely custom JS implementation of chat UI. 8k stars
- react-native-slider[3]: A pure JS implementation of a slider. 1k stars
> - React Native you most certainly do get accessibility.
My point wasn't that it can't be done, but that it requires significantly more work that, let's face it, most developers will not do. With native UI you get a lot more for free which results in a better user experience for everyone.
See https://news.ycombinator.com/item?id=20709259
> - Running a JS VM isn't that bad, but it is a tradeoff. Imo it's completely worth it to prevent having to learn X different languages for each platform.
I agree it's a tradeoff and to be fair I don't have more than a hunch that running a JS VM is bad for energy and resource usage. The tradeoff is distinctively on the user's expense in favour of the developers. As developers shouldn't we be making tradeoffs that benefit our users instead?
> - The app size evens out, but yes the minimal is higher. However many apps are much larger than 20MB, it's better than other cross platform solutions
Yes many native apps do grow quite large too, my point is the default. The most basic RN, but especially Flutter, app is much larger than the native counterpart. Again a distinct tradeoff on the user's experience in favour of the developer.
0: https://github.com/jondot/awesome-react-native#components
1: https://github.com/leecade/react-native-swiper
2: https://github.com/FaridSafi/react-native-gifted-chat
3: https://github.com/jeanregisser/react-native-slider
> - Binary size. A basic Flutter/RN app easily pushes you past 20MB in app size on iOS, whereas a complex and complete app like Tweetbot is ~7MB.
I have working examples of fairly complex production applications that are <=10 MB on iOS.
> - Poor accessibility. Native iOS apps get a lot of accessibility for free because Apple has done a great job, with RN and especially Flutter you don't get this benefit.
False statement. React Native provides you with ability to tag elements so you can use accessibility-tools to navigate the app. I have recently tested this with a RN app running on iOS 13 using the new voice control feature. Several testing frameworks also rely on these features being available.
Fair, the problem isn't as bad for RN, for Flutter it's still very bad though.
> False statement. React Native provides you with ability to tag elements so you can use accessibility-tools to navigate the app. I have recently tested this with a RN app running on iOS 13 using the new voice control feature. Several testing frameworks also rely on these features being available.
The ability to tag elements is only a very simple basic requirment to get accessibility right. My point was more that if you use UIKit you get significant levels of accessibility for free.
Just as a quick example I did a quick ddg search for "react native how to create custom button" and all 5-7 top results that I looked at failed to set the appropriate accessibility roles so the button actually appears as button to a user with the screen reader. Yes you can still do accessibility right with RN, but it's not the easy to get it right be default and most app developers will not do this on their own.
Appreciate that you looked into it. On iOS and you do not need to set anything to become screen reader friendly _in React Native_. The default TouchableOpacity with a simple piece of text inside of it will become focusable and iOS will read the text aloud for you. This works because RN uses native elements unlike Flutter, Electron, and others.
In fact, I took you up on the claim that it wouldn't read correctly. I used my app just now which has never been tested or optimized for accessibility. Covered my eyes and began navigating. It works just fine! All tappable elements are indeed read aloud. I was able to navigate through the app settings, change them, go back, and reload other screens, navigate to the updated content, and perform actions on the new content.
Please do not put RN in the same bucket as Flutter or Electron. They are fundamentally differently.
[1] - https://www.youtube.com/watch?v=ZcBtF-JWJhM
Have you heard of Electron, Cordova and tons of other crapware that help produce so much garbage “apps” every year, it would put to shame even the most toxic enterprises in an unregulated Republican dream?
I'm more excited about leveraging native platform UI with shared code in a common language like Rust. C++ as described in the blog is problematic for this.
I'm more intrigued by AirBNB moving away from React Native - the linked article says "RN was too small a component to bother supporting, and the developer experience wasn't up to par", but I'd like more detail than that.
I've been working with Flutter for the past 6 months, and it would definitely be my "go-to" for any mobile application.
To be fair, I did spend 2 weeks going down a rabbit-hole to get Flutter talking to a .NET assembly by embedding Mono and invoking via JNI/Obj C, so I know the pain of native interop. If you're mostly doing work at the native platform level, then I can imagine why you'd stay away from a cross-platform VM.
In my case, I ended up with a brittle project that was clearly going to be a PITA to maintain & automate builds for, so I just rewrote the component in question in Dart.
> While debugging, React Native attaches to a Chrome Developer Tools instance. This is great because it is a powerful debugger. However, once the debugger is attached, all JavaScript runs within Chrome’s V8 engine. This is fine 99.9% of the time. However, in one instance, we got bit when toLocaleString worked on iOS but only worked on Android while debugging. It turns out that the Android JSC doesn’t include it and it was silently failing unless you were debugging in which case it was using V8 which does. Without knowing technical details like this, it can lead to days of painful debugging for product engineers.
https://medium.com/airbnb-engineering/react-native-at-airbnb...
RN would definitely still be my go to tool for the majority of green-field mobile apps. If I'd already invested in learning flutter/Dart I'd probably feel the same about that, but certainly feel no urgent need to go out and learn it. As in, I don't think there's a significant difference in what I'd be able to accomplish, and my time is probably better invested elsewhere.
Wait, React Native uses JavaScriptCore on Android?
It's a different story if you want to use native features. Plugins provided by community offer only basic functionality, and are often very buggy: you will encounter iOS bugs, Android bugs, Flutter bugs and plugin bugs, all in one package. Anyway, it sort of works if you plugins provide stuff that you need. If they don't, you are forced to fork the plugin and add ad those features, learning Android or iOS during the process, and writing a lot of boilerplate for communication.
> That being said, C/C++ are the only languages with a compiler supported by both Google and Apple, so using a different language would have created a whole host of other problems to deal with.
Also the UI frameworks are being written in said preferred language these days, eg SwiftUI, and adding one additional language could be perceived as a pain.
https://developer.apple.com/metal/Metal-Shading-Language-Spe...
"The Metal programming language is a C++14-based Specification with extensions and restrictions. Refer to the C++14 Specification (also known as the ISO/IEC JTC1/SC22/WG21 N4431 Language Specification) for a detailed description of the language grammar. This section and its subsections describe the modifications and restrictions to the C++14 language supported in Metal."
Also, the MSL and Objective-C compilers are built on top of LLVM, written in C++.
2 - Metal requires MSL
3 - IO Kit is a C++ framework for macOS, iOS, iPadOS and watchOS drivers
4 - Metal GPGPU drivers are written in IO Kit
5 - Metal is useless without MSL and GPGPU drivers
6 - Ergo, Metal requires C++
And the language for writing drivers in is even more irrelevant because we're not talking about writing drivers. You can't write drivers in Swift either.
The platform developers will do their best to keep 1st tier tooling working and fix it when it breaks.
What's that about the definition of insanity? Doing the same thing over and over and expecting a different result?
Sever side rendered HTML is the closest we've come, but that's not cool anymore.
Isn't that an oxymoron?
If the user interface is usable and snappy, it is probably fine that it consumes twice as many resources as a similar native app would require for the same result.
Example: Slack.app is a huge memory hog (though not as bad as it was before their rewrite), but it fits decently into OS X and does not lag on me.
I have lots of RAM, so the extra consumption is fine.
Sure, it annoys some programmers that it could be more efficient, but other than them, who cares? Those guys are probably using Emacs or a CLI program as their client anyway.
(I must be a rare breed, since I do email, writing, and programming in Emacs, but not chat)
I switched from Sublime to VS Code and went from 20MB of RAM usage to 500. Add slack, add discord, you now have GBs of RAM getting eaten up just for the UIs. Most mid-range laptops still only have 8GB of RAM, add a browser to the mix and it's a constant battle to have everything running smoothly, the programs frequently crash due to memory issues. It's a real problem and not solely programmer efficiency-OCD.
My laptop has 8 gigs of RAM, and I run many programs simultaneously (usually including several codebase analysis servers behind Emacs, a VirtualBox VM or two, Slack, and of course tens of Chrome tabs, several in development mode), but I don't have anything like the problems you describe. I do use The Great Suspender aggressively in Chrome and that does help a lot.
My Emacs instance itself is extremely tricked out with extensions and usually weighs in between 100 and 200 MB of RAM. Maybe that's the difference - sounds like VS Code eats a lot more.
I'm on a MacBook Pro from 2015 at work, if memory serves.
What setup are you running that handles your needs so poorly?
No wonder I don't have issues.
I hope tab suspension helps you. It certainly made Chrome more usable for me (but I do have a bad habit of getting to fifty or seventy tabs open).
Even worse it's using significant amounts of video card memory, and I have a tenth as much of that.
And then the IDE of another guy does its indexing really fast zillions of times per second, great, but then another guy sits there waiting for "git status" to complete for several minutes.
Nothing in this industry lasts forever. I'd certainly rather inherit a Java/Swing or Qt app from the early '00s than an MFC or Carbon dinosaur.
Oof. Yeah MFC was something else.
I hated Swing the bit that I worked with it.. but I'm always blown away when I see the Jetbrains IDE's in the wild (I'm a VS Code guy but a few people I work with prefer the Jetbrains stuff). They managed to make a really slick, and pretty performant (if you ignore startup time) app with it.
I guess you could say VS Code is a similar exception to the rule in Electron land.
Java is a good language, as long as you rarely use implementation inheritance.
I would not recommend using React Native or C++ for any project.
In my experience, while Flutter may not be elegant because of Dart, it more or less just works.
Developing in React Native is mostly just debugging the framework itself and browsing through React Native Github issues.
I don't know what you are trying to build on mobile but I'd definitely learn Flutter instead of RN, which I have. Others here have said you should just go full native instead, and they're probably right.
It's evolving pretty quickly, too. Non-nullable by default is coming up, along with extension methods, FFI. Possibly implicit conversions.
I've been working with Flutter/Dart for the past 8 months or so, and I have to say...I'm pretty into it.
Non-nullable by default will be a huge win. It does feel like a huge step backwards having to deal with nulls again.
https://www.youtube.com/watch?v=J5DQRPRBiFI&feature=youtu.be...
C++, plenty of jobs outside mobile dev, and a very nice pay to come along.
Flutter - Dart, death silence outside Flutter use cases.
Furthermore, it looks like their team changed a lot and they were unable to retain the C++ talent that implemented the original strategy, nor were they able to find interested developers.
The mobile landscape has also changed enormously during those 5 years, even the official programming languages have changed.
Our core "business logic" lives in Rust. This is a shared bit of code between Android & iOS that mainly deals with orchestration, serialization, and server communication. We managed to extract ~1/2 of each platform's native code into this shared orchestration. What's left on each platform is more like a platform driver.
I fully admit that things are different for us because we're not dealing with a bunch of UI that we manage (instead we're dealing with UI that our customers have written in Java/Swift/Objective-C/etc), but I think that there's a few places where we've made this work in a better way:
- We've chosen flatbuffers to serialize most (not all) of the data between the platform drivers and the shared library.
- We're using a language that's a little more hip. It's still not very easy to hire Rust developers, but developers interested in Rust are _very_ interested.
- We built tooling early on to make this pretty seamless. Our Rust code builds in XCode and gradle, so there's no real friction to a developer getting up and running.
Our team is about a year in on this transition to Rust and so far it's helped us move far quicker, especially given the size of our team.
Uh oh. So immediately you do understand that you have taken on the risk of potentially being unable to find any good(or bad) Rust engineers in the future, correct? Also they won’t be cheap as there won’t be many of them.
A smarter, business-friendly, future-proof approach would be to have done that in Java. Future you will want you to have done that in Java, but if you’re trying to retain good engineers maybe I get the Rust thing.
I was a fan of Java for a very long time. It was my language of choice from early 2000s to mid 2010s. It does _amazing_ things with keeping memory management out of mind (while still giving you the the "backdoors" to make things work well if you need a non-gc approach), but thread safety continues to be a glaring hole.
From a former Java super-fan, I honestly think the future is Go + Rust.
FWIW we also evaluated Go as a shared language, but there were risks around integrating our Go shared library with apps that may include some pre-existing Go code.
Under the hood, Android is very much a Linux-looking system and iOS is very much a Darwin/OSX-looking system, so as long as you avoid moving too far into the UI layers, they'll behave exactly as you expect.
BTW I'm pretty sure I simply just misunderstood their platform support page. https://forge.rust-lang.org/platform-support.html
I did run into a bug with the rand crate running out of randomness on Android, but that's a different story. :)
Do you also keep ViewModels or things like an AuthManager (incl Keychain) or view coordinators in Rust?
I have code that contains useful parts that are worth publishing, but it also contains horrorshow code and library/tooling specific dependencies that are useless to anyone else.
I don't want to make the code useful for others, but I would remove comments/keys/PI, and parts of the code would remain useful to others to copy or use as a reference for how to do something.
The main issue is avoiding getting roasted by some random dev blogger for some of the technical debt (the embarrassing code you remove or fix if publishing properly). Maybe a click-through agreement before you can read the code?
Maybe my own viewpoint is twisting the amount of devs I think are available, but I don't think the choice dropbox originally made was crazy. C++ is a great way to share complex code over multiple platforms (i.e. desktop + mobile) if you're running a relatively small engineering team with limited resources.
Now, if you have semi unlimited resources, it makes sense to rebuild things natively for each platform in many cases. But Dropbox might not have been around, had they not maken the choice to share part of their codebase cross platforms.