327 comments

[ 2.6 ms ] story [ 309 ms ] thread
IMHO another downside is Flutter not using native UI components, unlike React Native.
Also: - People have to learn Dart, where React-versed devs are plentiful

- Can’t share code between the web app and the mobile app

Dart is pretty easy to learn and you can use the same code base for a web and mobile app if you were inclined
Except I have yet to find a Flutter site that isn't bloated. It makes about as much sense to just focus on PWAs now.
Sure, it's easy to learn, but why bother when you can just use React Native? Also there are a ton of senior people with lots of years of experience to hire, where Flutter seniors basically don't exist.

With React being prevalent on the web front, why would anyone do a Flutter web app + mobile app?

Flutter release code compiles to AOT code which speeds up execution. React Native has the Javascript engine which can slow things down. For most of us here on HN, who are using flagship phones none of this really matters, however for other parts of the world that have less capable phones, the ability to run AOT compiled apps is a big deal. Flutter is a huge in Africa, mostly because it runs well on a lot of the popular phones there.
Maybe in theory but JS JIT engines are very fast and Flutter can be janky especially on iOS.

Both will perform well, I've made advanced applications on RN that perform well.

(comment deleted)
They must exist because I’ve been passed up on senior flutter roles. It can’t be me, right?
Using Flutter Web now, and sharing code between web app and mobile. Early but working well for us.
How does web accessibility work if everything is rendered in canvas? Interested in the topic, but this would be a potential deal-breaker for me.
Transparent DOM elements with aria attributes overlayed on top of canvas is a typical solution to this problem.
Could you elaborate on why is it a downside?
It will not have a native feel I guess, so it will feel a bit off to both android and iOS users
Have you actually tried it or it's just a guess? I had similar thoughts before I tried myself, and actual experience is completely opposite. People don't care if it "feels off" (especially when it's pixel-to-pixel perfect and you literally have no way to distinguish native components from "non native" – in the end it's just a bunch of pixels sent to the GPU).

I mean, Flutter is stupidly good at this.

It brings its own widget implementation, with themes that approach, but do not perfectly match the native toolkit.

The downside is, that it doesn't implement the platform look&feel perfectly. If you want fully custom look and feel, it might be not a bad thing, but those who aim at native experience, they will never reliably get it.

---

On the other side of the debate, React Native, it is not all roses either. While it uses native widgets, it also runs JavaScript. And not just any JavaScript engine, or your preferred JS engine, but JSC. With JSC, RN team took their sweet time to support 64-bit Android properly, with issues rearing as late as 2020.

Before I started writing Flutter I had the same feeling. My first reaction to the Flutter design was "haha, it's not gonna work". But when I tried to make my first app I was shocked how good it was.

Since then I learned that most users do not give a s...t if it's pixel in pixel perfect copy of native components. Especially when Flutter team makes it literally pixel in pixel perfect to the native UI. I mean, it really doesn't matter in 99.99% cases in my experience (I have around 12 apps in Flutter atm).

So I see this Flutter design feature as huge upside, not a downside.

To add to the other replies here. It also puts the project in a precarious position since there is a huge amount of work involved in reimplementing UI controls from scratch and keeping them up to date with the platforms. If Google drops it or winds down their commitments, it would need backing with equally deep pockets to survive.
- Flutter widgets can be made pixel perfect replicas of native UI components.

- Supporting older platforms is much easier with Flutter.

- You can use native UI components with Flutter if you want to, and mix them with Flutter widgets.

- Flutter has a tiny and fast runtime, React Native runs on Safari or Chrome. Flutter works great on embedded platforms too, such as IoT devices.

- Dart is similar to JavaScript, with the same runtime behavior, though obviously you can't use existing JavaScript libraries outside of the browser. You can use many WASM ones though.

>- Flutter widgets can be made pixel perfect replicas of native UI components.

How can I make flutter use native font rendering? I've played around with it a bit and fonts look completely off, don't respect my systems hinting settings, etc.

Low PPI displays require subpixel antialiasing which is not yet supported.

https://github.com/flutter/flutter/issues/63043

That is unrelated to my question. I'm using hinting and have everything sub-pixel-related disabled. If flutter does not support this, then flutter cannot look native.
Flutter uses Skia, Harfbuzz and FreeType under the hood. The last two is used by almost every other software for text shaping and rasterization.

You should open an issue if your font configuration is not applied, although on Android, iOS and macOS font hinting is not relevant, and I think on Linux fontconfig is used. I don't know about Windows.

On iOS, Flutter apps feel out of place. They don’t respond to common gestures, the Flutter team is always in catch-up mode with the latest iOS UI changes, and they don’t even support 120Hz refresh rate on the iPhone 13 Pro yet.
I have been investigating Flutter and other solutions for cross-platform desktop GUIs, where I am not interested in mobile or web apps. For me and for this use case, I think I've landed on not caring about native UI components for GUI. It just doesn't work in my opinion because you're either at the whim of the OS in regards to their constantly changing UI components and UI guidelines/styles, for Windows and macOS, or you're in Linux land where such things don't exist. There's quite a few big applications that are on both Windows and macOS that don't follow either OS' guidelines or use native components.

If you're going true cross-platform across Windows, macOS, and Linux, I think it's hopeless to try and maintain three separate apps that look and feel like a supposedly native app should look and feel like, if there's such a thing anymore. Windows and macOS are not even consistent for their own apps and OS GUIs.

Flutter definitely looks the most hyped cross platform SDK, but is it really the most adopted one? For some reason I don't see many flutter jobs in western world unlike you can find many jobs for react-native devs.
This is one of the reasons I don't fully embrace it for now - every Flutter gig is posted by someone non-western, i.e. with non-western budgets.
Flutter is becoming the belle of the bal outside of Western countries where venture capital to hire specialists with a 7 figure salary is generally available.
I see more companies specially startups adopting Flutter even in the west. But companies that had already started with RN are not going to switch to Flutter, and that is reasonable
Flutter has become big in places where there are limited resources, financial and human, and getting as much value out of each becomes more important.

In the limited mobile ecosystem of Iceland for instance, there are no positions advertised for native mobile development, only Flutter/ReactN.

Question count on SO doesn't necessarily correlate with popularity. It might correlate with poor documentation, high bug counts, low API discoverability, higher usage in "sweat shop" contract houses.
Yes, I don't believe that Flutter is more popular than React Native.
...and popularity doesn't correlate with quality.
Since Dart left the browser quite a while ago, would be great to have a native multi-threading.
Dart did not "leave the browser"; compiling to JavaScript is still one of the supported compiler paths and Flutter for the Web is a heavily touted ability of Flutter.
He's talking about Dart once being natively supported in Chrome, or it was going to be awhile back. They cancelled the idea in 2015.

Dart is nice but it lost, TypeScript has won for many reasons.

While Dart has always compiled to JS, TypeScript has always been "JS with types." Any JS file is a valid TS file if you change the filetype from .js to .ts but Dart has always been its own thing. I don't think Dart was ever natively supported in Chrome; there was a development fork of Chrome in which it was supported but it was never mainstreamed (unless my memory is faulty on this -- it has been several years). The rumor was that Google would put Dart support into Chrome and suddenly web apps like Gmail and Maps and G-Suite would see a 20x performance increase while using fewer resources, all because they had been re-written in Dart, and that would push the rest of the web to at least seriously consider Dart if not adopt it. Clearly that didn't happen.
Yes the GP comment was about their Dart support in Chrome that never went mainstream, then they cancelled it. My comment about TypeScript was an overall view on the ecosystem. Even Angular abandoned Dart.
Yes, basically Dart/Flutter now embraces being a full fledged standalone cross-platform client development tool. Lately, desktop platforms are embraced as well. In order to lure C++/Qt/wxWidgets, C#/WPF, Delphi, etc... devs, native multi-threading support is vital I believe. Otherwise, Flutter will keep the reputation of "a sandboxed tool for cute weather apps development" among such devs.
I read that Flutter is biased towards Android and that iOS support therefore falters.

I've therefore decided to write my iOS app in Xamarin.iOS, instead of a cross-platform solution like Xamarin.Forms or Flutter. The Xamarin.Android version already works perfectly, but my attempt at a Xamarin.Forms version had dismal performance and simply couldn't match the native Android version.

Not sure the scope of your app, however I have built several sizable apps using xamarin forms over the past 3 years, and over the past 2 years the forms apps have improved to have pretty much identical performance for me. My apps are mostly data collection forms with offline data sync and report viewing with charts & graphs.

Also try looking into xamarin's successor "Maui" which I have been playing with and am impressed with the speed and code organization, even though it is still in beta/preview.

I'm anxious to try Maui but also want to see it come out of preview first, which is supposed to happen some time in Q2 from my looking earlier today (with RCs hitting this quarter).
The thing that bothers me about Xamarin.Forms and hence MAUI is that it's never finished. Even now Xamarin.Forms feels like it's in Beta, almost a decade after its first release.

Now with MAUI we're moving into yet another long period of instability and change. I'm fed up with this.

I would say https://capacitorjs.com/ is the best in this space right now, which this article doesn't even mention. Especially with the nativescript plugin https://capacitor.nativescript.org/.
I believe Obsidian uses capcitor for their mobile app, and frankly, the experience has been nothing short of amazing.
After years and years of using Cordova and struggling with it (native code being akin to dark magic) I used capacitor on a project a few months ago and I absolutely love it. I've written a good bit of native code (iOS and Android, swift/java) and it's been a breeze. Also the shift to commit your iOS/Android projects saves a ton of headaches vs something like Cordova that regenerates that for things like CI builds.
Capacitor creator here, really appreciate the kind words! The article indeed is missing some critical projects in this space. In fact, Cordova is still more widely used than both Flutter or React Native when you count production app store apps. Capacitor is focused on improving that web native/hybrid stack and it turns out that a lot of people love that approach just wanted the DX to be better (which is is today!)
SO questions by month doesn't mean it's more popular.

Whenever I search for something in React Native it's already answered in the past or has a regular React equivalent answered so I don't need to ask a new question.

Since Flutter is newer and uses a less popular language there's many more questions about Flutter. This is totally expected.

Call me tinfoil but I believe SO is really financially supported directly or indirectly to support Flutter over React Native.

> Call me tinfoil but I believe SO is really financially supported directly or indirectly to support Flutter over React Native

Could you elaborate on this one?

People at SO are definitely smart and that blog post seems a bit skewed. Almost all the good sides they praise Flutter can be equally or better applied to RN too.

I try to "reverse engineer" it and think "what would have caused these very smart people to write such a lame blog post that doesn't reflect reality" and that leads me to this conclusion.

Again, I just said I believe in this. Maybe I am wrong.

In my experience, the majority of engineers evangelize the tech stack they use, even when this makes no sense. Hence => Flame Wars ;)
Many do, including me.

But I really try to be realistic and frankly can't see Flutter being truly more popular.

But just because I favor React Native over Flutter doesn't necessarily mean that I'm biased and there's no truth in what I'm saying.

>Since Flutter is newer and uses a less popular language there's many more questions about Flutter. This is totally expected.

It's more complicated than your proposed cause & effect. A counterexample is that Rust is much newer than C++ and yet C++ still has higher volume of questions using Stackoverflow's trending tool:

https://insights.stackoverflow.com/trends?tags=rust%2Cc%2B%2...

This matches real world observation that C++ is still more popular and widely used than Rust.

I don't have the raw data but I'm guessing that even if Stackoverflow compared Flutter-vs-ReactNative # search queries instead of # of questions, Flutter would still have a higher count.

Another article highlighting Google Trends[1] shows that Flutter surpassed React Native around 2020: https://www.nomtek.com/blog/flutter-vs-react-native

[1] https://trends.google.com/trends/explore?date=2018-01-02%202...

Another metric could be activity on their respective subreddits. Here is subscriber count:

Flutter: 87K, Initial Release: Mar-2015

React native 88K, Initial Release: May-2017

I think growth rate of Flutter is higher than React.

I think you got date incorrect?
Yeah it should be reverse and now I can't edit it.
Sorry, the two year lead that Flutter has, and still being close to React Native in terms of subscribers implies React Native was picked up quicker or is more popular.

However, I do agree that RN has the momentum and familiarity of React as tailwinds.

The dates are reverse. React is older than Flutter.
It's normal that Flutter is growing faster than React Native.

It's newer, has a less-known language, learning React Native is very easy for existing React developers so less searches for how-tos.

It still doesn't reflect reality.

It's not just that: of all the questions that might come up during development of an app built on react native, a big chunk won't be related to react native at all. Those questions won't be counted for react native in that metric. Flutter on the other hand is on the very far end of the batteries included spectrum, every question that might come up is tightly related to the fact that it's in the context of a flutter app.
> Call me tinfoil but I believe SO is really financially supported directly or indirectly to support Flutter over React Native.

Thank you for bringing up a very good point. There's definitely manipulation going on. I've never used Flutter, but this blogpost doesn't reflect the impresion I get on HN regarding Flutter or even Google in general.

Good lord, another Flutter ad disguised as an article.

Dear Google, we will choose your framework if we want to learn your language before you cancel it and your bloated locked in framework that emulates native decently for now and sucks on web.

I much prefer React Native and from my perspective it's winning out by far, especially with react-native-web. The entire stack is flexible and extensible.

>Dear Google, we will choose your framework if we want to learn your language before

This is why I left dart ecosystem last year, thanks Google. At the beginning or 2020 Googlers promised full support of AngularDart, saying that they have a lot of internal websites developed in it and adwords is in AngularDart, they were fully committed to making it a competitor to angular and typescript. I discussed it on one meetup and met a technical startup founder that decided to go this way, one language for web, android and iOS. A year later AngularDart was soooo outdated that it was impossible to use cross platform. AngularDart team didn't even bother with a proper announcement or giving us notice. They updated wiki on github saying that it won't be supported. I have no trust in Google giving us anything good.

> especially with react-native-web

I've seen this but never heard of anyone using it. Do you have any notable examples of serious production apps shipped with this?

I use it in production for a complex app that has tens of thousands of users hit it a day, and it's used by at least Twitter, Flipkart, Uber, and Major League Soccer.

It's a really nice React library, I go to it even for web only apps. The CSS-in-JS engine meets all the expected performance features like atomic css.

Do you have any notable examples of a Flutter web app being used in production? I assume not because of accessibility isn't ready, along with the many other issues.

Never used Flutter, no plans to use Flutter, likely would never rely on anything by Google in this space if I could help it. Not sure why you're asking me about it, unless you think my question about this v0 library is somehow a defense of Flutter, which it's not.
There's no ulterior motive, I asked because we're commenting on an article/ad about Flutter.

You posed the question if there were any notable examples of RNW used in production because you haven't seen any. (it's on their home page)

I answered who is using it and simply posed the question if there were notable examples of Flutter Web used in production because I haven't.

If you knew enough about RNW to look out for sites using it and pose a question about it then I assumed you knew enough about Flutter to do the same?

> If you knew enough about RNW to look out for sites using it and pose a question about it then I assumed you knew enough about Flutter to do the same?

That it exists, it's general purpose, and given it's semantic version that it's pre-release software. That's all I know about it. I know a little more about Flutter since it has a marketing budget.

It probably wouldn't be wise to rely on either of them outside of hobby projects. Unless of course you are Facebook/Twitter/Google, aka have effectively unlimited budget and employ the people who wrote the stuff to begin with.

> I know a little more about Flutter

That's why I asked. You asked about RNW because you hadn't heard of anyone using it, I asked about Flutter because I haven't used it and don't know anyone who does.

> It probably wouldn't be wise to rely on either of them outside of hobby projects. Unless of course you are Facebook/Twitter/Google

I rely on RNW and RN everyday for a production app (iOS/Android/Web) with thousands of DAU. I developed and maintain the app solely.

(disclaimer: I work on Flutter Web)

Curious what's not working in Flutter's accessibility. We are aware of multiple bugs, some specific to a particular assistive tech not interpreting our ARIA attributes that we need to work around, but our accessibility support is rarely described as not ready.

"According to Stack Overflow" nobody uses Quora or any other question/answer site or scheme. I'm not saying SO is unreliable, only that it's one source which could be rather skewed.
Flutter suffers on iOS because it completely takes over the render surface (ie. it renders everything using Skia), and doesn't offer any escape hatches for native components. In a way, this is an amazing approach: it completely sidesteps a lot of the platform-specific woes that plague React Native, and makes it much easier to support completely new platforms (ie. if you can get Skia to run on it, it can probably run Flutter).

But particularly on iOS, the native components have some incredibly subtle behavior (eg. the "fling" gestures from UIPageViewController, the native modal animations, overscroll, etc.), and these are extremely difficult to get right.

React Native's story for native inter-op has recently become miles better with JSI, which allows native<->JS FFI at much better performance than the previous approach. This has enabled libraries like Reanimated 2 (https://www.reanimated2.com/) and Gesture Handler 2, which take full advantage of this and get React Native apps tantalizingly close to "truly native"-feeling.

Thank you for taking the time to write that.

I was gonna say, “look, Flutter looks like peering at a screen through a fishbowl, responds like your hands are in some kind of jelly glove, and feels like you’re two martinis into happy hour,” but technical responses are of course better appreciated with this crowd.

Last year I was looking at using Flutter for something that needed extensive use of a WebView, I very quickly came to the conclusion that they are having massive difficulty to get it working well due to the Flutter architecture. It looks like the situation has improved but just look at the web_view issues, there are a lot of them:

https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3A...

A lot of apps end up using at least one if not a lot of web views, I probably wouldn't use Flutter because of it.

If you can control the HTML, https://pub.dev/packages/flutter_html works pretty good.
That does look good if you have control and its somewhat simple html.

The particular use case I was looking at was integrating a web based rich text editor based on contenteditable. It had to be a proper webview, and the issue is that the interaction with the text (cursors/selection/typing/onscreen keyboard) was completely broken.

A few years ago I would have agreed that the native subtleties must be a top priority for user experience, but these days I don't think it matters that much anymore.

Flutter's UI can't match native components exactly, but they do a very good job, and I don't think the vast majority of users would be able to notice the difference or cares that much.

The reality is, the native UI homogeneity is long dead anyway. Every app, website, brings it's own set of UI components and styling. It's all inconsistent and people are used to it.

It really does not matter whether your modal dialog is native or not, as long as it follows basic abstract UX conventions of looks and behavior.

> I don't think the vast majority of users would be able to notice the difference or cares that much.

Users do notice these things. They just can't explain it in technical terms like "i feel like this app is built with a non-native toolkit that is why animations are wrong".

They explain it as "this feels off" and "why doesn't it run like X" and "I don't like it" etc.

Exactly this. For example when I started playing Wordle the first time, I was like what is this keyboard this just feels kind of odd!
I think long-time users of Apple's various platforms will notice, especially. I bought my first Performa back in 1996. That old OS -- especially up against Windows 95/2000/XP apps -- conditioned people to be UI snobs. If I download an app from the App Store, and something rubs me the wrong way within the first few seconds, I will almost always ditch it. I want a native experience, and I don't think I'm alone.
It boggles my mind that anyone invests precious time and effort chasing such a fickle group of users. Anything less than Apple's vision of perfection and harmony or you'll be dumped in a heartbeat. "Think Different" indeed.
The people willing to put up with mediocre and bad software aren't willing to spend money on it either. Just look at the revenue gap between iOS and Android. It makes sense that people put time and effort into pursuing the fickle users willing to pay money.
> It boggles my mind that anyone invests precious time and effort chasing such a fickle group of users

This "fickle group of users" is eager to spend money, moreso than other groups of users.

It's not "fickle" to want competently built apps made by developers who respect their users.
Or, you know, developers could be thoughtful enough to create a half decent UX. That's not asking for a lot.

I'm happy a significant portion of consumers have been trained to expect better than the bare minimum in terms of UX.

Look how loyal those users are. If you can keep them long enough... they may develop their own loyalty to you.

Also they're rich.

If you've been around that long, you know that Apple changes their UI guidelines sometimes and not always for the better. I no longer know what a "native experience" is supposed to be. (I haven't even used Monterey yet.)
Yup, the downfall of Apple's UI is obvious, public, and heat-breaking.
This is valid criticism. Apple's taste isn't what it used to be.
And then Kai's Power Tools came along with its completely unique UI and everyone loved it. And other developers decided to emulate that idea - that a funky UI is a differentiator.
I don't think it's fair to blanket blame Flutter though. What you are noticing are poorly made apps. What you are not noticing are well made Flutter apps, that are almost indistinguishable from native apps. I guarantee you we all interact with way more different UI frameworks then we are aware of on a daily basis.

Some apps also fail by trying to emulating native UI so hard, when it would be better advised to just adopt a more abstract style. Today's flat UI is just simple shapes after all.

From technical a standpoint, Flutter definitely is performant, capable of delivering smooth scrolling and 60 fps. Your experience may vary of course, but I've been shipping an app with it for 2 years now and things been working out well. Can only really say great things about it.

> What you are not noticing are well made Flutter apps, that are almost indistinguishable from native apps. I guarantee you we all interact with way more different UI frameworks then we are aware of on a daily basis.

That is, indeed true. So the question becomes: does the framework nudge you towards and help you with making well-made apps almost indistinguishable from native apps, or the opposite :)

I'd wager these sentiments have more to do with performance/responsiveness than they do with whether or not UI elements and animations are system defaults. Pretty much every wildly popular application in the market has a totally custom UI.
Native UI parity went extinct because platforms kept changing UI guidelines in every major release to keep things feeling "fresh" and new. A native app might inherit a lot from the toolkit but it'll still look weird without an update.

At some point, you're better just doing your own thing rather than be dragged around on the leash of some product manager looking to make a splash at the next conference.

I develop with React Native in my day job and I'm observing all the UI changes that are happening in the systems. So far there aren't many problems with the differences, for example in the alpha version of Android 12, Google introduced a sparkly ripple effect (they eventually removed it again). But this change was automatically propagated to all our interactive components of our React Native app, no changes to our codebase necessary. And this is the case for many other changes, since React Native uses actual native elements.
I kind of disagree. I don't mind apps that bring their own visual styling and don't reuse OS components/styling, but I get _really_ annoyed by apps where gestures behave slightly differently. Things such as the exact tolerances required to activate the "fling" getsure, or to swipe from the edge, are really frustrating when they're not quite right. Beyond basic conventions, the minute details of how the user input/output responses work are really really important.
I hate when apps implement the swipe-back gesture for anywhere on the screen, rather than just the left edge.

It’s far too easy to be scrolling, accidentally go slightly too horizontal and end up popping the view and losing your place.

I hate it when swipe is inconsistent. Even using two Microsoft products (Todo and Outlook) on my iPhone, in Outlook you swipe right to delete a message from the list, in Todo you swipe left to delete a task from the list :-/ . Lucky "undo" is easy to find.
No. I'm a hardcore iOS user and i can recite off-hand specific apps that run "wrong" and why i hate using them (because if their UI). I tend to actively minimize using them when possible too. If your app doesn't support the "scroll to top" gesture when i tap the top bevel of my screen, i will stop using it if i can find alternatives.

Yes, i know that it runs wrong because its ReactNative and not SwiftUI, but you don't need to know why its wrong to know its wrong.

Eg: Alexa App doesn't go back a frame when you swipe from left, you have to click back button.

In the React Native app I'm working on, I actually noticed this gesture on an iOS simulator (I didn't know about it before) and it worked well. React Native uses native components to render the UI, but it uses JS for the logic of what and where should it put the native components. I think this might be an issue in Flutter though.
> it completely sidesteps a lot of the platform-specific woes

This is the key point where Flutter wins over both React Native but also the native Android and iOS toolkits. When you design a screen in Flutter, it will behave as you expect on every different version of Android and iOS. You just check it does the right thing as screen size changes (which is usually pretty easy to implement, and very easy to test) and then you get predictable behaviour. It is so rare that you need to fix X screen on Y phone running X version of the OS because it has odd behaviour, and that happens all the time with any of the native toolkits.

That said - I haven't used Swift UI, so it's possible the situation has improved (although I wouldn't bet on it).

SwiftUI is still incomplete IMO. It has perf issues and bugs still. Needs a few more years or to stop wrapping UIKit.
My former firm put a lot of effort into Flutter as a preferred alternative to RN or native app dev -- including standing up a lot of onshore/nearshore/offshore experience -- but we never were able to to make it a viable alternative on anything other than small or trivial apps, due generally to performance problems, weird iOS corner cases, hard-to-debug crashes arising from deep within the framework, and sharp edges on their emulated components. From a governance perspective, we ran into difficulty rapidly spinning up new dev capacity relative to RN (where you can have a web developer productive within a few days, as long as they've got a mobile dev running their pod to oversee integration and build). I'd love to see Flutter become a strong alternative, but I'm not sure Google is willing to drop enough of its NIH syndrome to meet developers where they are, rather than where they want devs to be; until then, it's a tech to push further out on the radar until it's more battle-tested, especially on iOS.
While Flutter and RN might be improving in many ways, it feels like the risk/reward tradeoff is actually getting worse for using a unified app layer. The underlying platforms getting easier to use themselves (Kotlin, Swift, SwiftUI, Jetback, etc) and the developer market getting stronger skill-wise at developer apps. There is more of a consolidation of best practices etc. The reward for building a single codebase becomes very low, but the risk is remaining high. You are adding a layer of indirection and dependency right in the middle of the platform. You basically cannot evolve at the speed of the platform. Sometimes platforms move fast and you want to capitalize on change. This always made it seem like non-starter for me.
there are developers who are just happy to write the same logic in multiple languages, and there are those who find it extremely mind-boggling, this is regardless of how nice/easy to learn those languages are.
I can understand for combersome shared logic.
Nobody is happy to write the same logic in multiple languages. There are other ways to package logic and have it be consumable by multiple teams building native mobile apps for various platforms. If you are trying to solve this by very specific problem by adopting something like React Native or Flutter then I would question many other things beyond this.
> There are other ways to package logic and have it be consumable by multiple team

Really what way? Make a backend endpoint? Convert to C++ and invoke as native code? I'm only speaking for react native it's more than sharing code it's sharing skill, a web/nodejs dev can learn it and jump on company's mobile app when needed, as opposed to have dedicated devs for Android and iOS who sit around doing nothing sometimes and stop company from shipping when they go on vacation.

> ...doesn't offer any escape hatches for native components...

Lest anyone read this the wrong way: you absolutely can embed native components in your Flutter app. They have a scheme called "platform views" that involves splitting the scene hierarchy above and below a native component, and this is used for stuff like web views or map controls that are firmly native components which people want to drop into their app.

Corona (now Solar2d) does this as well. Lua into a opengl 2d space.
I am not sure if Flutter is the most popular one.

Does React-Native have an exclusive forum, IRC channel, or Discord server?

One creator of a famous Deep Learning framework regularly blabbers on Twitter about the framework being the most popular one based on number of SO questions, where the actual most popular one has an exclusive forum for all questions.

Is that the case for React-Native? I wouldn't know.

I don't have have an answer to your question, but one major factor that one should consider when making a popularity comparison between Flutter and React Native is that _React_ part.

Most problems and questions that developers encounter while working on React Native applications are not specific to React Native, but rather React itself. As such, I find it likely that many RN developers don't always use "native" in their search terms.

I've extensively used Flutter for a messenging app. It's awesome in so many ways, but it's clearly not production ready! For example:

- Text Fields are almost unusable for iOS users that don't have predictive keyboard enabled. Reported in 2017: https://github.com/flutter/flutter/issues/12920

- Emoji rendering is broken on iOS. Reported in 2019: https://github.com/flutter/flutter/issues/28894

This is due to the fact that everything, including the OS controls, are re-implemented in Flutter.

I don't know. I have a Flutter app in production for two years now with 200k downloads and > 10k MRR.

I get consistently good reviews about performance and ux/ui.

I think it's quite ready.

I believe you but it's hard to make a reasonable comparison without knowing what your app does. I've seen some really janky Flutter apps on iOS.
(comment deleted)
It's an investment tracking app [1]. Flutter did a lot to fight jank on iOS in the past months/years and is still improving there. So far I've heard no complains from my users.

[1] https://stockevents.app

Great work, I downloaded and played around, it's a useful app and am glad it's working out for you. I may be picky as I work as an iOS developer but I definitely see the places where it doesn't look or feel native to me and unfortunately list scrolling and view transitions still stutter - I understand this is a known issue the Flutter team is working on and is out of your control. Overall probably expected and reasonable trade-offs for a cross-platform framework.
Cool, thanks a lot for the review and feedback! I think oftentimes it's hard to tell if it's a problem with the framework/SDK or your own code. I can't deny that there is a lot unoptimized code (for performance) in my app and I'm sure native iOS would be more forgiving. I guess it's 50/50 fault of my own negligence and flutter causing this jank.
I migrated from being a lifetime Android user to an iOS user a few years ago and I’m also a paid user of your app. StockEvents has never felt jankier than iOS as a whole. Is it perfect? No but iOS itself is filled with bugs and inconsistencies (just like Android). It’s definitely never felt out of place UX wise, I can’t think of any app I use regularly that uses much of the native iOS UI toolkit (except maybe the phone Settings) so I really have no specific expectations.
Hey, thanks a lot for using Stock Events and thanks for your feedback! I'm always humbled whenever I come across one of my users. Feel free to contact me through the app or otherwise if there's anything that could be improved!
These are actual issues recognised by the Flutter team themselves - you can't really hand wave them away as being standard iOS issues.
Saying Flutter and native iOS share the same issues is not the same as denying it as a Flutter issue.
I think the point was that from the perspective of the user the experience isn't any worse than a native IOS app. Your user likely doesn't know or care about the difference between a Flutter issue vs a Native IOS issue. You just don't want them to open the app and say wow this is jankier than normal, I don't trust it.
Worth noting that inconsistent jank on iOS due to the way shader compilation works is a "known issue", and that whole part of Flutter is being rewritten as part of the 2022 roadmap: https://github.com/flutter/flutter/wiki/Roadmap#jank
Yes! I'm looking forward to that update. But even before, there have always been little performance improvements here and there with every update of Flutter.
I'd say text inputs are notoriously hard/cumbersome to emulate/re-implement in order to match the native control behavior/functionality. I guess your app doesn't depend that critically on it? (unlike messaging app)
I will be honest. I was focusing on getting to production fast and never really bothered with the look and feel of specific inputs, so I can't really tell. And my users don't seem to care as well, since I never heard any complains from them in that category. They're just happy there is an app providing them value in this specific space.
The presentation of your app is gorgeous, but I was unable to open the try pro free page on LineageOS (no Play Services installed). I was just curious about how monetization worked. It just shows an endless spinner, tried repeatedly and waited 30+ seconds

Just curious, how much time do you think you put into it in total? App / web

Also curious how you marketed it, if at all

Thanks for downloading and reviewing! Yes, you can't buy the pro version without Play Services or the Apple equivalent right now.

I'm monetizing only through subscription. I made it part of my mission to refrain from all ads and focus on privacy as much as possible. For the next version I have removed Firebase Analytics and Crashlytics as well.

The subscription for my app is half as expensive as the one from other apps on the market. But there is a rather hard point where you kinda have to buy PRO. That's if you want to track more than 15 stocks.

I put in around 1000 hours so far.

Would you mind sharing the iOS/Android breakdown? The claim was it doesn't work as well on iOS.
Sure!

Android 70% of the downloads and 60% of the revenue

iOS 30% of the downloads and 40% of the revenue

Generally, there are a lot more Android users outside of the US.

Interesting. I think the conversion rate is (industry-wide) higher on Apple than Android, but you seem to have aimed at people who have money (literally) as your target audience, so I'm guessing that helps even out the converters. But also, you don't offer an ad-based option, so any tendency among Android users to lean towards ad-based software is likely overcome.

Thanks.

Our experience has been similarly good. 750k monthly active users between iOS (29%), Android (60%) and web (11%). Supporting low spec Android devices has proven to be a much nicer experience for us using flutter.
Curious what yours and daves apps are! Could you link?
Are you using flutter for the web, how is your experience with its performance
It must largerly depend on the use case. Games, for example, might not need to deal with text input at all. A chat application on the other hand, might be more difficult nut to crack if the text controls do not work well.
That seems like a huge exaggeration of the severity of those issues:

> Text Fields are almost unusable for iOS users that don't have predictive keyboard enabled.

"Almost unusable" sounds like you can't type, but really it is just missing the autocorrect popups. And if you check the comments, somebody provides an implementation that does show them.

> Emoji rendering is broken on iOS.

This makes it sound like it doesn't show emojis, but really they're just slightly too small.

Agreed. I was thinking that we must have completely missed something (working with flutter right now) to not be aware of those bugs, but looking at them they are minor and have a solution in the issue threads. These are in no way blockers for getting apps done that users can like.
I agree the emoji issue is a little overblown, but I think "almost unusable" could be appropriate.

On a phone, the synergy of autocorrect and fat fingers is a delicate one, and even small changes can really upset the typing experience.

Samsung once updated the keyboard on my phone, and the different visual cues and behaviour completely threw off my muscle memory and made typing very difficult.

Even the autocorrect mode being wrong on an email input can be annoying, so a whole app acting up would be even more unpleasant.

Saying "it is just missing the autocorrect popups" is misleading. The problem with not providing the autocorrect popups is that you _can't cancel an incorrect autocorrect_. That would 100% infuriate me.
I tried Dart when I heard Notch was spending his time with it several years ago. Then I found a Lisp implemented in Dart in 2016, which has been updated [1]. I think in hindsight, if Google had kept supporting Dart, it would have been invigorated by the Flutter wave. I am looking to use Flutter for an app, but the iOS lag has me concerned.
Flutter is DOA, IMO.

It has two fundamental mistakes, each of which is probably fatal.

(1) non-native controls. The problem is it takes a lot of work to catch up and keep up with native controls. This is a cross-platform SDK, so multiply that by all the platforms. You end up doing a massive amount of work to achieve a lowest-common-denominator, janky, low-quality experience.

(2) custom language. There's a lot of unnecessary friction here.

Maybe Google will keep paying for it anyway... but I doubt it.

Dart is particularly bad. I tried to enjoy using it but I just cannot. I don't understand why they didn't choose Typescript.

It felt like they couldn't use it for anything else so it was mandated that people use it somewhere.

This is really some armchair psychoanalysis on my part, totally not worth anything in the way of intellectual attention, but I always found this interview with both Typescript and Dart leads to be interesting. https://youtu.be/5AqbCQuK0gM

I can't help but infer that Lars is quite often a little bit frustrated with the emergence of Typescript. But on top of it being embarrassing for me to imagine up such personal rivalries based on hardly anything, you could view the interview as Dart-hostile given the interviewer.

Dart predates Typescript by a year, so you can turn your question to why didn't Microsoft use Dart instead of creating Typescript :p
They didn't use JavaScript / TypeScript because of AOT requirements on iOS (Flutter actually was originally prototyped with JS as the language). Dart was mostly chosen for its runtime, which allows both Hot reload at dev time, as well as full AOT compilation to get native speed on iOS. React Native runs a JS interpreter to get around this on iOS and as a result is an order of magnitude+ slower
The speed is fixable. Performant AOT is very possible with Typescript. But if Facebook is not doing it, then the performance is good enough for them. Plus one can always code the problematic part in the native language.
I am merely reporting why they made that decision years ago, I don't know what to tell you
Huh, which AOT compilers for JavaScript exist which achieve high performance? I thought JS as a language 100% depended on the runtime information available to a JIT for decent performance?
fpoling is referring to a _theoretical_ TypeScript compiler that doesn't actually exist in real life but could be written, that the Flutter team would apparently summon from the aether whole-cloth then proceed to maintain feature-for-feature parity with the official TypeScript compiler
Well, you wouldn't have to maintain feature parity with Microsoft's TS compiler. If you had some magical ES5 AOT compiler, you could just compile your TS to ES5 using the official TS compiler and then AOT-compile your ES5. No evolving spec to keep up with (at least as long as the upstream TS compiler maintains ES5 support). I'm really just curious about how one would AOT-compile a language as dynamic as JavaScript (be it TypeScript, ES3, ES5, or anything else) and achieve JIT-like performance.
Right, but then you miss out on the advantages of type-driven compilation. It would be hard to compete with Dart's AOT without that.
Because TypeScript's type system is (by design and for good reason) unsound, an AOT compiler can't rely on static types to generate smaller more efficient code. It's always very hard to compile a dynamically typed language to fast code than it is a statically typed language.

Dart (as of 2.0) has a sound static type system. It's just an easier language compile well.

Dart didn't have sound static type system when Flutter was created.
Even before that, Dart was easier to compile efficiently than JavaScript because classes are purely declarative and all objects have a fixed field layout.
Just to give a counterpoint to this, I love Dart. My preferred language is Ruby and Dart certainly is not Ruby. But it also makes me a bit happy when writing it: It's easy to understand and clean enough. The typing system is done well enough that it does not get in the way as much as early Java did. There were very few surprises with Dart. It has limitations (especially when trying to incorporate more functional patterns and felt when working with JSON), but I can work with that. Most of the time I can just write the code I want, organize it as I want and the Code will look as expected. No blockers there.

Typescript would not have been a plus for me.

It has been a pretty big arrival and huge bang to kill Flutter judging by your assessment, because when Flutter first started to be developed it was a pretty big success regarding what it delivered ( and promised to deliver ) even if it clearly wasn't ready for "production" ( this is 5-6 years ago ) and by initial success I mean people cheering and paying close attention to it.

Now it's clearly a success because the alternative is Phonegap and all it's offspring ( ReactNative kinda included ). It's compelling enough for people to learn a different approach to UI building ( new for most people coming from Web ).

There always be a "lowest-common-denominator", but with Flutter and for most types of app it's a pretty high denominator.

Another thing that doesn't get mentioned is React Native is much easier to staff talent for. Flutter can be better than RN in every single way and companies will still choose RN because it's easier to integrate into the org.

If you have a webapp built in React, it's going to be very easy for you to spin up a React Native app, mostly because you can pull those React devs into RN without much of a fuss. With Flutter/Dart though, you will have to hire outside specifically for the role, even if you hire a "React Native" developer, it will be easy to transition that dev to regular React if org needs change, Flutter/Dart are more brittle in that way.

(1) is essential to flutter's success, otherwise each new release of every new system would break something and introduce bugs.

Flutter will never provide native feel and that's not the point.

I'd potentially use it when starting a new cross-platform project but the biggest psychological blocker for me is that it's.. Google. How can I be confident that it's still around in a year? Two years? Five years? Will it survive (and thrive!) on its own in case Google decides to pull the plug?
It’s a common question. It is used by them internally for important projects. So is guaranteed at least maintenance work for the long term.
This reads more like a commercial than an article.
Every few years, I see "Why <sexy platform of the day> is the most popular cross-platform mobile framework", then after a few years, it's out of the spotlight. I don't see Flutter being different.
The obsession with the concept of a "one true cross platform toolkit" even just for mobile is wrong, it will never happen.

They all have their strengths and weaknesses, you should always chose one where the strengths align with your app and your team. I see it something like this (of the ones I know enough about):

Flutter - Brilliant for somewhat simple apps talking to an api that don't need to share any ui with the web. Sonos is a brilliant example. Banking/Utilities, Smart Home, Restaurant/Takeaway (I think here in UK the Pizza Express app is Flutter). Things that need a "flashy" but consistent ui. In many ways I see Flutter as the new Adobe Flex/Flash.

React Native - Brilliant where you need a more native feel or need to drop to native more regularly. Good WebView support if you need them, mixing web and native views together. Also good to extend native apps. Facebook and other social media apps are a good example.

Ionic/Capacitor (or the older PhoneGap/Cordova) - You have a small team and need to get a fully cross platform app (web/mobile/pwa/desktop) done quick. If you are just calling a few HTTP apis (a CRUD app) and rendering some screens you can't be more productive than with this platform, particularly if sharing views with the web. Brilliant for enterprise, or internal apps. Good examples are the UK NHS apps. Performance on any mobile hardware less than 5yo is better than good. I have used NativeScript with Capacitor, they work very well together when you need to access native functionality not available with the standard capacitor apis.

(I don't know enough about Kotlin and its cross platform tools)

Flutter Web exists and works reasonably well.
True, although if you are trying to build a cross platform app where the web is a major part of it, I wouldn't even look at the Flutter and default to Capacitor.
>Reasonably well

Rendering to a canvas does not "work reasonably well", unless you want to go back to Flash days (but controlled by google this time)

Therein lies the future, thanks WebAssembly.

Blazor, Uno, Qt, Yew, Flutter,....

Although WASM is brilliant, I don't think its right to use it to recreate the whole UI drawn to canvas. You loose all accessibility integration with the OS either locking out users or making your life much harder reimplementing it. WASM is perfect for graphics and backend processing, see Figma it uses WASM for drawing the canvas but the rest of the ui is native web with all the accessibility tools that come with the browser/os.
My life was made much harder when Flash and Silverlight like tooling was taken away.

The craziness of faking UIs with paragraph tags massaged via CSS and JavaScript into a drop down menu.

Now they are back, even Google Docs is moving into it.

That's a philosophical issue, not a functionality one: something can work reasonably well even if you hate the world that results.

(And I sadly just can't buy the philosophical issue anyway, frankly: if anything, I'd argue the biggest flaw with the web is it has a million nit-picky features when it should ONLY offer JavaScript+canvas, as third parties have a hope of reimplementing that correctly, unlike HTML+CSS. To the extent to which there were important behaviors people liked, such as accessibility, those should come from higher-level frameworks instead of being baked into the lowest level of the system.)

accessibility is not a behavior that "people liked". It is enshrined in law in so many countries that they _have_ to be at the lowest level of the system.
I would argue it was enshrined in law because people liked it so much they demanded it, so maybe that's a semantics issue? That said, I do not believe the law insists that it be in the lowest level: the law merely insists that it exist for every site. It is convenient to put it at the lowest level if possible, but now it is just one more thing that literally every browser has to implement from scratch, and so the world that results is that the only company capable of making a good web browser is Google. There are sane reasons why accessibility is not considered part of a CPU (and thereby by most other reasonable runtime engines).
People with reading disabilities, vision issues, etc are rarely the ones being heavily represented in parliaments. Accessibility is truly a case of things being earned through spilled blood, and while there's probably much fewer people dying because they can't read the text on your website, it's a natural extension of the physical world. While the laws do not say that it should be up to the browser, it becomes natural that this moves to the lowest common denominator. Should it not be part of browsers, the moment any dominant browser comes in (say, Chrome) and implements it would lead to thousands of websites relying on this behavior from the browser, leading to "Works only on Chrome" situations, and other browsers most likely rushing behind to also support that feature.
> I'd argue the biggest flaw with the web is it has a million nit-picky features when it should ONLY offer JavaScript+canvas

That would break the web, though? One of the biggest _strengths_ of the web is backwards compatibility.. I, for one, am grateful to use modern browsers to consume older content and apps.

This is a "the web made a fatal mistake in the past and should have done X" argument and not a "the web should now do X" argument, though if you want a forward-looking suggestion we need to immediately stop adding NEW behaviors.
This is a strange position considering I would rank the JavaScript engine as, bar none, the most complex and difficult part of the entire browser stack to develop and keep maintained, and it continues to grow and become more and more complex along with the runtimes implementing it, which were already incredibly complex by design.

> behaviors people liked, such as accessibility

lol

I don't disagree--though I know people, including myself, who have managed to pull off either all of or most of the work required alone--and so in an argument about the JavaScript engine I would argue it should be a VM only, such as WebAssembly.

(As for accessibility, I appreciate you might find my wording funny, but it isn't a laughing matter really.)

No, it doesn't. Try dealing with accessibility, emoji, screen readers, non-English languages. The people in charge left all of that "TBD" and now they've backed themselves into on unsolvable corner with their "render everything to a canvas". They didn't understand what they were dong. The web apps feel like Swing in Java.

Type some CJK in here and watch as each letter appears 500ms late, or try to bring up the emoji input on MacOS

https://flutter.github.io/samples/web/form_app/#/form_widget...

If by reasonably well you mean barely hits 20 fps on Desktop and unusable on mobile then sure, it works reasonably well.
What's the weakness to React Native?

From my experience anything you could have done natively you can bridge to RN.

So either create a native app if you have resources, otherwise, create a RN app and use either custom or community extensions.

That's the beauty of the flexibility and extensibility of React.

React Native Web works so well I use it as my main for even web-only projects.

You basically get a mobile and desktop site for free with your app. Or native apps for free, whichever way you look at it.

> What's the weakness to React Native?

Non web-devs seeing the word "JavaScript" and running away. Or stated otherwise, having to learn React + the JS ecosystem (minimized within RN) on top of all the mobile specific stuff.

Pretty good point, haven't thought that way since I was a Web dev, then React dev, so transition to RN/W was easy.

I had no previous experience with Android or iOS or the languages and was able to get caught up, but there was a curve to figuring out code signing, the app stores, deploying, permissions, etc.

For those non web-devs, they will have to learn some of web. You will need to learn the tooling like the other platforms. You don't really need CSS knowledge or HTML just basics. RNW implements RN stylesheets which is a streamlined subset of CSS.

The main thing is learning React, but SwiftUI was inspired by React so it should be easy for at least iOS devs to grasp it.

Xamarin?
+1

Xamarin is very popular in enterprise

For some reason NativeScript is never mentioned on HN.
NativeScript looks interesting and would be where I reached if React/RN TypeScript wasn't my preference.

React Native has a much larger ecosystem and feature set, including desktop & web targets, native view, many extensions, huge support, a lot of jobs.

NativeScript seems to just tie into native APIs, not the view layer, right? React Native bridges to native controls so you get native look and feel.

Flutter emulates the native view later by drawing everything itself which can be off, but it's performant at least.

If I preferred Web components, Svelte, Angular, or Vue I'd see the appeal of NativeScript.

React Native is based on NativeScript – which provides the JS layer and access to native APIs RN needs.
After looking into it, NativeScript does use native UI controls, not webviews.

React Native is not based on NativeScript though, they are two different implementations.

+1 for Ionic. I have been able to scale complex B2B and B2C software apps (not games) very well with it. v1 to v2 was rough but since v3 its been great. I'd strongly recommend this to anyone who wants web and mobile apps with one codebase.
I recently blogged about a comparative evaluation of the three technologies you identified as cross platform (Flutter, React Native, Ionic) over at https://glennengstrand.info/software/architecture/ionic/reac... by implementing a feature identical PoC app in each tech stack.

The value of cross platform toolkits is all about cost reduction. It is cheaper to staff up on a single skill set rather than to staff up on three entirely separate skill sets. As of 2022, that single skill set is most likely web SPA development.

Flutter and Dart are no where near as similar to React or Angular as Ionic or React Native. Even the most experienced web developer will need time to learn Flutter. There are also some positives to Flutter that you should consider. Of the three PoC apps, the Flutter app had the fewest lines of code and took the least amount time to develop (once you know Flutter).

  > The value of cross platform toolkits is all about cost reduction.
cost reduction rarely leads directly to product quality though...

what i want to know is, how do cross-platform tools lead to better software products (less bugs, faster iteration, higher quality features, smoother animation, higher performance etc) for customers?

We evaluated those 3 options to develop an application used to configure, control and monitor battery systems at Northvolt, and reached very similar conclusions regarding the strengths of each platform.
I think there’s a real bias in all developers toward aiming for a “good” experience in one’s chosen environment, and then declaring that as “good enough” in everything else. I certainly fall for that as a “Mac guy,” where I might build something that gets used in Windows, and it might not be as good but literally nothing in Windows is good so what’s to be done?

Many/most developers — at least in the tooling world — are Linux people, so we get these cross-platform tools based on Electron and Flutter that everyone insists are either “good” or “good enough”, and it makes me feel so bummed about the state-of-the-art, that our hardware is better than ever and we’re just throwing it away on this crap.

No, your cross-platform app is not indistinguishable from native, or good. It is probably good enough, here’s a participation ribbon.

You’re not alone, “good enough” always bums me out too. It’s why I’m a big fan of sites/services that open up their APIs or use open protocols/standards — even if the service provider has decided to settle on their client app, I personally don’t have to. I can seek out alternative client apps where workmanship is a focus or if so inclined build my own.
Though compare this to the typical Linux experience of a closed-source application (especially non-x86_64): no experience or reverse-engineered with a cease-and-desist letter after it gains any sort of traction.

Usually you wait til someone gets fed up and builds a GPL-licensed clone.

Best line in the whole thread, "No, your cross-platform app is not indistinguishable from native, or good. It is probably good enough, here’s a participation ribbon." Nice!!!
Flutter is great!

I'm working on a multi-front-end, multi-back-end UI framework called Nexus. The initial front-end will be Flutter and the initial back-end will be Nim (Python following soon).

https://nexusdev.tools

My team has been porting our mobile product over to Flutter now over the last two years, and it has been interesting seeing what can be done with it.

The reason we are moving to Flutter is the limited size of the development team (only a handfull collectively working on both platforms). In that regard, being able to share the codebase has been a massive boon to productivity.

However there are tons of issues that come with Flutter, just like any programming language and framework. Like the article mentions, the third party plugin ecosystem is nowhere near the maturity and stability that one has come to know from the Android & iOS community. Packages sometimes get left behind and not updated for ages, which causes various issues as new versions of the platform OS's come out.

Dart is also a very verbose language, and it really took a long time to get used to the noise it generates on screen. The lack of proper null safety until only recently had also been difficult for the team to get to terms with.

In our case we are also integrating Flutter along with our native code base, which opens up all kinds of other cans of worms then when just using Flutter standalone.

To me it serves a purpose, and is another tool in the toolbox. I am however much more excited for the possibilities that come with Jetbrain's new UI framework Compose.

I’ve been using flutter in anger for a cross platform web / iOS / android music app. I love it!

I see lots of Dart skeptics here. I was too when I started but Dart is great and better than JS.

I’m a Go developer by profession and Dart feels similar in ways. Simple language, simple type system, easy to learn, only one way to do things. Great compiler, great debugger, good ecosystem, good performance.

The complaints about widgets feeling off on different platforms is fair. My app is a totally custom UI so it doesn’t matter.

My favorite feature is the widget testing framework. It’s really easy to run the actual app and interact with it and verify UI interactions, UI state, app state and even UI pixels.

My frustrations are:

- cross platform system packages are of various quality and feature support. Someone in the ecosystem has to build the libraries with native bird and message passing to the flutter interface. I’m constantly surprised how much exists but when there are bugs or features missing on one platform it’s some major work to get it addressed.

- app initialization, lifecycle and navigation and routing took a long time to get right. Some more conventions on overall project structure and better getting started templates would go a long way.

The monolithic language and framework will be an advantage to some and a turn off to others. As a solo hobbyist, it’s a super power to get all these platforms at once.

> I’m a Go developer by profession and Dart feels similar in ways. Simple language, simple type system, easy to learn, only one way to do things. Great compiler, great debugger, good ecosystem, good performance.

Hm that's interesting to me. As a Go dev I just felt like "welp, I'm in Java."

I don't dislike it, but it doesn't feel nearly as light.

Another go developer here, also worked with flutter / dart. Dart felt to me like a simpler Java.
As a Java dev I felt like I was in JavaScript.
as Java/Kotlin dev I had same feeling about it, "hello Java", but when discover async/await smell some JS spirit.)
>- cross platform system packages are of various quality and feature support.

I've been working on a video call app for fun and have certainly noticed this. On the surface it appears possible to write such apps with Flutter. The reality though is that the implementation depends on half a dozen or so third party plugins with varying degrees of quality (and a small enough ecosystem to afford very little choice). Not to mention the inconsistencies with how they work across Android and iOS, although there's little which can be done there. At this point mostly everything's just adapters and other integration glue. If it ever goes beyond a hobby project I'll probably write native versions for each platform.

In anger with what? React ? ReactNative?
Used "in anger" means "professionally" or "for real" or "where working or not really matters" vs. using it for hobby projects or experimentation.
Makes little sense, even less with the following sentence.

Hopefully it doesn't catch on.

(comment deleted)
(comment deleted)
"In anger" is an idiomatic usage, meaning something like use for a non-trivial purpose. I think it comes from the military, roughly synonymous with "in combat".
(comment deleted)
I first saw it: https://ant.apache.org/ant_in_anger.html "Ant in Anger"

I've taken it to mean: You don't know it, you might not particularly want to be using it, but you have a specific requirement and a deadline.

eg: "Plumbing in Anger" I would expect to distill enough to fix a sink or install a toilet or something, and tend towards a bundle of task-focused items/outcomes, and less on the "Gestalt of Plumbing".

I also have complaints about the package manager. A language as new as Flutter shouldn't have significant dependency conflict hell as it is a solved problem. Npm/yarn, cargo, Go are all able to (in most cases) handle conflicting upstream dependencies. In other words, if package A required version 2 of C, and B requires version 1, the code can still compile without any user intervention (such as shading) barring some corner cases. This is the biggest difference between the new generation of package managers and the old pip/gem/maven type. For some reason, Dart's authors decided to use the traditional Java style package management algorithm (which in the worst case, on paper at least, requires NP time constraint solving but this is rarely an issue in practice). I have wasted days trying to get an obscure third party dependency n levels up the chain to build so the codebase can successfully compile.

I strongly suggest aspiring dependency manager authors read these

https://research.swtch.com/version-sat https://pnpm.io/faq

before building yet another broken package management solution. This is a huge problem in the Lisp community too but their problems are worse. Racket doesn't have lockfiles. Same problem with quicklisp. The alternative replacements like Racksnaps don't support conflicting versions either. As far as I know, CLPM is the only modern dependency manager in the Lisp world though it is very poorly documented, barely maintained, and installing it is difficult. If you go to the racket mailing list, nobody seems to be interested in tackling the problem or even acknowledging that it exists.

Hm... I am kind of collecting all information I can about package managers for a few months now... pub is one of the best I've seen.

Cargo/Go/npm, as you say, will try to "shade" conflicting versions, which is basically a gamble. It may or may not work at runtime because data exchanged between different nodes in the tree of dependencies may have conflicts that make them incompatible... so having module A depend on version 1 of X, while module B depends on version 2 of X, and then A and B exchange objects that depend on which version of X they use will cause issues... this will blow up at compile time in Rust, at least, if you expose X in the API of A and B... but even if you don't, it's still possible for a conflict to occur if the exchanged information is in the form of serialized data or generic collections.

Pub selects one version of each library. It has great tools like listing the currently latest versions of every dependency, or the currently updatable ones given your version constraints, it addresses Dart SDK bounds of each package and it just works greeat. Can you give an example of when it didn't work for you?

EDIT : in the Lisp world, the biggest package manager is Quicklisp[1] as far as I know... and it works decently! I think Ultralisp[2] might be somehow better because it updates indexes faster or something.

[1] https://www.quicklisp.org/beta/

[2] https://ultralisp.org/

Build a project with enough dependencies and there will always be dependency issues which you will need to fix by forking upstream. For Rust and Go the package manager can trace the codepath and identify conflicting type exports.
I unfortunately didn't keep great records at the time (probably because I was so pissed off), but my app [1] has gone through some dependency hell on more than one occasion. I've more or less stepped back from the project but the thing that sticks out to me the most is when I left the project for several months, then tried to re-clone and re-build the app to fix a bug. I ended up having to change at least a few depenencies and even send in an upstream PR to get things working (thankfully accepted quickly) before I could compile because something had somehow changed in those few months. Fixing it took a couple days of effort, which for a toy side-project almost killed it on the spot.

In my experience, Flutter is the worst cross-platform mobile development tool; except for all the others.

[1] Time Cop: https://github.com/hamaluik/timecop

> Go are all able to (in most cases) handle conflicting upstream dependencies. In other words, if package A required version 2 of C, and B requires version 1, the code can still compile without any user intervention (such as shading) barring some corner cases.

Different languages place different constraints on package management. For Go:

1. The language is structurally typed. If A gets a value from C 2.0 and passes it to B which expects a C 1.0 value, as long as the interfaces are structurally compatible, it will compile. (Whether it runs correctly is a completely open question. In principle, it won't because C is explicitly saying that 1.0 and 2.0 are incompatible. But there's nothing in the language to prevent a value from one version of C being passed to a function from the other version of C.)

Dart (like most languages) is nominally typed. If you have a class named Foo defined in two different libraries (or different versions of the "same" library), they are considered different, unrelated classes. If Dart were to allow multiple versions of the same package, then users will run into compile errors like "Expected a Foo (1.0) here but got a Foo (2.0)."

2. Code size is relatively less important for a primarily server-side language. Most Go developers don't really care how big their executable is as long as its within reason. Want to compile in five versions of some package? No big deal.

Dart is designed for client-side mobile apps, both native and compiled to JS. That means small code size is an absolutely critical performance requirement. Silently allowing multiple versions of the same package even when it's possible to find a single version that satisfies all constraints would bloat applications for no benefit.

This was historically a problem when people started trying to use the Node/NPM ecosystem in the browser. NPM freely gives you multiple versions of packages and the end result was large apps that weren't friendly to running in the browser. NPM added shared dependencies later to try to mitigate this, but now you've got two ways to manage dependencies and the extra complexity that entails.

3. Go chose to bake the major version number directly into each import in the source files. This makes imports unambiguous in the presence of multiple major versions of a package. But it means that upgrading a package to a new major version is a sweeping transitive source code change even when the new major version is in fact backwards compatible, which is the common case.

For Dart, we wanted users to be able to rev versions more easily than that and keep version management outside of source code.

> Dart's authors decided to use the traditional Java style package management algorithm (which in the worst case, on paper at least, requires NP time constraint solving but this is rarely an issue in practice).

Pub is most closely based on Bundler (which in turn informed the design of Cargo), and not Maven/Ivy/Ant. You're correct that version constraint solving is NP-complete. Fortunately, we have a state of the art solver [1] and it generally finds solutions very quickly. When it fails, it tends to fail fast and report helpful errors.

It's not perfect but there is no silver bullet for code reuse, and package management is fundamentally about code reuse. Code reuse is hard and anyone claiming they have a solution that makes it easy is most likely sweeping some unsolved part of the problem under the rug.

[1]: https://nex3.medium.com/pubgrub-2fb6470504f

> In other words, if package A required version 2 of C, and B requires version 1, the code can still compile without any user intervention (such as shading) barring some corner cases.

I never understood why you would want this to ever compile, especially as the default. There is no way to guarantee that two versions of a library loaded into the same program will work together, so of course you want the compilation/package resolution to fail if this happens.

Now, in some rare cases this may not be a problem, so it would be nice to have an escape hatch to permit this highly unusual use case, but it certainly can't be the default in any sane technology stack.

I've been using Flutter recently to build a cross-platform Notes app. I initially bemoaned that I'd have to learn Dart for it. And while I don't have a particularly high opinion of the language, it was pretty easy to pick up. It helps to just treat it like a DSL for GUI apps, and move core logic to something like Rust.

That being said, the Flutter widget model is remarkably simple to understand. And rules like "Constraints go down. Sizes go up. Parent sets position." make it pretty easy to reason about the UI. State management is a bit of a hurdle, since there are so many options, each with its own advantages and disadvantages.

All in all, this was a great choice for building something that works on both mobile and desktop, and has a fast startup time.

Wait what, a drawback is you have to learn Dart?! No - you don't have to use freakin' lame-ass javascript. That's like a giant plus.