Ask HN: How are you building cross-platform (mobile and browser) apps?
I've been developing web apps for 5+ years and in my next project I've been tasked with building a mobile (iOS and Android) app that we can also run as a web app. I would obviously like to try keep a single code base for simplicity as we have limited resources. I've investigated writing a PWA but I'm put off by the arbritrary heuristics that Google are placing on whether or not the apps are presented as "installable".
After that, it seems the only options are Ionic, or React Native + separate web app.
What is your experience writing apps for both mobile and browser?
83 comments
[ 3.5 ms ] story [ 156 ms ] thread[1]: https://github.com/turbolinks/turbolinks/#readme
https://www.youtube.com/watch?v=SWEts0rlezA
The web, iOS, and Android devices utilize all of the same server generated HTML + JS google maps et al. 0 to completed for both Android and iOS in maybe 30 hours because of the native API stuff I had to learn. If you don't need those native API's or know Swift/Java better, that time could be trimmed down considerably.
https://www.dartlang.org
https://blog.appfigures.com/wp-content/uploads/2018/03/11-No...
(from https://blog.appfigures.com/ios-developers-ship-less-apps-fo... )
Edit: [Disclaimer] I work with them. To clarify, the container is already built, you can build hybrid or native apps on top of that.
If you want to share UI across platforms you could potentially use something like https://github.com/lelandrichardson/react-primitives to do that, but we don't and I'm not sure we'd want to because we don't want to use the same design on all platforms.
I'm not convinced this is what we'd do if we were starting fresh, I imagine we'd look at React / React Native. However, this definitely works for us for now.
[1] We also deploy to very old / basic phones, so we use this opportunity to bundle our own version of the web view so we can target higher chrome versions.
The only downside is if you do want a native look and feel, you'll need to find a UI library to provide that, but that's no different than if you were writing a PWA.
One code base plus auto-syncing of user data.
Works pretty great.
Ionic is pretty close to a native feeling. I think most people wouldn’t be able to tell the difference.
Specifically, tools for Apache Cordova: https://www.visualstudio.com/vs/features/cordova/
(disclaimer: I haven't used them, but I've heard very positive feedback)
2) If you are a non-MS person, make sure you don’t miss out on the greatness of Visual Studio Code by dismissing it as yet another Windows centric product. VS Code is world class performant, has a great plugin arch/ecosystem, and somehow combines a hardcore developer first mindset with carefully thought out UX at the same time.
Also to be clear for those not much in the MS world, the “Visual Studio“ product line you’ve heard of for decades is not the same thing. It’s confusing naming but Visual Studio Code is relatively new and very different.
I second your recommendation, I'm a sucker for a sleek editor with a great plugin architecture.
React Native is a great for cross platform iOS and Android native. If you want code sharing across native app and web app, look into ReactXP, or come up with your own code sharing technique, which apparently @sdcookie’s team did.
Titanium from Appcelerator also supposedly targets Native and Web.
Also consider focusing your efforts on native and not doing a web app. RobinHood stock trading app went a long ways without having a web app. Just throwing that out there.
Apps targeted for B2B users are considerably more flexible in terms of UX, the goal is mainly to help users get stuff done, so hybrid is more viable here. Which is what we usually do with cordova. Some considerations to bear: using cordova, the team doesn't really get much expertise with the proper platform, so problems are sometimes harder to debug because of lack of developer maturity in the platform. You need to design with an eye to light performance requirements, which usually means facilitating inputs and maybe have a separate web interface for complex UI like dashboard and management.
If you absolutely have to share code between apps, your options are:
- hybrid approaches like cordova, or build your own native web view shell and load your web code manually
- react native, which is not v1 yet, and looking at it recently I'm personally not sold on it yet, many unkown unknowns to actually double down and build on it. But that's just my opinion.
- Black box compatibility frameworks like Xamarim, Nativescript and the like. They work by giving a common platform middleware that builds to multiple target platforms. There are a lot of trade offs here, specially the lack of control. If a feature is buggy or not supported there is little recourse.
- I have read some big companies share code via C++ bindings used natively on each platform (loaded in Java and Objective C). I imagine this technically "solves" the problem, as you can share code and build natively, though I have no idea what tooling there is to help with this, and imagine the developer experience gets the short end of the stick.
edit: typos
After a few Cordova and Electron projects I'm going to try this approach in my next project.
I need to support 5 OS (Android, Chrome OS, iOS, macOS, Windows) and having a native UI for each platform is completely out of the question.
I think a web UI is a valid approach. Not only it reduces dev time, but it also adds responsive features not available anywhere else.
This is a great example of a web iOS done right: https://medium.com/missive-app/our-dirty-little-secret-cross...
[0] https://github.com/xamarin/Xamarin.Forms ; https://github.com/xamarin/xamarin-android ; https://github.com/xamarin/xamarin-macios
Writing a graphql endpoint emitting a data class. Then have react directly cast to that same data class. With proper type safety is great.
There are bugs but they feel like fringe cases. I spent half a day cleaning up my bindings to react material ui. An hour or two fighting serializaiton bugs. Those are the biggest time sinks that come to mind. It's still marked as experimental but it's something to keep an eye on.
A few years ago, I worked on a project in Xamarin with some success. The iteration cycle with React Native is far faster, though.
[1] https://blog.google/products/google-play/winners-2018-google...
- React Native Web and React Native (iOS/Android) are handled in one go
- Windows Support
- Stripped down so nothing from within will work on iOS but not Android, for example, as is the case with React Native...
- Lots of components from Material UI (just launched v.1) can work right on top without too much of a hitch
Caveat: we're just getting started, so I don't want to oversell this. But faced with a similar problem, this route seemed optimal at this time.
That being said React Native has stability and performance issues that are tricky and can hold up your app for a non-trivial amount of time. Also staying on top of updates requires diligence and can be a pain. But if you're looking for the quickest path to market I would say look no further.
Also, thanks for the feedback I actually keep getting similar comments that it's a lot to learn all. I'm currently trying to simplify things. To add a track you just add it to your "queue" by searching and clicking the plus icon, then when it's your turn (your UN is all the way to the left) your track will play for everyone. Assuming you figured it out but just FYI
It's super fun because I tried to make a music app to make collaborative playlists on steroids but my UX is so lacking. You can check it out at http://www.niche.fm
One question: Do you plan on writing a native desktop solution? I'm not a fan of having to keep my browser open just to run a single app.
Just checked it out. This is really well executed! Definitely doesn't look like a one man operation. Congrats!
(BTW it just pinned a Google chrome helper on my machine so I had to kill it. Not sure if you know anything about perf. with your app yet. Just FYI)
Sorry about the perf- it's a known issue and I'm working on it, I only recently got it (somewhat) feature complete so It's next on the list...
Can you shed some light on what some of the performance and stability issues you faced are? What can I expect and how did you deal with them or work around them?
Nice app btw!
1. Long lists (>100 items) don't perform well if you have to reorder them. Initial render is a bit slow but not that noticeable but if you have to reorder or add/remove from them on the fly it can be resource intensive.
2. Animation behavior varies between Android and iOS depending on what you're animating.
3. Re-rendering is expensive so you need to be careful when you update your state if you're using redux.
4. Easily fixable but console logging is expensive so be sure to remove all JS logs from production.
It's pretty hard to beat the productivity of one codebase for every platform with a powerful type system catching errors across every part of system.
For the first time, I used a webapp and was hoping that the ios/android experience would be good enough. Unfortunately, It wasn't and it was a big mistake. I'd only recommend this for quick mvp knowing that it'll need to be rewritten or if your audience really understand what it means to have a mobile webapp compared to a native app. I.e. if there's an IT department in place that can install it on the devices and understand the limitations.
For the second time, we went with ionic/phonegap. It was a huge improvement, but we hit too many limitations and scenarios where we wanted native tweaking for animations or handling the keyboard hiding fields or the topbar acting weird, etc. You don't see those issues at first.. but they start appearing as you start doing QA on more devices and with real users. And at that point, you've invested so much in trying to make it work that you can't just go back, so you start piling weird hacks on top of weird hacks.
For the third time, we went with react-native. Overall it was a great experience and unlike ionic, it's a real native app, not just a webview. We could reuse a big part of the code between web, ios and android. The issues we faced were often related to weird edge cases that are buggy within react-native itself such as input fields not working correctly when dictating or a "pull-to-refresh" supposed to be stateless but in practice being stateful and buggy if you call "refresh" on it twice within 30ms. However, it's a good feeling to know that when we'll have the time, we have the flexibility to either fix the library itself or re-write it (compared to ionic where we couldn't do much and web apps where the solution to most our problems would be to "wait a few years until the browsers decide to improve it".)
If I had to do it another time (a fourth time), I'd go with react-native again but I would make sure to stress test the libraries with real data on all the devices we'd want to support. Also, it's popular in the javascript ecosystem to have libraries that depend of another library that depends of another library that wraps another library.. in most cases, it's just better to write a quick wrapper for your app and only include the inner-most library that does most of the work anyway. Otherwise you're depending on too many authors and libraries quickly go out-of-sync and you're stuck with old versions that aren't compatible with new ones.
React-Native has a lot of cross-over with React for the web. So I'm hoping when the time comes my port will go smoothly.
[1] https://medium.com/@ron.arts/web-support-for-create-react-na...
create-react-native-app works by leveraging Expo
eg: websites/single page webapps over native ios/android apps
You can use local storage to cache for offline use. TBH I don't think most apps really need the overhead of these new libraries. Half of the apps on the app store just display and update data from a DB.
For us the ability to run on literally any(!) device (this includes for example also smart TVs) completely outweighs the potential (minor) performance drawbacks.