12 ms·
Using Flutter to build a native-looking desktop app for macOS and Windows
- zorr 5y agoThis is a nice in-depth article that shows it's not impossible to create native-looking experiences using cross-platform tools. Kudos! I would like to see more content like this, promoting cross-platform tools while not forgetting native platform capabilities and guidelines. Question for the author: do you have anything to say about building/signing/publishing for both app stores? Is there any automation involved?
- whiplashoo 5y agoI wrote another relevant post, if you are interested: https://blog.whidev.com/same-features-macos-to-windows-with-flutter/ https://blog.whidev.com/same-features-macos-to-windows-with-...
- whiplashoo 5y agoThanks for the kind words! Building can be a hassle, as you can only produce the release version on the host machine. This means there is a bit of back and forth between my Windows laptop and my iMac, but it's expected. I haven't looked for an automation process for this, but I believe Codemagic are building a solution for Flutter desktop as well: https://blog.codemagic.io/codemagic-ci-cd-releases-support-for-flutter-desktop/ https://blog.codemagic.io/codemagic-ci-cd-releases-support-f...
- colinramsay 5y agoI've been doing some work with Flutter on Linux and I've been really impressed. I like Dart as a language, the VSCode support is superb, and Flutter seems well thought out. The two UI packages mentioned in this post look great too.
- rbanffy 5y agoI noticed there doesn't seem to be a `gtk_ui` module. I was saddened that they lumped me together with the Windows crowd.
- TheMatten 5y agoThere's https://pub.dev/packages/gtk https://pub.dev/packages/gtk - has limited set of widgets ATM, but may be a good start.
- mmargerum 5y agoI just can't learn yet another language. There's nothing even particularly novel in dart. Why couldn't they just use an existing language?
- csells 5y agoDart as a platform provided the unique ability to target both JIT at development-time to enable sub-second hot reload and AOT for release apps, providing native performance when it comes to scrolling, animation, etc.
- gnabgib 5y agoDart (2011), TypeScript (2012) and CoffeeScript (2009) and arguably Haxe (2005) all competed in the same space. Google made a optics mistake embedding Dart into Chrome - people feared antitrust, but it is a significantly better language to use than JavaScript.. it's disappointing how that played out. Usability wise, Dart is similar to TypeScript, in many ways better (real type safety, null safety, not being hamstrung by down compiling to JS). Dart feels closer to C# in syntax, style and language features.. TypeScript is also trying to travel that way, but syntax is different, and it's still hamstrung by JS.
- WA 5y agoThat's a great writeup. However, am I correct in understanding that the UI packages are not bindings for SwiftUI or UIKit? Would this "native" package then truly benefit from OS integration of keyboard shortcuts, accessibility settings etc.? The biggest downside of Electron (or Cordova/Capacitor for mobile apps) is not necessarily performance (as proven by VSCode), but the non-standard implementation of UI controls. For example, if I change some accessibility settings on the OS level, all UI elements in all apps implementing truly native UI components would inherit the OS-level settings. The toggle button on iOS could be set to have an I and an O for the ON and OFF state. A web-based app would not respect that setting. So, if we talk about native, the most important part is OS-level integration of the UI. I'm not sure if Flutter really is an alternative, if the only thing you get is a bit less memory consumption and a smaller download size. Please correct me if I'm wrong.
- zoontek 5y agoNo, you are right. Flutter isn't really native since it uses Skia to render native platform look-alike components (as opposed to react-native which really use the platform)
- sparsely 5y agoThe result is that everything will look and feel slightly off, as the recreation of native elements will never be quite perfect.
- amimetic 5y agoAs I’d guess most people spend most of their time in Chromium browsers and electron apps probably a case to make that ‘native’ in the sense you imply is Chromium!
- mmargerum 5y agoMore than just off. Especially on iOS there is a ton of functionality in those native controls thats going to be very hard to replicate.
- 5y ago
- slownews45 5y agoIt may not matter in this context but did the flutter team ever figure out jank on iOS especially first run? Something always seems off with that vs native. This was an old issue, but they seemed to struggle with addressing it / or it wasn't needed for their use cases.
- jamil7 5y agoIt's still an open issue I think and a difficult one to solve, even with their resources. https://github.com/flutter/flutter/issues/32170 https://github.com/flutter/flutter/issues/32170
- IceWreck 5y agoNo, theyve been struggling with it ever since Apple switched from OpenGL to Metal.
- slownews45 5y agoBummer - I'm sorry to hear that.
- square_usual 5y agoI like flutter and would definitely pick it if I had to make a mobile app, but if you have to write a conditional at every step to pick the right component for each platform, I don't see the point of keeping one codebase any more. You're writing code twice, and you have to test it twice, and each underlying implementation can have its own quirks. It can only get worse if you have to work with platform-specific layouts that mean your larger views have to be conditionals as well. I can understand the impulse to have one common codebase for the logic, but these days you can do that with many languages - like Kotlin or Rust - while using the native UI toolkits. If you're writing what is essentially two view layouts, you might as well write them in the native toolkit and skip the overhead of flutter altogether.
- hdjjhhvvhga 5y ago> and you have to test it twice Note that whatever solution you choose, you still need separate tests for every platform. Ignoring the differences between them and assuming everything is going to work the same way is a recipe for disaster.
- thom 5y agoI know modern programmers are raised to disregard design patterns because some blog said they’re dumb, but I hope nobody actually writes code like this.
- anaisbetts 5y agoYou write components at the lowest levels with the if/then, or maybe at the page level if the pages are completely different, but many of your UIs are going to share the same code.
- moring 5y agoI think you would end up writing applications that look native, but not behave in a native way at all. We have a lot of those already. Just some thoughts: - for an application that modifies files (e.g. a text editor), are changes applied to the file immediately or is there a separate "save" action? Platforms differ on this. Basically your internal data handling becomes platform-dependent. - define a set of keyboard shortcuts that is consistent and intuitive, but plays well with the platform's shortcuts. You'll basically define a separate set of shortcuts per platform. - whenever functionality overlaps with existing native applications, cooperate with them instead of duplicating their functionality (especially in an incompatible way)
- dt2m 5y agoThere's a big difference between native-looking and native-feeling.
- flohofwoe 5y agoMaybe a stupid question for Flutter users, but why are there two versions for every UI element in the source code? I'd expect that I initialize the theme once at application startup, and then the widget and layout engine works in "Windows" or "macOS" mode (or whatever else the theme decides to implement). What's the point of using a cross-platform UI framework if I need to duplicate the code for each platform?
- rbanffy 5y agoIt makes sense if you have significant code that's not UI-related. IIRC, Photoshop is implemented this way - there is little code reuse at the UI side, but the bulk of the program is platform neutral. I had Photoshop (2.5) running on IRIX on my desktop for some (very fun) time.
- mstade 5y agoI too had Photoshop running on IRIX way back when. As a matter of fact, it saved my butt on a job where I had a massive file for a poster design, and it would keep crashing on my PC whereas on the O2 with an older version of photoshop it just chugged along slowly but surely. It was an exercise in patience, for sure, but it also ensured I could deliver on the job and ultimately get paid! Man those were the days...
- tyingq 5y agoThe peer widgets seem to have many differing properties. Compare the two AlertDialog widgets. You'll see they are very similar, but not at all the same: https://api.flutter.dev/flutter/material/AlertDialog-class.html https://api.flutter.dev/flutter/material/AlertDialog-class.h... https://api.flutter.dev/flutter/cupertino/CupertinoAlertDialog-class.html https://api.flutter.dev/flutter/cupertino/CupertinoAlertDial... My guess is there were enough widgets with enough differences in behavior or features that they abandoned a theming approach.
- dgellow 5y ago> What's the point of using a cross-platform UI framework if I need to duplicate the code for each platform? You still use the same development tools, reuse your business logic, and reuse generic components/widgets. You still need to account for the fact that users from different platforms expect different interfaces, but the common bits can be reused.
- wiradikusuma 5y agoIn case you're wondering why 2 separate widget sets, it's only needed if you want to follow each platform's look and feel. If you don't care, or if your app has its own L&F (e.g like Spotify app), you only need 1 widget sets (which you can adjust the theme). As others have pointed out in the comments, Flutter is drawn like a game engine, as in everything is drawn on a canvas, so at the end of the day it's just drawings, not native widgets.
- dgellow 5y ago> Flutter is drawn like a game engine, as in everything is drawn on a canvas, so at the end of the day it's just drawings, not native widgets. How well does that work with accessibility features from the different operating systems? I never used Flutter or an application written with it, I just remember the horrible experience of using Gimp and Inkscape on macOS, and the lack of support for native accessibility features can be a pain.
- timsneath 5y agoFlutter has comprehensive a11y support: https://flutter.dev/docs/development/accessibility-and-localization/accessibility https://flutter.dev/docs/development/accessibility-and-local... There's ongoing work on the Windows implementation here, which is tracked in https://github.com/flutter/flutter/projects/209 https://github.com/flutter/flutter/projects/209, but this is supported on macOS, Linux, phone and web platforms.
- Toutouxc 5y agoI appreciate the time and knowledge that went into this, but I feel like I need to say that when the time comes I am absolutely going to start avoiding Flutter-based "native" apps just like I'm currently avoiding Electron based ones. I don't like what they're doing and I won't be willing to spend any money on them.
- eloisius 5y agoSame. I know I'm probably just being a grouchy crank, but I wish there was a "Awesome Not Electron" list featuring only true native apps. I've recently migrated back to Linux after 10 years full-time on Mac. I am often looking for an open source replacement for something, e.g. Apple Notes. I cannot believe how many "native" note-taking apps there are and how few of them aren't a shell wrapping a web app. At this point whenever I'm considering adopting a piece of software, I first check if they have a "native" app for all three major platforms (sometimes plus web), and if they do, I take a peak at the git repo. If it's mostly written in JS, I assume it's an electron app and de-prioritize it on the list of options.
- d3nj4l 5y agoAlmost all cross-platform apps that are available on linux these days are electron, so that makes it tough to do what you say. I tried it myself - I can't stand apps taking up resources in the background disproportionate to what they're worth - and had to go back on it pretty quick. It's either cross platform electron apps or linux-first native apps.
- eloisius 5y agoYep. I've been learning the same lesson. I'm actually rediscovering all the things I loved and hated about Linux 10-15 years ago when I was on Ubuntu full time. The janky, unpolished, hodge-podge look and feel, but super snappy and configurable apps are more endearing this time. The inconsistent UIs between Qt, GTK, etc don't bother me so much after a decade of web-first UIs.
- randyrand 5y ago
- mmastrac 5y agoI love the idea of Flutter, but tying it to Dart just seems like a way to guarantee it'll have a long slog to getting larger-scale usage. It feels like Google had a language that had no users and had to use it for _something_.
- eloisius 5y agoI'm kind of curious why they haven't tried to bring Go to more domains. Back in 2015 I thought by now they'd have released a framework for building Android apps in Go.
- d3nj4l 5y agoThis. Flutter is fine, but Dart rankles me. I wish they'd used Kotlin for it instead - a much nicer language with cleaner aesthetics.
- mmargerum 5y agoAgree. I am not learning another language unless its an order of magnitude better than what's out there.
- gnabgib 5y agoDart came out the same year as Kotlin.. it's not like this decision was made this year (they're both 10 years old). Re: Sibling comment it really is an order of magnitude better than many other languages. It's worth giving a try. Null safety alone is worth it (although other languages like C# now support this too).
- csells 5y agoDart as a platform provided the unique ability to target both JIT at development-time to enable sub-second hot reload and AOT for release apps, providing native performance when it comes to scrolling, animation, etc.
- fulafel 5y agoHow would it look on other desktop platforms?
- comeonseriously 5y agoWhat do you mean? There's only Mac and Windows. /s
- whiplashoo 5y agoPlan to port this to Linux as well! Haven't look a lot about the available UI design option, but this could be useful: https://pub.dev/packages/yaru https://pub.dev/packages/yaru
- whiplashoo 5y agoHi HN, Author of the post here! Didn't expect this to be posted here and making the rounds, so I will try to give some more context. First, you can check a short presentation of the app's features in a previous post: https://blog.whidev.com/shortcut-keeper-app https://blog.whidev.com/shortcut-keeper-app . Then, I wrote on why I chose Flutter for this instead of native or Electron, and how it helped me ship an app on both stores in one month, here: https://blog.whidev.com/building-a-flutter-desktop-app-in-one-month https://blog.whidev.com/building-a-flutter-desktop-app-in-on... My main background is web development (JS, jQuery, Vue, WordPress, etc.) and I have been using Flutter for the past year or so for another mobile app (iOS and Android). If you want to keep one thing from this, is that Flutter enabled me, a developer with no prior desktop dev experience, to: - Build on my own a desktop app for macOS and Windows (Linux is also possible, and I will try it). - Solve my own problem (that's where the idea of the app came from), and the problem of a few hundred users in the past two months. Also bear in mind that it's a paid app. - Get it accepted and published on both platform stores in a short timeframe. - Make it look native on both platforms by using two community packages and some conditional logic. Of course, I could use the default UI design (Material) or adapt my own design system, but, as I explain in the post, I consider it a huge advantage to feature an adaptive app design. - Do this from a single codebase, with the same business logic: database calls, models, controllers, settings, etc. are all shared between the two versions. Happy to answer any questions! Minas *edited formatting
- webmobdev 5y agoThanks for the great writeup. Can you clarify if Flutter is like QT in that it uses its own GUI library to emulates the native UI of the OS, or does it actually render the UI using the native OS UI library?
- csells 5y agoFlutter provides its own widget implementations and does not rely on those provided by the underlying OS. This gives us the ability to give you complete control over scrolling, animation, theming, etc. while still running at native speeds across multiple platforms.
- 5y ago
- fauigerzigerk 5y agoFlutter has massive battery drain issues on macOS and Google appears to be saying that it's unfixable. That kills it for me unfortunately. https://github.com/flutter/flutter/issues/59327 https://github.com/flutter/flutter/issues/59327 https://github.com/flutter/flutter/issues/59327#issuecomment-673147157 https://github.com/flutter/flutter/issues/59327#issuecomment...
- fabiospampinato 5y agoI've been pretty excited about the possibility of using Flutter in the future potentially, once it gets good, that issue got my hopes down a lot. You know a project is not in good hands when they say spending 6~10% of the CPU for rendering a blinking cursor is justified.
- MathCodeLove 5y agoI was excited about using Flutter "when it got good" almost 2 years ago now. At this point I just go for React Native if I need an app for mobile and web, and React if I just need a web app.
- fabiospampinato 5y agoThat's a practical solution, but IMO React is playing a fundamentally different game here, they have Native for mobile apps, and third-party (!) support for Windows and Mac (what about Linux?). Native doesn't even support the web, like React and React Native are two different things, they just share a somewhat similar UI framework basically. Flutter on the other hand is architected as a solve-it-all solution. They even went as far as designing Dart rather than hacking a decent solution on top of JS and the current mess of web standards. IMO that's a much more interesting and powerful approach, that isn't fully ready yet, but if it ever becomes actually good I'll personally probably jump ship and use it for everything.
- cercatrova 5y agoReact Native Web exists [0]. But I agree, having parts be third party doesn't mesh well with being a complete framework for building apps (on whatever platform you need). [0] https://github.com/necolas/react-native-web https://github.com/necolas/react-native-web
- whywhywhywhy 5y agoOn the Mac side the traffic lights have no anti-aliasing On the windows side the maximize widget is messed up and there is a stray 1pm border top left. If "native looking" is your goal then please take screenshots of your faked window borders and widgets and overlay them over the real thing and see where you went wrong.
- whiplashoo 5y agoWill check it out, thanks for the feedback!
- karmicthreat 5y agoI have had pretty good luck banging out a glorified calculator app for one of my products using flutter. Started from zero with flutter/dart and had a workable app in a couple weeks. The code is pure crap since it was written while figuring out the framework. But easy enough to refactor into something more reasonable. Now to add OTA updating over bluetooth for an ESP32 device to the app.
- chimen 5y agoI think Flutter is going into the right direction. I developed some apps with it, it has rough edges but it gets you there. Dart is ok language, no issues for me going with it. My only complaints are as follows: - the dart formatter which is a cancer that wants to do things in only one way. The forced 2px indentation for example is unbearable for me. The maintainers are close-minded and refuse to understand that some people cannot operate with 2px indents. They will even delete your issues/comments at this point. - Flutter is backed by Google which likes to anihilate, sometimes without warning, projects that don't go as planned. It is open source but still, without Google backing it, it would have never left the ground maybe.
- skybrian 5y agoWhat do you mean by 2px? Are you complaining about two space indents? Is that really so unreasonable?
- anaganisk 5y agoI always thought spaces are either tabs or spaces. Wym 2px indents? Also Flutter is a framework based on dart. Its like saying Django doesn’t support braces instead of indent based syntax. Its how language decided it works no cancer there. Also even I was sceptical about google cemetery. But at this point flutter is widely used and is fully open source and licenses. It will not drop dead like Google services. May be no more bugfixes after its final release.
- gigel82 5y agoIf you want to go this route, I recommend exploring react-native as well. Microsoft maintains desktop versions for Windows and macOS which are pretty functional. And you don't need to create 2 entirely different UI layers (which kind of defeats the purpose IMHO) - you'll be able to share 90% + (closer to 99% if you don't care about re-arranging content but still getting native controls for each platform).
- leodriesch 5y ago+1. The main advantage of Flutter is the write once run everywhere, which is apparently not taken advantage of here. If you’re gonna try to emulate native on multiple platforms, go with React Native and not Flutter. Especially on Apple’s platforms flutter is always going to feel a little bit off compared to native applications.
- jkmcf 5y agoMy heart fluttered when I checked out the app size on Apple's App Store: 19MB -- quite a nice surprise! The equivalent Electron app would probably be 100MB+.