RepoPilotOpen in app →

ReactiveX/RxSwift

Reactive Programming in Swift

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 5w ago
  • 45+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/reactivex/rxswift)](https://repopilot.app/r/reactivex/rxswift)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/reactivex/rxswift on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: ReactiveX/RxSwift

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ReactiveX/RxSwift shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 5w ago
  • 45+ active contributors
  • Distributed ownership (top contributor 42% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live ReactiveX/RxSwift repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/ReactiveX/RxSwift.

What it runs against: a local clone of ReactiveX/RxSwift — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in ReactiveX/RxSwift | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 62 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>ReactiveX/RxSwift</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ReactiveX/RxSwift. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/ReactiveX/RxSwift.git
#   cd RxSwift
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of ReactiveX/RxSwift and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ReactiveX/RxSwift(\\.git)?\\b" \\
  && ok "origin remote is ReactiveX/RxSwift" \\
  || miss "origin remote is not ReactiveX/RxSwift (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "Package.swift" \\
  && ok "Package.swift" \\
  || miss "missing critical file: Package.swift"
test -f "Documentation/GettingStarted.md" \\
  && ok "Documentation/GettingStarted.md" \\
  || miss "missing critical file: Documentation/GettingStarted.md"
test -f "Platform/DataStructures/Bag.swift" \\
  && ok "Platform/DataStructures/Bag.swift" \\
  || miss "missing critical file: Platform/DataStructures/Bag.swift"
test -f "Rx.playground/Pages/Introduction.xcplaygroundpage/Contents.swift" \\
  && ok "Rx.playground/Pages/Introduction.xcplaygroundpage/Contents.swift" \\
  || miss "missing critical file: Rx.playground/Pages/Introduction.xcplaygroundpage/Contents.swift"
test -f ".swiftlint.yml" \\
  && ok ".swiftlint.yml" \\
  || miss "missing critical file: .swiftlint.yml"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 62 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~32d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ReactiveX/RxSwift"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

RxSwift is a Swift implementation of ReactiveX (Rx), a library for composing asynchronous and event-based programs using observable sequences. It abstracts streams of data and asynchronous operations through the Observable<Element> interface, unifying KVO observation, async operations, UI events, and data streams under a single sequence abstraction. The core capability is enabling declarative, composable handling of complex asynchronous flows without callback hell. Monolithic structure with core Rx logic at the root, Platform/ directory containing OS-specific utilities (Darwin, Linux) and thread-safe primitives (AtomicInt, RecursiveLock, Bag, Queue, PriorityQueue data structures), Preprocessor/ tool for code generation, and Documentation/ as a comprehensive guide suite. Tests are co-located with implementation. The Makefile orchestrates common tasks.

👥Who it's for

iOS, macOS, tvOS, watchOS, and Linux developers building applications with complex asynchronous dependencies—especially those needing reactive UI binding, multi-step API chains, or real-time data streams. Also appeals to teams migrating from other Rx implementations (RxJava, RxJS) seeking language-native patterns.

🌱Maturity & risk

Highly mature and production-ready. RxSwift has 24k+ GitHub stars, well-established testing via GitHub Actions CI/CD (see .github/workflows/tests.yml), extensive documentation across 13+ guide files, and a standardized code style enforced via .swiftlint.yml and .swiftformat. The project maintains Swift 5.9+ compatibility (Package@swift-5.9.swift) and is actively maintained by the ReactiveX organization.

Low risk for active codebases. The repository has stable, broad platform support (iOS through Linux) and no external package dependencies in Package.swift. Risk surfaces are: (1) Reactive programming has a learning curve and requires mental model shift, (2) Swift concurrency (async/await) introduction documented in Documentation/SwiftConcurrency.md suggests potential paradigm tension as the language evolves, (3) Single maintainer risk typical of community-driven projects—check recent commits in .github/workflows for activity.

Active areas of work

Active development visible through CI/CD pipeline in .github/workflows/tests.yml, with recent focus on Swift Concurrency integration (Documentation/SwiftConcurrency.md), Swift Package Manager and Carthage compatibility, and cross-platform (watchOS, Linux) stability. The .swift-version and .ruby-version files indicate managed language/tool evolution.

🚀Get running

git clone https://github.com/ReactiveX/RxSwift.git
cd RxSwift
make

Or use Swift Package Manager: swift build. Requires Swift 5.9+ (see .swift-version).

Daily commands: This is a library, not an executable. Build via make or swift build. Run tests via GitHub Actions (see .github/workflows/tests.yml for exact commands) or locally with swift test. Examples are in Documentation/Examples.md and Documentation/ExampleApp.md.

🗺️Map of the codebase

  • Package.swift — Entry point defining RxSwift's library structure, dependencies, and module organization for Swift Package Manager—essential for understanding how the framework is assembled.
  • Documentation/GettingStarted.md — Primary onboarding document explaining Observable fundamentals, subscription patterns, and core Rx concepts that underpin all framework usage.
  • Platform/DataStructures/Bag.swift — Core thread-safe collection for managing observable subscriptions and disposables—a foundational data structure used throughout the framework.
  • Rx.playground/Pages/Introduction.xcplaygroundpage/Contents.swift — Interactive introduction showing Observable creation and subscription patterns, demonstrating the core API contract developers must understand.
  • .swiftlint.yml — Defines code style and quality standards enforced across all contributors' code—critical for maintaining consistency in the 600-file codebase.
  • Platform/RecursiveLock.swift — Thread-safety primitive protecting shared state in observables—understanding locking patterns is essential for preventing race conditions in reactive chains.
  • Documentation/Schedulers.md — Explains thread-execution semantics and scheduling strategies fundamental to concurrent observable behavior and performance tuning.

🛠️How to make changes

Add a Custom Operator to RxSwift

  1. Study existing operator implementations in the Rx.xcodeproj—operators extend Observable<Element> with chainable transformations; examine how they manage subscriptions and disposables (Rx.xcodeproj/project.pbxproj)
  2. Create a new operator file (e.g., Sources/RxSwift/Operators/MyCustomOperator.swift) following the pattern: extension ObservableType { func myOperator(...) -> Observable<NewElement> { ... } } (Package.swift)
  3. Implement the operator's subscribe(observer:) method, handling .next, .error, and .completed events; manage the upstream subscription with a Disposable (Platform/DataStructures/Bag.swift)
  4. Add unit tests in the RxTest target demonstrating the operator's behavior, including edge cases (error propagation, completion timing) (.github/workflows/tests.yml)

Create a New Scheduler Implementation

  1. Review Documentation/Schedulers.md to understand the required ImmediateScheduler and SerialDispatchQueueScheduler protocol contracts and timing guarantees (Documentation/Schedulers.md)
  2. Implement the Scheduler protocol in a new file (e.g., Sources/RxSwift/Schedulers/MyScheduler.swift), providing schedule(state:action:) methods for immediate and delayed execution (Package.swift)
  3. Use Platform.Darwin.swift or Platform.Linux.swift primitives (DispatchQueue, pthreads) depending on target to achieve the desired thread-execution semantics (Platform/Platform.Darwin.swift)
  4. Register the scheduler in the main RxSwift module and add it to the Xcode scheme targets so it's available for observable.observeOn(myScheduler) (Rx.xcworkspace/contents.xcworkspacedata)

Add a New Trait Type (Single, Maybe, Completable Variant)

  1. Read Documentation/Traits.md to understand the constraint semantics: a trait emits 0 or 1 success events, or 1 error, reducing observable complexity (Documentation/Traits.md)
  2. Define the new trait event enum (e.g., enum MyTraitEvent { case success(Element), error(Error) }) and create the MyTrait<Element> wrapper type in Sources/RxSwift/Traits/ (Package.swift)
  3. Implement asObservable() to convert the trait to a standard Observable, and add convenience constructors using the event semantics (Documentation/HotAndColdObservables.md)
  4. Add playground examples in Rx.playground/Pages/ demonstrating the trait's use case and how it simplifies composition versus raw Observables (Rx.playground/Pages/Table_of_Contents.xcplaygroundpage/Contents.swift)

Implement Thread-Safety for a New Shared State

  1. Review Platform/RecursiveLock.swift to understand RxSwift's locking abstraction for protecting concurrent reads and mutations (Platform/RecursiveLock.swift)
  2. Wrap your shared state (e.g., array of observers) in a RecursiveLock and use lock() { ... } blocks around all read/write operations (Platform/DataStructures/Bag.swift)
  3. Ensure that no locks are held during user callbacks (subscribe, next, error, complete handlers) to prevent deadlock; use Bag for lock-free iteration where possible (Platform/DataStructures/Queue.swift)
  4. Test under high concurrency (many simultaneous subscriptions) using the test schedulers in RxTest to verify no data races or drops (.github/workflows/tests.yml)

🔧Why these technologies

  • Swift & Reactive Extensions (Rx) Pattern — Swift provides strong type safety and value semantics while Rx abstracts async composition, error handling, and threading into a unified Observable interface—enabling safe reactive code across all Apple platforms and Linux
  • RecursiveLock & Bag data structures — RxSwift runs concurrent subscriptions; locks protect shared state (observer lists, event buffers) while Bag provides O(1) unsubscribe to minimize lock contention during high-frequency emissions
  • Scheduler abstraction (ImmediateScheduler, SerialDispatchQueueScheduler) — Decoupling event emissions from thread execution allows observables to run on appropriate queues (main for UI, background for I/O) without tight coupling to GCD or platform threading
  • Trait types (Single, Maybe, Completable) — Restricting Observable semantics to specific emission patterns reduces API surface and prevents misuse (e.g., Single guarantees at-most-one success), improving type safety and clarity

⚖️Trade-offs already made

  • Opt-in multi-platform (iOS, macOS, tvOS, watchOS, Linux) via Platform.Darwin.swift and Platform.Linux.swift

    • Why: Supporting both Darwin and Linux requires conditional compilation and duplicate implementations of thread primitives, but enables a single reactive framework across the Apple ecosystem and server-side Swift
    • Consequence: Increased maintenance burden; developers must test on both platforms; some features (e.g., DispatchQueue) are Darwin-only and require fallbacks
  • Lazy subscription model (cold observables by default)

    • Why: Cold observables only emit events after subscription, reducing resource consumption and enabling per-subscriber state; however, requires replay operators for shared behavior
    • Consequence: Surprising behavior for newcomers: subscribing twice triggers two separate event chains; solves by using .share() or Subject for hot observables
  • Thread-safe disposal via Disposable/DisposeBag bag semantics rather than reference-counted memory

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

  • Memory leaks via captured self in Observable chains—the library teaches [weak self] patterns extensively in documentation but mistakes are easy.
  • Scheduler choice matters: default Scheduler vs. MainScheduler vs. ConcurrentDispatchQueueScheduler can silently cause deadlocks if misused; see Documentation/Schedulers.md.
  • Observables are lazy by default—nothing executes until subscribe(). Cold vs. Hot observable distinction (Documentation/HotAndColdObservables.md) trips newcomers.
  • RxSwift and Swift Concurrency (async/await) have overlapping goals; mixing paradigms requires careful thread-hopping via Scheduler.observeOn() and is documented in Documentation/SwiftConcurrency.md as an ongoing design question.
  • The Preprocessor tool is undocumented in main repo docs—see Preprocessor/README.md if operator codegen seems magical.

🏗️Architecture

💡Concepts to learn

  • ReactiveX/RxJava — Java/Kotlin parallel implementation of Rx standard; useful for understanding cross-language design decisions if you work on both platforms.
  • ReactiveX/RxJS — JavaScript/TypeScript Rx implementation; largest Rx ecosystem by adoption; RxSwift borrows naming and semantics from here.
  • apple/swift-async-algorithms — Apple's companion library for Swift concurrency; increasingly relevant as RxSwift ecosystem considers bridging to async/await (see Documentation/SwiftConcurrency.md).
  • CombineCommunity/CombineExt — Extends Apple's native Combine framework (RxSwift's direct competitor on iOS 13+); useful for understanding how Rx and Combine differ in API and execution model.
  • RxSwiftCommunity/RxSwiftExt — Community-maintained extensions and operators for RxSwift; shows real-world usage patterns and fills gaps in stdlib operators.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for Platform/DataStructures components

The Platform/DataStructures directory contains critical data structures (Bag.swift, Queue.swift, PriorityQueue.swift, InfiniteSequence.swift) that are foundational to RxSwift's performance and correctness. While the repo has a tests.yml workflow, there's no evidence of dedicated unit test files for these data structures in the file listing. Adding thorough tests would catch regressions and document expected behavior.

  • [ ] Create Tests/Platform/DataStructures/ directory structure
  • [ ] Add BagTests.swift covering add, remove, count, and iteration operations
  • [ ] Add QueueTests.swift covering enqueue, dequeue, isEmpty, and FIFO ordering
  • [ ] Add PriorityQueueTests.swift covering priority-based ordering and edge cases
  • [ ] Add InfiniteSequenceTests.swift covering sequence generation and memory efficiency
  • [ ] Integrate new test targets into Package.swift and Xcode project

Add platform-specific unit tests for Platform/Platform.Darwin.swift and Platform.Linux.swift

RxSwift supports multiple platforms (iOS, macOS, tvOS, watchOS, Linux) with platform-specific implementations in Platform.Darwin.swift and Platform.Linux.swift. The current tests.yml workflow likely runs on a single platform. Adding conditional compilation and cross-platform test targets would ensure Darwin-specific and Linux-specific code paths are properly tested.

  • [ ] Review Platform.Darwin.swift for Darwin-specific implementations (DispatchQueue, locks, etc.)
  • [ ] Review Platform.Linux.swift for Linux-specific implementations
  • [ ] Create Tests/Platform/DarwinPlatformTests.swift with #if os(macOS) || os(iOS) guards
  • [ ] Create Tests/Platform/LinuxPlatformTests.swift with #if os(Linux) guards
  • [ ] Update .github/workflows/tests.yml to include Linux test job (using Docker or Linux runner)
  • [ ] Document platform-specific test execution in CONTRIBUTING.md

Complete missing Documentation/SwiftConcurrency.md guide with practical examples

The file Documentation/SwiftConcurrency.md exists in the file structure but its content is not provided. Given RxSwift's evolution and Swift Concurrency becoming standard, this document is critical for users. Based on other documentation files (Schedulers.md, Traits.md), this guide should explain async/await integration, Actor isolation, and migration patterns from RxSwift to async/await.

  • [ ] Add section: 'Swift Concurrency Overview' explaining async/await and Actors
  • [ ] Add section: 'Bridging RxSwift Observables to async/await' with code examples
  • [ ] Add section: 'Using withCheckedContinuation and withCheckedThrowingContinuation'
  • [ ] Add section: 'Task and TaskGroup integration with RxSwift'
  • [ ] Add section: 'Migration guide' comparing Observable patterns to async/await patterns
  • [ ] Add practical runnable examples (consider adding to Rx.playground pages)
  • [ ] Cross-reference from Documentation/GettingStarted.md and Documentation/Tips.md

🌿Good first issues

  • Add unit tests for Platform/DataStructures/PriorityQueue.swift—it's a critical scheduler utility with no visible test file in the file list; contribute queue operation correctness tests.
  • Expand Documentation/SwiftConcurrency.md with concrete examples showing Rx-to-async/await migration patterns—the file exists but is sparse; the tension between paradigms is actively being resolved.
  • Create a runnable playground or example in Documentation/Playgrounds.md for common MVVM+RxSwift patterns on iOS—GettingStarted.md covers theory but lacks practical UI binding examples.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 132aea4 — Fix flatMap key path type inference for Package@swift-5.9.swift (#2689) (CAMOBAP)
  • ed67142 — Fix macCatalyst compilation & add regression testing on CI (#2691) (nighthawk)
  • 5734ad2 — Fix compilation for < Swift 6.2, add CI for Xcode 16 (#2688) (freak4pc)
  • 34e2c25 — Swift 5.9 manifest, remove trailing commas from function calls (#2685) (mitschlagel)
  • d65747c — Update Gemfile to address dependabot warnings (freak4pc)
  • b529ef9 — Fix recursive lock test (freak4pc)
  • 719613a — Bump to 6.10 (freak4pc)
  • eb5a47e — Fix resource leak in AsyncSequence.asObservable() tests (freak4pc)
  • 68bdf8e — Cleanup, remove CHANGELOG.md (freak4pc)
  • a0d98e3 — Fix AsyncSequence.asObservable() to always use Task.detached (freak4pc)

🔒Security observations

The RxSwift repository demonstrates good security practices overall. It's a well-maintained, open-source reactive programming library with no obvious critical vulnerabilities detected in the visible file structure. No hardcoded secrets, SQL injection risks, XSS vulnerabilities, or exposed infrastructure configurations are apparent. The main recommendations focus on enhancing security best practices: (1) adding a formal SECURITY.md vulnerability disclosure policy, (2) ensuring robust validation in build automation scripts, (3) maintaining up-to-date dependency audits for Ruby and Swift packages, and (4) documenting supply chain security practices. The project follows standard open-source practices with CI/CD workflows, linting configuration, and code organization, which are positive security indicators.

  • Low · Missing CONTRIBUTING.md Security Guidelines — CONTRIBUTING.md / Root directory. The CONTRIBUTING.md file exists but typical security contribution guidelines for reporting vulnerabilities are not evident from the file structure. No SECURITY.md or security policy file is visible. Fix: Add a SECURITY.md file with clear instructions for responsible disclosure of security vulnerabilities. This should include contact information and process for reporting issues privately before public disclosure.
  • Low · Potential Build Script Security — Makefile, Dangerfile. The presence of Makefile and Dangerfile suggests automation scripts that could potentially execute arbitrary code. Without visibility into their contents, there's a risk if these scripts are not properly validated or if they depend on untrusted sources. Fix: Ensure all build scripts use pinned versions of dependencies, validate inputs, and follow the principle of least privilege. Review for any dynamic code execution patterns.
  • Low · Ruby Dependency Management — Gemfile, Gemfile.lock. Gemfile and Gemfile.lock are present, indicating Ruby dependencies for tooling (likely for CI/CD and documentation). Without seeing the lock file contents, there's potential risk from outdated or vulnerable gems. Fix: Regularly update and audit Ruby dependencies. Use bundle audit to check for known vulnerabilities in gems. Consider using a dependency vulnerability scanner in the CI/CD pipeline.
  • Low · Swift Package Dependencies Not Visible — Package.swift, Package@swift-5.9.swift. While Package.swift and Package@swift-5.9.swift files exist (indicating Swift Package Manager usage), the actual dependency declarations are not visible in the provided structure. External dependencies could potentially introduce supply chain risks. Fix: Maintain a Software Bill of Materials (SBOM) for all dependencies. Regularly audit transitive dependencies using tools like SwiftPM's dependency resolution features. Pin to specific versions rather than floating versions where possible.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · ReactiveX/RxSwift — RepoPilot