I'm sure you've long since found your own answer to the question, but this came up in a google search on a related topic & I'm procrastinating, so: In a client app, I think it'd be equally difficult to move from/to any of the systems you mentioned. They all pass in data through props and have proprietary methods for mutating data. That said, it's worth noting that they're not mutually exclusive. If you conceptualize your app as having both a state and data from your backend, then it starts to look a lot more clear. Ex: on a regular Facebook feed, you might have 50 news items, 5 messages, and 10 notifications all loaded into browser memory from the server. If you logged in from a new computer at the same time, those items would be replicated to that client. So while that data lives in your app, it's got diff't considerations wrt managing it. The other kind of data is different. If you have an IM window where open=true , for example, this is state that can change arbitrarily and not affect the data on the server--'local' state basically. Relay (& to a lesser extent, Apollo Client) solves the first type of state. It's not just a good solution, it's as good a solution as I can imagine. You connect your components almost directly to your database, tell Relay what fields you need, and Relay handles the rest--caching, retries, loading/fail states--all set. You're on your own with local state, though (outside of hacks & special third-party libraries that can tap into Relay state). The learning curve is steep, but honestly, once you've conquered it, you have a more solid foundation for your app's data than you'd likely achieved w/ Redux/MobX (simply because they don't handle all the hard work for you like Relay does). Redux/Mobx, on the other hand, don't discriminate b/t local state and data from your backend. This means that, before anything else, you're responsible for loading your backend data into those systems (often using another library, like Redux-saga (which is incredible, btw). From there, you can do more/less what you want with it. In my opinion, that substantially increases the amount of stuff to worry about. Redux, for example, brings tons of reducers and action creators to the table for you to manage. If you need the control and have the skill, great. Personally, I don't (on both counts). I just ported an app from Redux to Relay and am disappointed I didn't do it earlier. Lastly, the reason I bolded client app above is this: Relay makes some considerable demands of your backend that MobX/Redux/Apollo Client don't. Your GraphQL schema has to be structured very specifically so that Relay knows where to find what it needs. I hear this can be a huge pain if you're rolling you're on, but if you're using a GraphQL-as-a-service (think: Firebase for GraphQL) like scaphold.io, reindex, or graph.cool--your endpoint is ready out-of-the-box for Relay.