They're effectively ready to use even if experimental; the migration path is typically pretty painless when features are stabilised and the codemods get you most of the way. There's a couple of missing features for them but if you don't need those then it's not a problem.
I've been using them in production for several months and zero issues. A few small workarounds here and there but otherwise they've been great.
I've had no problem using them in 2.x
What was used instead before ?
The idiomatic way to do data fetching in stable SvelteKit is via load functions.[0]
They still do a good job and allow you to cache the results and invalidate that cache, but they are at a route/layout level rather than at a component level, which is what remote functions solve.