RxSwift vs. Combine Wrap-Up

Over the last several days, I’ve gone on a deep dive on the differences between RxSwift and Combine. To recap:

We’ve been on a long journey, so let’s go ahead and wrap this up… for now.

Overall Impressions

Naturally, there’s a lot to love in Combine. So much of Combine is exactly what I’ve been hoping for: a first-party, blessed, approved, framework for reactive programming on Apple platforms. To my eyes, a tremendous amount of Combine was inspired by the ReactiveX project, of which RxSwift is a part.

A lot of what I’m used to is already there, even if the names have been changed. In some cases, such as DisposeBag becoming Cancellable, I think the change is a dramatic improvement. In most other cases, I don’t have a strong opinion one way or the other. Which, ultimately, is a win.

Furthermore, there are some differences in the way RxSwift and Combine are designed. RxSwift doesn’t bother itself with typed errors nor backpressure. That leads for easier bookkeeping, but sometimes far more convoluted code. Combine, by comparison, bakes both typed errors and backpressure in from the start. More bookkeeping, but more robust code.

Overall, Combine today is definitely a “1.0” release. There’s a lot that is still missing from Combine. There is no clear way to bind to UIKit objects; the most obvious answer is KVO, but KVO isn’t available on most UIKit objects. Naturally, one can write these bindings by hand, but that’s fraught with peril, and a lot of work.

Plans for Vignette

All of this makes my planning for Vignette… complicated.

Currently, my plan is to keep on developing Vignette using RxSwift. There’s just too much missing from Combine that I’d have to give up and re-write to use it in lieu of RxSwift.


Vignette’s UI is trickier than you’d expect, but still not that complex, in the grand scheme of things. And the siren call of SwiftUI is very, very strong. To affect state changes in SwiftUI, Combine is preferred.


Having only played with SwiftUI a couple times, my current plan is:

  • Any new views will be SwiftUI wherever possible.
  • Existing views will be ported as time allows and as seems reasonable.

For existing views that I port, my current plan is to bridge from RxSwift → Combine. Thankfully, the way I write my apps makes this reasonably easy, as there is one Observable<State> that will need to be converted into a Producer. Everything is contained in that one stream, so it’s not like I have to assemble 350 output streams in order to bridge into the Combine world.

(This could get real ugly on the input side, however, as what goes into my state generator is a ton of UIKit-sourced Observables. I’m still not sure how this would play out in a SwiftUI world.)

Greenfield Apps

For a greenfield app, I’m not sure what I’d do.

I think if I could make 100% of the app SwiftUI, I would do so, and use only Combine. To avoid pulling in the large RxSwift dependency would be awesome. However, the moment I need to do more than one or two things in UIKit, I’d probably have second thoughts.

Existing Apps Without RxSwift

If I was looking at what to do with an app that doesn’t use RxSwift, but does use UIKit, I’d probably avoid retrofitting Combine onto any of it. However, I’d absolutely do all new development in SwiftUI and Combine going forward. It is clearly the future; embrace it.

Where Do We Go From Here?

For now, this series on RxSwift vs. Combine is over. I’ve said all I can say without really diving into how this stuff works. The best way to do that, of course, is to use it.

Over the summer I plan to do some compulsory updates to Vignette, like dark mode support, and then start dabbling with SwiftUI and some of this new Combine hotness. As I do so, I’ll surely be putting up new posts describing my findings.

Need Help?

Should you find yourself in the position of needing some assistance with your own RxSwift (or straight UIKit) app, and want me to come in and take a look, please reach out. I have plenty of my own things to keep me busy this summer, but if the fit is right, I’d love to help out some other users. In no small part to help me learn too. 😊