It's completely painless with Expo. With the tradeoff being you are locked into the Expo compatible ecosystem. Incredible devX if you go all in on it though.
I was considering using RN for a cross platform app and for some reason got the impression (earned or not) that Expo was for beginners, and people who have "non trivial" apps will have to "eject" (as it's called in Expo) sooner or later. So I was going to avoid it.
The reason people "eject" is primarily to add 3rd party native modules for functionality not available in expokit, or to optimize build size by removing unused expokit functionality. This isnt neccessary in the vast majority of cases as you can use Expo App Services to do this (locally, or remotely if you dont have mobile sdks installed)
And you still get the other benefits of expo - e.g. "batteries included" api, OTA app updates, not having to install the mobile SDKs, etc.
whats the type of functionality not available?
You then use 3rd party modules (or build your own) to add/extend native functionality that is exposed to react native. For example, webtrc: https://github.com/react-native-webrtc/react-native-webrtc
To be precise, EAS Build does actually eject IIRC, but you never notice this during development. I haven't ejected or seen an android/ or ios/ directory in the past year of developing an Expo app, using many third party libs.
The only thing that's really a pain is that react dev tools has a harder time dealing with RNW components, and debugging in general can be a bit of a pain.
Any concise/clear resource or guide you used?
Perf seems totally within reasonable bounds for a react app, no issues so far.
In terms of resources or guides, it's pretty spotty out there. The project has definitely slowed down in terms of dev and i'm not sure where things like react 18 fit into the picture across platform, but we've setup our own config that works just fine for now.
We may need to reappraise in 2-3 years if react does change architecturally too much.
It gets harder if you want to retrofit it to an older app using older third party libraries that have no or limited support. You have to pick through everything to work out what's playing up.