You mention Ionic at the end, so I have to comment as the co-founder :)
The first thought is on maintenance and support from Google/Facebook compared to someone like Ionic. One of the things people don't think about before it's too late is support, and Ionic is unique in mobile in that we actually make money from supporting our technology directly for customers. We have direct support available for our auth/security/data storage plugins, cloud services, and open source projects. We literally will respond to customer support tickets and make fixes/patches on a weekend if we have to.
Is there any other company out there doing what Ionic is in mobile? You mention having issues with the Web View component, is Google or Facebook ever going to prioritize your issues? It's not likely, they don't have that kind of business model around their technology like Ionic does. Facebook builds RN for itself, and who knows what Google's end-goal is with Flutter (drive GCP adoption? push its ad network?) but it's certainly not to monetize it through dedicated support for the most significant users of it. I'm proud that the Ionic stack is the most user-aligned offering out there because we're literally in the business of supporting and extending users of our OSS stack.
On the Web View side, we've recently shipped one of the first mobile micro-frontend projects in the ecosystem called Ionic Portals which is basically an awesome Web View component powered by our tech and expertise building web view experiences on mobile. Right now it doesn't have RN or Flutter bindings but we are working on them this year. This has been a pretty interesting shift for us and we're now working with traditional native teams not using the traditional Ionic stack:
It would be great if Ionic offered consulting for things like Cordova -> Capacitor migrations. However, the last time I talked to sales it seemed like the best we could get was a report on what plugins we could or couldn't use with Capacitor.
> we're literally in the business of supporting and extending users of our OSS stack
Can you define that a little bit better? Because I've contacted Ionic sales before about seemingly well-used but under-maintained plugins and was basically told we were on our own.
AppFlow isn't a horrible product—but the recent price increases gave me a sour taste. What am I getting for my money? OK. I'm getting a build system which is nice, but I can't stomach paying the new (nearly 10x) price just to be able to do things like kick off builds from CI or the CLI.
What I _would_ pay for is help with other OSS plugin issues, consulting to migrate to Capacitor, training and help with maintaining custom projects, or better yet general development support when things go south (like the dreaded white-screen of death).
Anyway, we've been happy with Ionic and are always excited to see things improve. I don't mean to be downer—rather I'd love to give you guys money so long as it makes sense!
Ooh Portals is interesting. My team went with implementing our own bindings on WebView (Android) to enable functionality from SPA/PWA, but there are definitely some growing pains/unexpected hiccups compared to desktop browsers.
I wish the Expo team offered support plans. Its an amazing product and they now sell hosting, but support is something I would (have my company) pay upwards of thousands of dollars a year for.
When you get stuck on a strange bug or find something in the docs doesn't work as expected your only options are Discord and GH issues. Neither feels appropriate as GH issues are slow and you get lost in the noise and Discord is a sea of noise that you're never sure if anyone with serious answers may be able to help you.
We've built amazing things with Expo (now that you can run almost any native code you want in an Expo app) but support would be an easy purchase.
I dare to say 99% of the time I can spot a non-native app within seconds of using it. RN & co. are fantastic for quick MVP. For serious product it might be actually faster to build native for both platforms. You will start hitting the limitations of RN very soon, even in core functionalities like navigation.
Even if you can spot a non-native app in seconds, does it really matter? The vast majority of users simply won't notice and not care at all if it's native or built with Flutter, Xamarin, RN, etc.
The same has been said for Electron on desktop for years, but look at how VS Code is probably the top editor in use on desktop platforms, and even more demanding audience, like developers, don't really care that it's non-native.
Well that’s the point. While it’s perfectly possible to build a poor app in any language, it’s almost impossible to build excellent app in cross-platform framework. The reason why you recognize them almost immediately is that there are some people obvious annoying details - scroll lag, non-standard UI elements, non-standard navigation patterns, you can just immediately feel something is wrong, even if you are a normie. It can be partially compensated by the app having some other great benefits.
I disagree about scroll lag. There are plenty of WebView apps (and websites obviously) that have zero scrolling issues.
Non-standard UI elements is something I don't personally care about. Some people do, but I think this is an issue that is often overstated (or perhaps rather overestimated as a factor) by platform enthusiasts.
What does matter a great deal to me though is launch speed and battery usage. Mobile apps are often used for short periods of time. They must launch instantly. And battery is the scarcest resource in mobile computing.
Nobody will voluntarily use an app that is slow to launch and shows up at the top of the battery usage table in spite of only having been in use for a few minutes.
As a developer, these are the issues I would like to learn more about in respect of any new cross-platform technologies.
> While it’s perfectly possible to build a poor app in any language, it’s almost impossible to build excellent app in cross-platform framework.
100% this. Cross platform frameworks will always fall into a weird uncanny valley where there are just things that are subtly off about apps made with them. Most of the user base may not be able to pinpoint exactly what's wrong with such apps, but I believe they still notice on some level.
I usually don't notice or care, unless they haven't put any effort into it. Now that I'm thinking about it, there are a few that I suspect aren't native, and I don't get bad feelings from the apps unless they are badly programmed and the functionality doesn't work.
What I mean is they don't actively consciously care. They have better things to do. But they're not immune to perception. They do have some impression and experience that they're also likely to be able to express in the form of feelings.
Even the best Flutter apps feel awful compared to a decent native iOS app. Which honestly sucks, because I much prefer writing Flutter apps to anything else.
Unfortunately the horrible experience is much more normalized with the amount of bloatware and horrible ux software out there to the point that users will use it either way in many cases.
And truth is, as long as you have exclusive content on a service, the quality of your app (and thus the satisfaction of your end users) doesn't matter all that much.
I'm not sure why you're getting downvoted. I often don't notice, and I've never heard anyone comment about those things. Most end users don't even know what those platforms are. Some apps look different than others just like some websites look different than others.
I hate when people bring up VS Code in defense of electron. It is basically the one application built in electron that isn't obviously significantly worse because of it. And it's because it is backed by a trillion dollar company that can afford to invest the time to fix the electron limitations for their project. No other app built in electron is even remotely close to VS Code, which is still noticeably bad in performance when compared to native editors.
I use Electron based apps, because they are part of the job, refusing them means looking for another job, which in the current world status is kind of not really what I want to do.
The path to sucess is a very tortuous one full of victims.
> The vast majority of users simply won't notice and not care at all if
Users will of course notice and care. It's just they are not versed in shitty tech to properly articulate what they notice.
So every time a user says "the app is broken/slow/hard to use/loses data/can't update data etc." quite often it's because it's some shitty wrapper on top of a shitty "web app".
It’s not that people like to play the game “spot the non-native app” for fun, but rather that the fact that non-native apps are so easy to spot means they have some obvious deficiencies that become apparent within seconds of use. No one ever said “I can tell this app is non-native because it’s too fast and fluid”.
I care that VS Code is non-native. Don't you dare move an open file around the file system outside of VS Code, less it thinks it's been deleted. And it still doesn't have the standard macOS file operations available in the window titlebar.
After 10+ years of Android development I honestly feel like I am cheating when writing UI code using Compose these days.
Also do Dart/Flutter development along side it and.... they (D/F) just feel so damn verbose and messy by comparison.
edit:
I can also mirror what the author of the article mentions. Any update in OS versions or the Flutter framework can seriously cripple some of the packages that you'll need to use in order to make a functioning application. Massive time will be spent hunting down the weirdest issues.
But to be fair, that can also happen on the native side. They are usually just much easier to find and fix.
Yet a shocking number of apps from major companies are all built in this manner. I think the reason it's so damn popular is RN & co. get "close enough" to where many companies can get away with having an cross platform app, especially for React Native apps once you dial everything in and get used to the quirks compared to Native.
True. It’s inexcusable for large global corporations, to be fair. Typical culprits include banks and airlines - those are some of the most awful apps around.
> For serious product it might be actually faster to build native for both platforms.
So Clubhouse 'succeeded' on native this then before every single competitor copied them to the point where everyone has abandoned it? At what cost?
It didn't stop Discord from copying them (which that is in React Native). It also seems that Discord is the prime example that proved how slow Clubhouse was to catch up in the first place without an Android app available at the time for their entire product.
As soon as the Clubhouse Android app released, it was already too late.
It is one of the many reasons why the hype died. [0] Ultimately they could not move quick enough against the competition.
The expectation with apps these days is to release on both platforms from day 1 and Clubhouse was still too busy writing their Android app a year after releasing their iOS app, meaning they were too slow to compete against everyone else.
As soon as that was finished with the invite system removed, everyone already left for Twitter Spaces or Discord Stages.
Honestly, I think the novelty just wore off. I doubt that Clubhouse users moved to other platforms, I think they just mostly stopped using the chatrooms.
After some exploration phase, it seems the main use case settled to just semi-interactive podcasting. Which is something that Twitter did take over. But my guess is this is just some 5% of the initial traffic and even Twitter could live without that probably.
non-standard UI elements are quite visible - modals, progress indicators, tabs
also everything around navigation is trouble - ios has those large headers that shrink down once you start scrolling. For a long time this was not possible in RN, not sure it finally is.
iOS 15 also uses modals quite a lot more than previous versions. Including modals on top of modals. Also impossible in RN up until recently, don't know current status.
While the navigation-related differences might not be consciously picked up by normal users, it may be subconsciously felt - the app doesn't feel right and user doesn't know why.
The cool thing about Flutter is that it draws components to the Skia canvas. I wasn't even aware it had a WebView. I'm not sure why you would use Flutter if your app consists mostly of a WebView. The bugs that were found are probably not fixed because they are very low priority. You don't save a whole lot by using a WebView in Flutter rather than building a simple shell around the iOS and Android WebView. Without knowing the details, I'd guess that the programmer is using the wrong tool for the job.
The Flutter webview is basically a wrapper for the native iOS and Android implementations. A native Android app using a webview and a Flutter app running on Android using a webview is using the same native webview.
It is like that for a lot of the Flutter libraries. They basically implement native versions of the functionality and make it available to Flutter. The Dart language has FFI so if you want to get "even more native" you can do Android and iOS system calls in your Flutter app using languages like C, C++, Rust or even Assembly.
I was really drawn to Dart when it came out in 2012 and still use it for hobby projects. I know Google uses it internally a lot and is used in the experimental Fuchsia OS. And of course Flutter. I wish Google would put more resources into doing the next version. It appears Bob Nystrom is the only person working on it
I wrote a fairly complicated web app in 2013 in Dart. I just updated it to Dart 2.0 and nullability and it still works, which impressed me. Someday people will catch on to Dart, probably if and when Fuchsia gets popular
Got any advice on how to lay out a design for Flutter? I'm a back end dev mostly, but I'd like to have a go at making a small mobile app. My sticking point is building the interface. Doing it all in code without a layout design tool to help feels pretty agricultural.
If one uses a webview, then typically there is JavaScript running there that does non-trivial things. So the application becomes a mixture of JS and Flutter. That already defeats the goal of using a single language and framework to develop the application. And when there is a mixture of two, the value of Flutter is reduced, as the mixture can be as well developed as JS + Android + IOS.
For me the strong point of Flutter is not to use the webview in the first place delegating the latter to the original cases of showing help pages etc.
Webview uses Skia but it uses HTML5/JS/CSS to draw on it. Flutter uses Skia in a different way, using a declarative component language and Dart in place of HTML and JavaScript
I was heavily involved with the rollout and maintenance of React Native(RN) at my previous job. This post touches on an interesting point that has just now crystallised in my head.
In particular the OP writes:
> Fortunately, I could find the bug in the library with my Swift skills, fix it within a day and even submit a patch to the owner of the repository. But I could find and fix it only because the library and my app were written in the same language, and this was a language that I was familiar with.
We adopted RN because we had a lot of web developers(hundreds) and wanted to enable them in contributing to our app. We explicitly didn't make it a goal to achieve code sharing, yet we did, to the tune of 90% of the code. Overall RN was successful for us.
However, one thing became apparent immediately: the RN developers needed support from native teams. As soon as the RN developers hit a problem that required bridging native APIs or a bug that required platform knowledge, they end up blocked with no way to unblock themselves. Luckily we could create a team of platform experts dedicated to supporting these developers.
This highlights the unfortunate paradox with cross platform tech. It's a great choice for solo developers or small startups looking to find product market fit and iterate quickly. They might be fooled into thinking that they can get by without learning the platform native methods and languages, only to find that they end up stuck when the leaky abstraction eventually leaks.
On the other hand, a well resourced company that can dedicate a team of platform experts as support for the cross platform developers will not suffer this problem, but is cross platform the right choice for a well resourced company? Such a company has probably already found product market fit and is better of paying the higher cost of native development to build a higher quality app.
A big takeaway from my RN experience is: One might expect that an RN developer can get away with knowing less about mobile than a native developer. Counter-intuitively, the opposite is true. A solo RN developer will, of course, need to know JS and React, but when the abstraction leaks they'll also need to be comfortable with Java, Kotlin, Swift, Objective-C, the respective build systems(CocoaPods & Gradle), and even C++.
If one considers RN's origin, being an internal Facebook framework. It all makes sense. RN was built to allow more developers at Facebook to contribute to their apps, without requiring them to learn native technologies or languages. Of course, Facebook has the best imaginable team to support these developer, the RN team itself.
In Flutter you need way less native code than RN in my opinion due to the fact that everything is rendered by the framework. I have around ~40k lines of dart in my app and only about 30 lines of native kotlin (and zero native lines on iOS, it's an android specific call). Flutter addressed my needs so in the future I could go back to zero.
I think the way to set it up is to have the senior engineers on your RN team be the ones who know everything: they are experts in JavaScript, but they are also comfortable dropping down into Swift/Objective-C and Kotlin/Java when needed. Then you can have junior engineers who are more focussed on the JS side of things (at least to begin with). They key thing here being that the people who can unblock are on the same team as the people who may need to be unblocked and can thus prioritise doing so quickly.
If you need extensive native code for custom modules (we haven't yet needed this at my work) then it would make sense to have native developers on each platform take a lead of that. But there should absolutely be people on your RN team who can do integration work and bug fixing independently of that team.
I think the key is: if you're working with cross-platform tech then you ought to have cross platform developers.
Absolutely, but this speaks to the paradox I think. Cross platform is an attractive choice, precisely when you don't have a such a person. For example, as a solo developer with no native knowledge who wants to ship an app or a small startup hiring their first mobile developer.
Being proficient in all of Web(JS, React), Android(Kotlin, Java, Gradle), and iOS(Swift, Objective-C, CocoaPods) is a pretty significant ask for a single person too. Personally, I check two of those boxes(iOS and Web), adding Android as well would be a bit much.
Hmm... I don't necessarily think it needs to be a single person knowing everything. For example a team made up of you, someone else who knew android and web, and a bunch of people who only knew web would work really well I think. Those who were experts in the native platforms would be responsible for bringing the rest of the team up to speed (providing context, advice, pointing to learning resources, etc).
As someone who came to a react-native project (as the lead) with a web and cordova background and no prior react-native or native platform experience, I've found that just knowing about the ios and android build systems and being able to add basic code to the AppDelegate (ios) and MainActivity (android) has been entirely sufficient for our needs. It would be different if we needed custom native modules (although I'm confident I could learn - I think learning something specific like that would be easier than trying to work out how to structure a whole native app), but then the react-native ecosystem is pretty broad these days. A lot of things are covered.
I’ve shipped a number of RN apps for my current and previous company. I guess I don’t know the extent of what some companies are doing with RN but every time I hear about having to dive deep into Native Modules for their app I always wonder what in the hell they are doing.
The react native ecosystem is huge so you really have to have some domain knowledge to be good at it in my opinion. I’ve read articles where the author was in Native Module hell and I just thought “oh well they could have just used this great package”. I know that illustrates a major problem with RN, but its exactly the type of domain knowledge that will make of break your RN experience.
Yeah I agree. I used to try and be good at all three but dropped android and now just focus on web and iOS (for both day job and hobby stuff). Keeping up with android wasn’t fun for me anymore
This is how we setup our teams for React-Native projects. We usually will have the lead for either-or of the Android/iOS teams also be familiar with that platform.
For example myself: I was the co-lead for 2 React-Native projects at my company along with a dev who is very familiar with Swift/Obj-C. I'm still much more familiar with JS/TS-land but I was one of the few on the team fairly comfortable dropping into native Kotlin/Java for when we needed to.
This worked out well for us. The native iOS dev who worked along with me was less experienced at React/JS/TS itself so I took most of the shot calling for that but having him there for native-iOS help definitely pushed us through points where we would have hit a roadblock for a fairly large project. In the end we had 200k LOC on the React-Native side, and a fairly large amount for both in native due to a large feature that required us to drop into native.
This totally true. I think however, Flutter does a better job in fixing platform related issues.
Also, in my experience upgrade to a new version of RN was usually very painful, with Flutter so far it was straight forward.
In the article, he mentions the need for a DOM parser dependency for his app, as Swift “does not have one.”
> AEXML was needed to parse some XHTML files as the native iOS SDK does not provide a DOM parser.
I have used Foundation XML parsers[0] for many years, but they are general-purpose; not specifically modeled on DOM or HTML, which probably limits usefulness on some Web content.
That said, if he has control of the content (don’t know the app, so I am not sure), then there should be no reason that they couldn’t render it in XHTML, so the Foundation parser could be used reliably. In the article, he mentions that the content is XHTML. I have to assume that AEXML[1] is easier to use than the built-in parser. It uses Foundation parsing (it actually seems to be a lightweight wrapper for the built-in parser), under the hood (and seems to be a very well-written dependency).
So, it could be posited that he would only need one dependency for his native version, if he wanted to handle the XHTML parsing, himself.
Personally, I am a huge believer in native platform development, having many, many scars from the compromises required for cross-platform solutions.
That said, I totally understand why folks prefer cross-platform development, and can’t, in good conscience, recommend a native approach for all apps.
Worth noting this article is almost a year old now (Feb 2021), prior to Flutter 2.0 which supports web-based apps with CanvasKit. Flutter was only officially (1.0) launched 3 years ago.
I have read a lot of feedback that, while flutter web is now stable, it seems a little premature. The performance of canvas rendering with flutter appears to be universally bad, especially on mobile, and there are some UX issues around scrollbars, insane bundle sizes, and long initial load times.
Anyone have some success stories of using flutter web? I read you can output HTML/CSS/JS instead of canvas and a lot of these issues go away, is that true?
I've been doing cross-platform development on and off for 30 years. Back in the DataViews days we had a team of two dozen professionals working on this problem and made good bank selling developer seats for about $15K each. Flash forward 30 years, and here's what's changed:
1. Users expect this stuff for free
2. For the most part it is, but only because the tools are being developed by big-tech and serve their interests more than yours
What hasn't changed:
1. compile-time. I just don't get it. Computers are like 5000x faster
2. cross-platform is hard and involves lots of compromises
> and made good bank selling developer seats for about $15K each.
> 1. Users expect this stuff for free
I learned Flutter for my own needs, I make about 25k€ / year after taxes, I couldn't afford to pay this kind of money for hobby stuff. Even Embarcadero stuff at 5k a seat is way too much (I can get a good used car for this price).
Even at work I have to fight to get better hardware than Raspberry Pis (they regularly have black screens that only a few hard reboots solve).
The problem is that we don't live in the same world: there are companies where money flows and other companies where every cent has to be justified because money doesn't grow magically under unicorns hooves ...
I looked into Flutter last year for an app I was developing that needed to use a webview for a large part of its functionality (I wanted to use a ProseMirror rich text editor). From what I could see it felt very much like webview was a neglected part of the framework; multiple incomplete community implementations, a work in progress “official” one, very long lists of bugs. There was massive problems with “contenteditable”. What the article is describing with random bugs on random devices what I saw in the bug tracker.
Ultimately I went with Ionic/Capacitor and it was a great experience. Very easy to get up and running. I also experimented with combining Capacitor with NativeScript (they launched a way to use the two together) and it seemed like a brilliant way of exposing native functionality to Capacitor without having to drop all the way down to Swift/Kotlin.
The only significant complaint I have about Capacitor is on iOS and a WebKit bug (Ionic can’t fix it). With WebKit on iOS if you have an overflow:scroll with a text input of any kind (basically any app you build) the text cursor or selection highlight will remain visible outside the overflow area when you scroll. So for example if you select text in an input and scroll the view so the input is under a fixed toolbar, the selection highlight or cursor is visible infront of the toolbar. It looks very messy, I wish Apple would fix it.
I would, however, definitely use Ionic/Capacitor again, particularly if a webview was a major part of the app or as a small team targeting web and multiple mobile apps.
Glad to hear Ionic and Capacitor worked great for you!
On the Web View side, one other thing we’ve been working on is a mobile micro-frontend product called Portals that is focused on enabling teams to bring in web experiences into their native apps. We’ve seen some really interesting adoption of it from traditional native teams. We will be supporting Flutter and RN this year. It’s probably the best web view experience out there at the moment: https://ionic.io/portals
used ionic for some small stuff years ago. Kind of assumed it had lost the cross platform race considering how little I see about it. I thought React Native was the lead runner in the cross platform wars right now, anyone care to correct me or give me their take on where it's all at?
They move some stuff around like null safety and it’s a bit of a pain but it’s fairly easily to update. It’s still a developing framework and language (Dart).
The difference for us, and the reason we chose it over React, is that Dart/Flutter look a lot more like C/C++. React seems fine if you are using/know JS, which we do not.
It sounds superficial but it’s been great and we’re quite happy with it.
Flutter seems to have been gaining a lot - React Native is still popular due to size of the web crowd who refuses to look outside their little ecosystem box. But mostly, companies have been reporting that Flutter is much easier to maintain and much easier to reliably deploy across devices - it also doesn't suffer from NPM hell / dependency rot in the same way RN projects do.
I'd say both are on about the equal footing these days.
> the web crowd who refuses to look outside their little ecosystem box
I mean, we usually don't require other developers to actively work in 3 different stacks because there are theoretically better languages around the corner. In fact we even make fun of premature fanboyism such as RIIR.
Today, the web works for most purposes, but when it doesn't, you may need native apps. It then makes perfect sense that people can reuse skills, ecosystems and tooling. From a UI perspective, any modern web rendering engine can do pretty much anything GUI fast and consistently.
Dart is a tiny language in comparison, and last I checked Flutter's web target backend used an opaque canvas element for all rendering, which wasn't just terrible for accessibility but also super laggy. I am still excited about Flutter but they have a lot to prove before I'll frown at the web folks.
I would say that the web does not work for most purposes unless I ignore the horrendous architecture that is imposed by using it.
I bet only 1% of developers these days have written a native or desktop app. If they had, there would be a gravitational pull moving away from defaulting to the web. I can hit any API from a Swing or WPF app and look damn good doing it with blistering performance.
It shows whenever project owners start asking developers to work around or prevent the use of browser based navigation like the back button.
The browser is like a hand grenade being rolled under a software project. The ultimate shitty dependency.
My perspective is the opposite. Flutter does have a super nice dev workflow, but it's quite limited in how well it can integrate with the underlying platform and hard to extend if you need to step outside of what's available. On the other hand react-native is really maturing and has addressed most of the issues that people had with it. And is now expanding on to the desktop too!
People and especially managers think that cross platform apps will save them money/time. However, they don't realisize that cross platform solves one problem and creates ten.
The developer experience is worse, the user experience is worse and you end up with a pile of mess after 1-2 years.
I have an Ionic app used by thousands of people daily since 2017 on both, Android and iOS. There are certainly some downsides, but it really didn’t create 10 problems for every solved one.
Ironically, I have an older native iOS app and it briefly stopped working on iOS 14.5 for no reason with the message "developer needs to update this app", like when apps had to switch to 64 bit. A few months later, the very same app started to work again in a later iOS version.
I follow a few native iOS devs on twitter and it looks like they have to deal with quite a lot of shit in Xcode and Swift all the time. I don’t. My app has been running pretty stable.
And yes, dev saves time. One code base for 3 platforms, dev experience is pretty great (hot code reloading, same IDE for all platforms 98% of the time).
Managers are incentivized to show pretty numbers about code reuse and platform feature parity to upper management, because that’s how they get their bonuses. Also webdevs are cheaper than mobile engineers. Upper management gets soaking wet from stuff like this.
Just embrace C++ for business logic (supported natively by both SDKs) and use native views, and for most CRUD apps, mobile Web works just fine.
Anything else, might look enticing, however as the author points out brings lots of attrition and failures can happen at any level of the stack, thus requiring native programing knowledge to sort them out anyway.
So instead of being experts in two stacks, the team now needs to be expert in three stacks.
The thing is, for most mobile apps, 99% code are views, with a very tiny part that can be called "business logic". Doesn't really make sense to involve C++/JNI bridges hassle.
For the projects I worked on, the bridges were automatically generated, so no hassle for the developer. Admittedly we built our own code gen system which of course was not free.
Dropbox used to do this but eventually abandoned it, due to the cost of maintaining C++ code that works on multiple platforms. Turns out that might be more difficult than maintaining native code for each platform.
I am aware of that case, and it mostly boils down to not wanting to pay market prices for newly hires to replace the C++ developers that left the company.
Absolutely, many large cross platform apps - MS Office, Zoom, Webex etc follow this strategy, it just doesn't seem to be that popular with the HN crowd.
Just a guess, many want to silo themselves into TechX Developer instead of embracing polyglot stacks.
You see that often, when instead of rewriting the parts that may have performance issues into a library and keep everything else working as usual, we get those rewrote X in Y posts.
xcode is the opposite of a tool and it is somehow getting worse with age. apple has exactly one job and apparently it's to make xcode into a hot pile of garbage. flutter is like terraform. Is dart a good language? No, it's a piece of shit. Most languages are. Dart, moreover, is the reason the google ads dashboard melts your laptop. But it saves you from the peril of directly gazing upon something much, much worse.
ios devs all have stockholm syndrome and will tell you 'it's not that bad' as they upgrade their dependencies for the 60th time to keep up with some unnecessary framework change aapl is forcing them to do because nice app store ranking, shame if something happened to it
Is this based on experience? Not saying you're wrong, but I've been bit before by putting emphasis on the language when what I really needed was tooling and a healthy ecosystem.
Is the standard library much better than Swift/Objective-C? As the migration was from a native iOS application to Flutter, I'm not sure why you're pulling in "JS framework" in your argument.
The author dedicated a fair amount of the post to say whether cross-platform frameworks are a good idea, the majority of posts here seem to be focused on the same subject. Given a lot of discussion about Ionic and React Native here, I figured I would toss in my two-cents.
To my memory of working with Swift, I wasn’t left wanting much when I moved to Dart.
Dart isn’t as interested in value-semantics as Swift, so there are all kinds of Dart packages for immutable classes and collections, so that’s a notable miss.
I believe they’re planning to add something more like Swift’s struct to Dart. (dataclass proposal)
It's still very early and very alpha - enough that it'll probably massively block at least one of your important production releases.
It's promising though, although it doesn't really solve the same kind of issues as Flutter - Flutter is a UI library first and formost. While Kotlin Multiplatform will most likely replace cases where we use C++ for porability now - internal, shared libraries.
I've used Kotlin Native around 6 months ago, which seems to be the iOS target for Kotlin Multiplatform. I ended up switching to Go, as much as I didn't want to, because of memory leaks when interacting with the official HTTP client (Ktor). The multithreading through coroutines is pretty experimental and unstable.
The community is small, and there is not a lot of actually multiplatform Kotlin libraries, although I saw some libraries making progress towards it. I found myself having to write bindings to C libraries a lot.
The language is very promising though, it's great with the JVM or JS as target.
Apologies for the naked plug, but I've had so many clients over the years try and fail to get cross-platform apps to work that i'm currently working to try make something that will actually work, freed from the incentives of the big companies pushing eg flutter and RN. It's slow going however... if you think there's a future in this kind of thing, consider asking your boss to sponsor it to help speed development? The idea is to write in a Swift-ish language, compiled to native code on both platforms, and wrap the native components, but do it in a way that learns the lessons from eg RN's difficulties to include a sensible cross-platform navigation component.
(the project is github.com/soniclang/sonic)
While I agree that the bug fixing capabilities of the flutter team could be improved, it‘s still reasonable to assume that they‘re primarily caring about Google‘s issues - given Google pays the party.
Still, you comparison isn‘t really a good fit IMHO because it seems you’re „just“ wrapping html content into the native ecosystem, which defeats somehow the purpose of actual native apps.
And even if you‘ll only target iOS I‘d say Flutter is still a more pleasant and more productive tech to use compared to f.e. SwiftUI - of course this only applies for actual native code.
Still interesting to read, thx for the article.
I might modify the title though since I wouldn’t consider a html wrapper a native app you‘re migrating to flutter.
In OP’s use case he describes the purposes of the having the html content wrapped in an app: easy access in an emergency.
I am curious as to why the tech community feels so strongly against html content wrapped as an app. There is a lot of valuable reference content which would benefit from being freed from the rigid structure of an ebook, and so suit an app very well, but doesn’t need ‘native’ functionality per se. Putting that content into PWA makes it harder to monetise. App distribution model works well.
Can you explain why mobile developers run away from third party components?
I'm a full stack/data engineer and use third party components all the time. In fact, I'd choose a popular and maintained component for the job, instead of writing it myself. I have no issues using as many components as I need. This seems like a bad practice in mobile.
If I encounter a bug in my dependencies, I find it, fix and send the fix to the maintainer. The same as I would do with my own code.
In this particular case, the problem is that the plugins require Dart glue code, and a native implementation on both iOS and Android. So if you run into a problem with a component, it's much more complicated to fix it.
In general, using third party components with native mobile apps is pretty straightforward.
Even for full native, I try to keep the number of third party dependencies down and limit them to libraries that fill legitimate voids in system functionality or are only light sugar around system stuff for a few reasons:
- Many libraries have zero guarantees as to how long they’ll be maintained or if their maintainer(s) will keep pace with new system releases, build tool changes, etc
- It’s less unfamiliar code that I’ll need to wade through at some point
- Fewer libraries reduces lock-in that can encumber refactors and other major changes
- I don’t have to waste as much time and energy “translating” things between different libraries with related functions
I used to not be as avoidant of a long dependency list, but over the years I learned that for both iOS and Android, each library represents a liability across multiple dimensions that WILL become a problem at some point, probably sooner than later. Mobile platforms aren’t like their desktop/server counterparts where the various APIs have barely changed in decades, and they aren’t like the web where everything continues to be supported for practically forever. Things change, and it’s important to be able to keep up with that.
This is a lot easier to manage under iOS than under Android, incidentally. Cocoa Touch still sees tweaks but it’s quite mature, and very deep and capable. You can build a world class app with just Cocoa Touch alone without too much trouble. With Android Framework on the other hand, much of what’s built in is incapable, with bits and pieces constantly shifting in and out of being supported, making it the norm to bring in a laundry list of libraries for super basic stuff (e.g. everybody uses Square’s OkHTTP for networking on Android while on iOS, not using the built in URLSession and associated APIs is very strange).
I think this is just a propagation of the issues larger organizations may generally have with dependencies.
You don’t want your applications be dependent on the update cycle of other organizations/individuals. What if the bug fix does not get merged into the master fast enough? Do you fork? When do you recombine again?
But otherwise I agree, sharing code and making it better for everyone as well as delegating complicated parts of the application to others are well practices.
I tried Flutter for two weeks before hoping out hard. Can't put my finger on it but the combination of chaining everything into a huge nested pile of shit and....Google really turned me off. I was far more productive in Xamarin Forms.
"Any piece of code that is not your own and that your app depends on adds to the technical debt of your app."
We need to start pulling in dependencies as code instead of binaries. It should become part of our project and we should remove that which we do not need and maintain or patch those parts that need it manually...one our own.
The number of dependencies in projects cause a great deal of bloat, cross-cutting nightmares, and unending security vulnerabilities that make us desperately seek support in the form of new binaries from unpaid contributors. It is not professional, dignified, or safe.
If you need StringUtils.isEmpty you should not be pulling in the apache commons jar. Just clip the code you need and squirrel it away in your project.
I find Qt/QML for cross-platform mobile applications to be a great solution. It uses the same basic architecture as Flutter – they both do not use native widgets and instead draw the entire UI on a blank graphics canvas. I think that approach preserves the most code between platforms and reduces the kinds of presentation hitches that HTML web view and hybrid native widget approaches can run into.
In relation to the particular problems of technical debt related to third party modules mentioned in this article, QML rides on top of Qt which is a 26 year old C++ cross-platform toolkit with a lot of mature technology in it. I.e. there is a lot more "batteries included".
There are still plenty of times you have to "go native" to integrate something Qt doesn't cover but it apparently isn't as often as with Flutter.
Can you give me an example of a good mobile app built with Qt/QML? I feel like only big corps can justify such apps where users have no choice but to use it because their boss forced them to.
You are jumping to mistaken conclusions based on one review, the motivations of which you don't know.
I think cross-platform apps are commonly misapplied and really only make economic sense with the appropriate assumptions. Once a company has the necessary resources they should go native and go all in on platform conformity.
But for many folks, that's not a feasible place to start from.
Tim here from the Flutter team; thanks for the post. There are some good points here: in particular, that no single framework or toolkit is the "holy grail". We all live in a world of trade-offs, and anyone who claims that any single technology is the panacea for all problems is selling a mirage.
I really appreciate the constructive critique in the article: both the good (getting an app up and running quickly), and the more painful to read ("Flutter's ability to execute leads a lot to be desired, particularly on iOS"). While Google is the primary sponsor for Flutter, it's an open source project, and so as ever having reproducible bug reports and ideally pull requests is how we make it better.
The raison d'être for Flutter is simple: we don't think you should have to write the same code six times for your app to reach each major desktop, mobile and web platform. This abstraction is not free, but we think it's worth the bet, and there are some cool apps being built with Flutter, plenty of which have been awarded accolades like Apple Editor's Choice. We're not the solution for every app out there, but there are startups who don't have the developer team size to build multiple apps but can benefit from Flutter, as well as larger companies for whom Flutter lets them unify their app development team behind a single codebase.
A few quick comments I wanted to make:
- Yes, we have a large number of open issues -- over 9,000 at the last count, but not all issues are bugs. We're somewhat unique in bringing together tools, packages, framework and engine issues into a single database, also merging feature requests, bugs and even API doc requests together. Our general philosophy is that it's better to have it out in the open rather than (for example) to prematurely close issues that we don't plan to work on ourselves. We're also not unique as a large open source project in having lots of open issues (also see projects like PyTorch, Rust and VSCode). Lastly, it's important to count the number of issues _closed_, which is over 50,000, representing bugs fixed, new features implemented, and so on. We document the triage process here: https://github.com/flutter/flutter/wiki/Triage
- I'm surprised that the author considers packages an inevitable weakness. We've deliberately kept the core of Flutter relatively small, because it enables us to iterate on packages at their own pace. We could have taken the approach of building things like XML parsing, HTTP servers, geolocation and so on into the core of Flutter, but it wouldn't automatically make them more robust. With a package model, we can fix a specific issue without requiring a whole release cycle for every part of Flutter. Over the last year since the author wrote this article, our package maturity has greatly improved, and I'd be interested to know whether this is noticeable.
- Lastly, the underlying fear expressed in the article seems to be that Google will at some point just give up with Flutter. I understand this, since we don't have an immaculate reputation in terms of long-term support. I will say that this question doesn't come up internally with our stakeholders, though. There are over 400,000 apps in the Play Store that use Flutter; about 1,000 Google engineers building highly-strategic products using Flutter; and a healthy ads revenue from apps that use Flutter. The project more than pays for itself, and I can't honestly envisage any scenario in the next decade where Google would choose to squander all that.
i love working with flutter and dart. really hoping the job market opens up more for those. one major annoyance for me is having to create a class to handle the data from a json.
i would love to see dot notation access to keys like how javascript handles json, it turns it automatically into an object after using .json()
but overall i enjoy working with it and it is always good to see posts popping up on HN about it
"After some research.. ..I decided to give it a go."
Hmm.. From my experience, every time I pick a new language / framework, always always always do proof-of-concept for ALL features you might need: camera, GPS, webview, deeplinking, etc. Don't want surprises.
Esp. if you already have an existing app, you should have a clear visibility of what's needed.
My theory on why Flutter is popular in developing countries is a Flutter app compiled in release mode is turned into AOT code. This gives it a performance boost on apps that are constrained by low CPU and memory resources.
I expect that that most HN users probably have a flagship mobile phone with lots of CPU, RAM and reliable mobile data options. The other 90% of the world can not say that and a lot more sensitive to apps that require advanced phones and operating environments to function.
Wouldn't it be more logical to build only for Android then? There probably are few Apple devices in developing countries and native is much faster than Flutter.
There's a video on YT where a guy (from India I think) shows the starting time of a todo app built with RN, Flutter and native. Native is lightning fast.
I am from India and pretty sure the reason here is it's much easier to make UIs in flutter than in Android native. Nothing specific to India being a developing country.
It's natural to see students using easier stuff as well. Most of student projects you come across is using react, flutter, firebase, MongoDB, as opposed to Angular/Vue, Android native/Jetpack, postgresql etc.. which have much higher barrier to entry.
But this may have to do with developing countries having more recent developers, and less established developers.
> Any piece of code that is not your own and that your app depends on adds to the technical debt of your app.
I find this ^ strange. There is a difference between using a library and technical debt. We use libraries so that we do not have to solve a problem that someone already has. Tech debt is a "shortcut" that you took when implementing a system because $deadlines/$budget/etc. An example might be calling a binary to do something for a PoC because interacting with a library will be more effort.
Using libraries is a good thing, it would be sad* if all of us keep solving the same problems over and over again. Tech debt, on the other hand, is debt, something you want to avoid as much as you can.
* personally I find having to re-solve solved problems one of the most frustrating things when programming, it takes away all the joy
I agree and I would not call all dependencies a form of tech debt. They become debt only when you need to replace the dependency to do what you want to do. At that point the work to fix a bug or add a feature will fall to you, and it will become a debt. However to preemptively call all libraries technical debt rubs me the wrong way, combined with the author saying debt is always a bad thing. I always see debt in that context as “work that was put off”.
On the other hand, if you don’t use libraries you’ll end up with an enormous pile of technical work to do, likely outside your core-knowledge, just to get your project off the ground. Nobody can afford that, and you need to borrow from existing libraries to get your app off the ground. In that way it could be analogous to debt, but in the way that debt can be good.
I also don’t see dependencies as technical debt. In many cases they are the best implementation of a thing for that Language/Framework. Take react-navigation which is the de facto navigation library for React Native. You could argue that it should just be a part of RN but can you really make the argument that reimplementing navigation is going to give you less tech debt than pulling in this lib.
The article expands upon this point in great detail. To wit:
> Flutter's HttpServer that crashed on iOS if the user briefly switched to another app and then back to mine.
The author is seemingly capable of writing a solution to the concrete problem, and even debugging and fixing issues in simple libraries, but fixing this issue in Flutter itself (which is much more complex than a concrete solution) is too complicated, leaving him at the mercy of the Flutter maintainers.
He may be saved from solving an old problem again, but it seems that he now has a new, much harder problem to solve. In this context, I think it makes sense to describe using the Flutter library as a technial debt in your definition above.
You say that libraries are a Good Thing (tm), but how would you handle such an issue?
I think your definition of tech debt is too narrow. As with "real" debt, it can be accrued strategically (like, say, a mortgage), but you will still have to pay interest on it (in this case, by struggling to debug/fix the code). As with a mortgage, you may decide this is worth it. Or, in the case of a shortcut, you may decide it needs to be fixed ASAP, because the ongoing cost is too high.
Honest question to those who've been there and don that. What's the right solution path for a very small (3-4 people) team to build a relatively polished mobile app? Options I see are:
1. Native iOS followed by Native Android
2. Flutter
3. React Native
4. Capacitor
5. Microsoft toolkit of the day
I may soon embark on such a task with such a small team. I am leaning towards #1.
I work on a Flutter app with a small team that does both iOS and Android from the same code base. It works really well for our use case given the size of our team. I also have experience with both native Android and iOS. The way Android and iOS handle apps is completely different and jumping between the two requires a lot of mental context switching.
Something to think about is all mobile apps come with the typical boilerplate. Think about a screen that displays the results from a REST call. You will need to create the screen for the Android app using either XML or Jetpack Compose frameworks. The iOS will need to create a screen using storyboards or SwiftUI frameworks. That is a lot to maintain. With Flutter you create the screens just once in Flutter and the only framework choice is Flutter. Now at some point in the future when the REST call adds a new field you have twice the work to do with native solutions then you do with Flutter to add it to your screen.
I would also like to correct misconception about Flutter. Flutter doesn't eliminate the need to do cross platform development. You still need to know the native tooling, native build cycles and native programming languages if you want to get a Flutter app out the door.
You will end up writing less code. You won't have to tackle advanced subjects like managing app state in Android and iOS. You can use a Flutter state management solution that works on both platforms. You won't have to feature match your two apps because they will all use the same code base.
If you are a small teams looking to get something out the door, all of these are points in favour of Flutter. It works better for teams will constraints such as team size, budget and time.
Disclosure: never done any iOS development, only android as a hobby/personal projects. I'll be first to admit I have always hated Java with a passion. So when Kotlin came along I was thrilled. It still piggybacked on the wretched and slow as hell JVM but at least the syntax was pleasant to work with and didn't offer one way to get from A to B which involved 3 abstract classes, 5 factories and two ultra wide monitors to fit your class names. Flutter came out iirc about a year later and I was on a bus going to a friends's house on the other end of the country. I pulled out my laptop and spent the next 4 hours fiddling with it. And even though it was young and far not mature, I have to admit, I enjoyed it and managed to make a fully functioning app in that time. I had fiddled with dart a bit while I was still in university iirc, just because it was a promising alternative to js(which I also hate with a passion). And even with my rusty memories of it, I felt right at home. It is true, flutter gives you a far greater flexibility when you are building a UI than any of the native solutions. But I feel like the author(s) of the article made one fundamental mistake - depending heavily on components developed by other people. The truth is, flutter is a good choice when you want to do a custom UI at a relatively low price(in terms of how much time and effort you need to spend on it, compared to the native solutions). In addition for cross platform development, dart, unlike javascript, is entirely predictable.
BUT! If you are working on a complex application which requires a lot of resources and clever ways to keep a low footprint, you might be better off with the native solutions(even though dart has a very mature ffi). I guess a similar comparison would be something like tinygo and micro python for embedded development - good enough for simple things, but anything beyond that, sack them and stick to C/C++.
The first thought is on maintenance and support from Google/Facebook compared to someone like Ionic. One of the things people don't think about before it's too late is support, and Ionic is unique in mobile in that we actually make money from supporting our technology directly for customers. We have direct support available for our auth/security/data storage plugins, cloud services, and open source projects. We literally will respond to customer support tickets and make fixes/patches on a weekend if we have to.
Is there any other company out there doing what Ionic is in mobile? You mention having issues with the Web View component, is Google or Facebook ever going to prioritize your issues? It's not likely, they don't have that kind of business model around their technology like Ionic does. Facebook builds RN for itself, and who knows what Google's end-goal is with Flutter (drive GCP adoption? push its ad network?) but it's certainly not to monetize it through dedicated support for the most significant users of it. I'm proud that the Ionic stack is the most user-aligned offering out there because we're literally in the business of supporting and extending users of our OSS stack.
On the Web View side, we've recently shipped one of the first mobile micro-frontend projects in the ecosystem called Ionic Portals which is basically an awesome Web View component powered by our tech and expertise building web view experiences on mobile. Right now it doesn't have RN or Flutter bindings but we are working on them this year. This has been a pretty interesting shift for us and we're now working with traditional native teams not using the traditional Ionic stack:
https://ionic.io/portals