Hacker News new | ask | show | jobs
React Native made me give up a project today
65 points by amateurInAll 1311 days ago
I revisited an old React Native project with a view to make a new, updated refresh.

React Native is great; React Native firebase is great; Firebase is great; Apple is great.

Getting an app published that depends on all these to work together is an absolute nightmare.

Just installing it is now a walk through a minefield of errors - is your mac an M1? There are dozens of different recipes to follow for a maddening mix of how to install different versions of ruby, of cocoapods, with homebrew or not, with the arm terminal or rosetta emulator.

Maybe I was naive to expect that after a couple of years things would have just gotten easier or faster.

After a day spent 99% on just setup and getting a generic app to not break, before even touching a line of code to make a feature, I have quit.

I wonder if others feel this way? I'm sad because I like app development, and the idea of building for multiple platforms. And I previously invested a lot in learning and supporting RN but the balkanization of this platform has reached the tipping point for me.

27 comments

Ruby, Cocoapods, Homebrew are not React Native problems, they are Apple problems. They ship an OS without a development friendly package management system. Their entire toolchain has no way to manage libs/packages which led to the creation of Homebrew + Cocoapods. Apple also does not allow iOS development on other OS where package management is much better. Apple now also has added the extra complexity of a new CPU architecture which only they control.

Then you add Android to the mix, it does not get better. RN is just trying to solve the multi-platform mobile app development, it cannot solve how Apple chooses to dictate build / release of their applications.

I was going to say, the same is true of every cross platform framework I’ve ever used.

Coming back after some time away is usually 5 minutes of updating things to get Android working, and then a few hours of iOS dependency hell.

It’s definitely an issue with RN, but I haven’t used a cross platform framework that’s any better in this regard.

I only thought it was web dev that had deployment/ installation difficulties.

So the problem is setting up and app either for development or deployment is annoying in general.

Sorta? You can claim it is the fault of Apple, but as it is literally the problem that RN is trying to solve, it is very much their problem.
Who solves this problem any better in the cross-platform GUI space?

Well, maybe Qt, but even if it does, C++ is much less forgiving than TS.

Doesn't change that it is the problem that they are trying to solve, though? Does it?
Flutter
Electron. Everybody knows about the performance issues, but there's a reason why people still use it
Stop shipping a browser with your website.
I'm not sure Electron proper is a viable path for mobile development.

Offline-capable web apps are, or course, a viable alternative, as long as you can afford ignoring iOS.

The answer as always is to use platform languages instead of third party stuff.
They could they just don't. You could use npm, you could use SwiftPM. There is no tie to the cocoapods infra really - they just use it because that was there.
> React Native is great; React Native firebase is great; Firebase is great; Apple is great.

Forgive me for saying this, but the fact that you started with that line makes it sound like you might have some Stockholm Syndrome (or perhaps Sunk Cost Fallacy is more appropriate here). Because what you wrote afterwards makes it clear that at least some of the parts that you mentioned afterwards are in fact not great.

Once everything is setup and builds are working, it's pretty great. Being able to write react components in a mobile app is quite the productivity booster.

However, the infra surrounding getting that to work is quite the burden and one could argue that it isn't worth it, but at the end of the day that's a metric that can be measured and judged by the developers.

Maybe - I just want to be clear that in all of these camps I see great contributions from surely very talented teams.

So it isn't a rant about any one actor being bad. But somehow, getting it all to work together is not just difficult, it seems like with time it's getting more difficult.

OP forgot to add Windows is great.

jesus christ so hard to code there.

This is one of the reasons that as a one person mobile team, I’ve avoided anything but native mobile toolkits. It’s a little more work in some ways that way, but if I have to set one platform down for a while to focus on the other, picking it back up isn’t ever a problem, and if I run into issues usually others have too and they’re easy to fix. Even the mess that are native Android projects are usually reasonable to get up to speed.

Cocoapods in particular is a huge pain in the ass though, even on native iOS projects. It’s been blissful to drop it in favor of Xcode’s built in Swift Package Manager.

As an aside, I’ve found it similarly frustrating to try to get old Rails projects running again. Found one that I hadn’t worked on in at least a decade, would be neat to see it booted up again right? Haha nope forget it, isn’t happening.

I recently got a Rails 4 project I wrote back in 2016 running on a VM for some consulting I'm doing. The contractee is still running it in production.

It was a bit of an adventure, but it can be done. The tricky thing is making sure native compilation works.

Yep, Borland always having to catch up to Windows SDKs taught me the same.

Platform tooling only.

Thanks for sharing this. I think you nailed it: the promise of RN is very appealing to the one person mobile team but ends up being more challenging in the end.
I've unfortunately had this experience many times in the Javascript ecosystem as a whole.

I recently started writing about going back to a Rust project (check my submissions if you're interested) after 2 years and the experience couldn't be more different (incredibly positive, can't say enough good things).

I would love to develop more for mobile platforms, but I just don't think the cost to my mental state is worth it. I actually ended up killing two mobile apps for my main solo project and replacing them with iOS shortcuts and a Discord bot which thankfully provide 99% of the same functionality that the apps previously did.

I know it's not possible for every use case, but if your mobile app is primarily used to send API requests with payloads of text/images/videos, you'd be surprised how far you can get just using iOS shortcuts these days.

Instead I have found working on my 5 years old Javascript projects very easy. Even with this old projects NPM can download the very specific deps without problem thanks to the commited lockfile. Then I can easly install the required node.js version (stated in the package.json) with NVM and no other problem arise.
Maybe this is true when you have an Angular js 1.0 project on Node.js and want to update to Angular 15. But that's not because of Node.js. I manage a ton of older Node.js projects and there is little to no friction.
That's one of the big reasons why I've been Nixifying my React Native projects, and gradually it seems to be working out. A number of projects seem to be starting to do something like that as well, like status-im, and occasionally I find their configs helpful. By itself, Nix doesn't help with the M1 React Native problems, but with fastlane, Ruby, cocoapods, things really nicely just worked, and once I've figured everything out once, I'll be able feel a breath a relief the next time I come around (except I suppose Xcode, which isn't properly Nix-able).
Yes and no.

I mean, I think this is absolutely the killer feature of Nix (even above the more accessible asdf, since Nix will also provide native libraries); it's really nice to get a development environment which will Just Work. (OP's frustration isn't unusual).

On the other hand, Nix doesn't make problems disappear; and can require having a deep understanding of what the problem encountered is. OP ran into problems trying to get a project which had worked on (presumably) x86_64 macOS, but didn't work on M1.

I don't understand the love for asdf. It doesn't support node versions like let's/gallium. It doesn't support Python venvs. Back to nvm and pyenv-virtualenv for me.
Mobile development is very fast-paced. Even with the native Android SDK, dependency issue can bite you. If I start working on an old codebase and I can't get it to launch in a few hours. I just generate a new starter project and migrate the codebase, adding the newer version of each dependency (while taking care of breaking changes and so). It can be easier and take care of security issue at the same time.

Desktop, CLI and Web Backend programs can be easier because they are in a much stable environment. But mobile development is very much a high-speed train.

My own tips for React Native is just use the IDE (XCode, Android Studio) for each platform whenever I have to build and use a text editor for the JS part. Always worked flawlessly.

On top of that, Google is now requiring that you keep within 2 versions of the latest API, meaning that you have to reupload your app every 2 years (or less) to keep it on the store. Even if it's completely fine.

I think there's something similar for Apple, but I can't actually remember the details right now.

Apple doesn’t generally enforce lower bounds on the supported OS or SDK built against unless there’s recently been a major transition (e.g. 32-bit support being dropped), which don’t happen too often. They will remove listings that have sat idle for too long though (4-5+ years I think, but don’t quote me on that). I’ve never dealt with it personally since the projects I’ve been responsible for have always been getting updates.
Use flutter if you’re looking to build something quick for cross platform iOS android.

Upgrading versions or dependencies isn’t a nightmare.

Dart is easy to use and a pretty good language.

Lots of community support and dependencies.

It works.

Hard agree. I'm not a huge fan of cross-platform dev tools in general[1], but in terms of code hygiene, documentation, and "it just works" factor, Flutter is way ahead of React Native.

Admittedly it's more of a vibe than a hard metric, but a clean build of an empty React Native app for iOS has a triple-digit number of warnings in Xcode.

[1] Making a cross-platform app that's snappy and really nails the platform idioms tends to be at least as much work as making two equally-good native apps.

It's a dream if you're wanting to develop an app with webapp like functionality. Go beyond that and it just feels like a fight.
I'm sure a simple tool would improve the environment issue you mentioned.

It's crazy to me how `https://asdf-vm.com` is still not that well known, Should help to fix lots of dependency issue and it should be a must install for all developers.

Treat brew like apt/dpkg: install programs you're going to directly use with it and basically always want at a recent—or, at least, not any particular—version, not dev dependencies. I know some people do that anyway on major Linux distros but that's also doing it wrong for very similar reasons, unless—maybe unless, there are still good reasons not to—your only deployment target is the exact same version of the Linux distro you have on your workstation.

Use asdf, language-specific package managers, various version managers (rvm, nvm, whatever), docker, vendor things in, all that kind of stuff, for dev dependencies. Same as you should do on most Linux distros (with some exceptions that are made so they play nice with dev dependencies, like Nix).

+1, asdf is so good
React Native is one of those things I instinctively avoided, not because it's bad but because it's a big ball of crap. Anything with that many dependencies and long install processes and such is going to be extremely brittle and hard to maintain.
I would say that a big ball of crap qualifies as bad.
That was poorly worded. What I meant was that React Native results seem good but the system itself looks fragile and messy and rickety. It seems to inherit a lot of the complexity and irregularity diseases that plague the entire JavaScript and web ecosystem.
:D
Getting React Native setup can be a bit of a pain, but I found the transition to M1 completely painless. You just use homebrew for things like Ruby and Cocoapods (the ARM version, but there is no special configuration required - that's what you get by default).

One thing you do generally need to do with React Native is make sure that you're on a relatively recent version of dependencies. If you're revisiting an old project you likely will need to upgrade everything. That probably does make it a bad choice for infrequently maintained projects. Although if you can avoid the native build and stick with what Expo provides then it would become painless again.

Mind you, old versions of Expo really aren't something you would like to use if you're getting back to it like right now; Expo's 3-monthly (I think?) release cycle, and their 3 major versions support policy make it quite hard to deal with, for example if you rely on things like Expo Go. If you had an Expo project as recent as Expo 43 and are just maintaining it today, you won't even be able to test it out on Expo Go (on device that is; their old versions of simulator clients are here https://api.expo.dev/v2/versions/latest), support being dropped already.

Especially now is a bad time to claim that Expo makes transitioning painless - Expo is under major transition to their new EAS services (and old Expo updates are going to be dropped permanently in 2 months) and support for the new React Native Architecture is significantly changing their build process.

I would agree that before Expo's recent major changes (which I applaud), upgrades have generally been quite smooth.

Thankfully, the latest Expo versions seem to allow much more flexibility in the build process, making it much more viable for me to do my own Expo builds and stay mostly intact from Expo's support cycles.

React Native is a huge PITA. It’s not worth it for a one person dev team. Try flutter. I highly recommend the appbrewery video course - it’s $10 and teaches you everything you need to know.
thanks for the tip!
i feel ya! i gave up on a mobile app years ago based on a similar issue. it's too much for one person to manage TBH. don't feel bad about it though. there are way too many vectors to consider and it's overwhelming to say the least. is your project open source? is it on GitHub or some other public-facing repo? let other's help if you're willing to relinquish some control! there is power in numbers and you can still preserve the credit for the idea.

simplify your approach.

If you like the React style approach but want something a bit more self-contained, why not check out SwiftUI? Alternatively for Android, Jetpack Compose? Both toolkits are similar in style to React.

If you're feeling brave (I guess not today) you could also try a Kotlin Multiplatform app, which lets you share code between Android, iOS and desktop or even use Jetpack Compose on iOS (but that's a road less travelled because you don't get fully native UI that way).

Is Jetpack Compose on iOS actually a thing yet? If so, any idea where I can see a demo of it in action, to check for accessibility? A quick web search didn't yield any definitive results.
It's early days for Compose on iOS. I doubt it'll have good accessibility support yet. I think most apps would rather use native UI on iOS.
I feel like the next iteration of a React Native-like tool (if Flutter isn't your jam) could build on top of SwiftUI and JetPack compose.
Judging from your fourth row, it seems to be that "Apple made me give up a project today" is the correct headline, since M1 is apparently the issue.
The native toolset works fine on M1, seems like dependencies issues, like always with React Native.
I was really tempted to buy a new Mac but there are still lots of gotchas my colleagues had to solve, so I decided to wait. Pushing ARM64 to developer machines still seems like a rushed decision imo, and it definitely shifted resources into building and supporting ARM64, resources that Apple doesn't necessarily pay for. At the end of the day, for me it matters how fast I can do a certain task and how much spare time I have left after I finish it.

Docker example: https://docs.docker.com/desktop/troubleshoot/known-issues/ See the "Known issues for Mac with Apple silicon" tab.

I've been on M1 since last year (Switching from a 2015 MBP) and while there have been some issues, the transition has been going fairly swiftly. The main one I had to deal with was some google library embedded inside React Native Firebase. But the fix was fairly easy (setting XCode and Terminal.app to open using Rosetta). My Mac Mini is enough for daily work and my MBA is perfect for personal uses, never getting hot, even with multiple applications opened.
“My desire to do my work on the latest shiny new tech toy made me give up a project today”
rn setup can be hard - but consider the problem space - two different operating systems, two different build systems. if 1 day is the max you're willing to put in to investigate build/config errors, there are very few dev environments you're going to succeed in.

Take, for example, native iOS development. For any dev, that involves regular bouts of multi-day configuration hell. Xcode is a huge beast and cryptic for beginners. Add in multiple third party libraries like firebase and it's a tossup which is harder, native or RN.

Toss in Android support, which is the main reason to use RN, and then you will see an order of magnitude improvement in your RN config.

Toss in web support, which RN has, and you're in a deeper hell.

> Take, for example, native iOS development. For any dev, that involves regular bouts of multi-day configuration hell. Xcode is a huge beast and cryptic for beginners. Add in multiple third party libraries like firebase and it's a tossup which is harder, native or RN.

Hard disagree here, to me this is one of the parts of native iOS development that is far, far better than web development. The web makes up for this with other strengths, but there is no way they're even comparable setup wise.

I guess we had a different experience - perhaps it is better now. my experience with native development was around 2014 with the objectiveC to Swift transition and that was its own hell - but I remember spending a lot of time, maybe 20-30% of my time I would guess, staring down weird build errors.
Oh yeah that period was rough. Xcode and Swift are a lot more stable these days. I guess my experience is also tainted by webpack-heavy JS work from years ago that was a dependency/tooling nightmare. It seems better now with the newer bundlers.
> Just installing it is now a walk through a minefield of errors - is your mac an M1? There are dozens of different recipes to follow for a maddening mix of how to install different versions of ruby, of cocoapods, with homebrew or not, with the arm terminal or rosetta emulator.

honestly, to me it sounds like you have moved over an old environment from years of upgrades, instead of starting fresh on an M1. You're just in edge case hell, and there's no way out if you weren't using segregated environments.

trust me when I'd say it would be faster to start over. when you need your special configurations or PATH variables, you'll find them that one time you need them.

The best investment I ever made and you could too probably is to setup some ci step and dependabot etc. That's how I constantly monitor my many web, mobile and desktop projects and keep my dependencies update. If a new version of a dependency or framework like say flutter drops, I set aside some time, make a new branch, upgrade and do the same. I practice the same with feature branches, merge as soon as possible so the rebases and merges don't get hairy in a week or two. It's maintenance work but the couple minutes a week or so end up paying off in the long term.
Not sure. I built this app[0] in 3 days[1], and it was basically a copy 1:1 from an old project. It was on an old version of React Native and many dependencies were the same. I ran into no issues at all.

Maybe it's because of your complicated setup?

[0]: https://apps.apple.com/app/id1620426799

[1]: https://twitter.com/daniel_nguyenx/status/157500684665792512...

Have you tried using expo? It makes development with react native much easier and does a bunch of stuff for you out of the box.

I'm a solo developer writing a fairly complex mobile application with watch integration and while some bits of the setup might be frustrating, however I would urge you to persist for more than a day if possible.

Indeed I had a huge amount of trouble porting my project from my previous mac to a new M1 but after the frustrating setup I just returned to writing JS and swift code and things have been perfectly fine.

Of all the hyped React stuff I feel like RN really didn't pan out. I always had a gut feeling it wasn't worth it.
I like to work on a linux dev environment, and occasionally need to work on react native. This can be quite a pain when ios specific testing is needed. My solution has been to get a cloud hosted MacOS VM and RDP into it to test with the iOS emulator. These VMs typically run x86, so you get around a lot of the M1 issues.
If it is a one page/view app with no special api needs I would go with a PWA today.
Can you get these on the app stores yet?
I'm currently building a React Native app and I was wondering how much easier would it be to create a PWA that would live in a WebView inside a native app just so I could publish it in the App Store.
It’s very easy. Take your app, dump it into Capacitor. Done.

If you revisit your Capacitor-wrapper a few years later, you either take the update-dependencies-route or just start a fresh project and dump your PWA bundle in there.

Depends on how many native APIs you are using, such as in app purchases.

Google's and Microsoft's, sure.
Wait, Microsoft has an app store?
Install Cocoapods using brew. Use the standard terminal without Rosetta.
You quit after a single day? those are rookie tenacity numbers bud, gotta pump those up. give yourself at least a week, all new things are tough. I have been programming professionally for 15 years and I still encounter these uphill battles that feel terrible - but once you are over the hump it is often smooth sailing.
I agree with you! But in this case it's for a hobby project and I don't have much personal time for it. The feature I wanted to add wouldn't work with the old codebase, and I was curious to try the current libraries/tooling. But the fun factor is zero if the whole time budget goes into just setup problems.
My first ten years of software programming, i was at a distance of the build process. Only when i was experimented did i discover how messy and complicated the build/test/deploy process can become.

So, i fully agree that it can be discouraging, when you hoped 98% of your time would be pure dev time.

Failing fast, when you know the subject area well enough to deem the obstacles clearly insurmountable, may be a useful skill.

I'm not certain it's the case here though.

Dockerize your dev/build env. You can access the Android emulator via VNC.
tldr:

- integration is hard

- parts don't always play nice - because that's not their job

- the better-integrated platforms (read: apple) are worse at playing nice with other parts

- open-source communities can tie things together, but any sustained effort requires some driving entity or opportunity, so they are first to fail in a downturn [ok, that's just a hypothesis]

As for how it feels: the sense of productivity/velocity is an unhelpful guide. You can end up polishing a turd, or playing infinite games, or stalling at critical point. If you instead are making something deeply valuable, the technical means are just that.

fwiw, in the complex equation of development, I pick one variable to maximize that's key for my goals, and leave the others stable/conventional -- which happens to avoid integration issues.

Why write? The devil made me do it.

Why give up after all that effort?
> “Why give up after all that effort?”

Because the speed of iteration in JS-framework-land is so fast that if you take more than a week or two setting up your dev environment your dependencies are already out of date and insecure, and the half of them that are using “require” instead of “import” stopped working with another library you depend on. Then, when you reported that, the maintainer replied to the GH issue, “modern browsers and Node releases have supported ESM loading for _ages_, like months and months before I started being a dev in 2018 so trust me, it’s stable now.”

(Not that I’ve had an experience like this, ever. And if so, not in a least six months. Or two. Whatever; I’m just slow, obviously.)

> Then, when you reported that, the maintainer replied to the GH issue, “modern browsers and Node releases have supported ESM loading for _ages_, like months and months before I started being a dev in 2018 so trust me, it’s stable now.”

Try this line with D3 :-) The maintainer, Mike Bostock, has been a developer since before Node and its commonjs modules. He dropped support of commonjs since d3 version 7, about a year and a half ago.

I remember the time I worked on a project with React Native and they broke a bunch of very useful tools by depending on an alpha of React in a release of RN. Stayed screwed up for a good long while. There were some issues posted on GH that were understandably like "bro, WT actual F?" and the maintainers were all "LOL we're with Facebook, trust us, it's fine".

And that was the day I decided RN was kinda bad.

Sounds like you’re a fan of the sunk cost fallacy.