RepoPilotOpen in app →

neuecc/UniRx

Reactive Extensions for Unity

Mixed

Stale — last commit 2y ago

worst of 4 axes
Use as dependencyConcerns

last commit was 2y ago; top contributor handles 93% of recent commits…

Fork & modifyMixed

no tests detected; no CI workflows detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 2y ago; no CI workflows detected

  • 6 active contributors
  • MIT licensed
  • Stale — last commit 2y ago
Show 3 more →
  • Single-maintainer risk — top contributor 93% of recent commits
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: 1 commit in the last 365 days
  • Fork & modify MixedHealthy if: add a test suite
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

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 "Great to learn from" badge

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

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/neuecc/unirx?axis=learn)](https://repopilot.app/r/neuecc/unirx)

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/neuecc/unirx on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: neuecc/UniRx

Generated by RepoPilot · 2026-05-09 · 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/neuecc/UniRx 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

WAIT — Stale — last commit 2y ago

  • 6 active contributors
  • MIT licensed
  • ⚠ Stale — last commit 2y ago
  • ⚠ Single-maintainer risk — top contributor 93% of recent commits
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<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 neuecc/UniRx repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/neuecc/UniRx.

What it runs against: a local clone of neuecc/UniRx — 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 neuecc/UniRx | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 843 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>neuecc/UniRx</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of neuecc/UniRx. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/neuecc/UniRx.git
#   cd UniRx
#
# 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 neuecc/UniRx and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "neuecc/UniRx(\\.git)?\\b" \\
  && ok "origin remote is neuecc/UniRx" \\
  || miss "origin remote is not neuecc/UniRx (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 master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Assets/Plugins/UniRx/Scripts/Asynchronous/WebRequestExtensions.cs" \\
  && ok "Assets/Plugins/UniRx/Scripts/Asynchronous/WebRequestExtensions.cs" \\
  || miss "missing critical file: Assets/Plugins/UniRx/Scripts/Asynchronous/WebRequestExtensions.cs"
test -f "Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs" \\
  && ok "Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs" \\
  || miss "missing critical file: Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs"
test -f "Assets/Plugins/UniRx/Scripts/Disposables/CancellationDisposable.cs" \\
  && ok "Assets/Plugins/UniRx/Scripts/Disposables/CancellationDisposable.cs" \\
  || miss "missing critical file: Assets/Plugins/UniRx/Scripts/Disposables/CancellationDisposable.cs"
test -f "Assets/Plugins/UniRx/Scripts/Disposables/BooleanDisposable.cs" \\
  && ok "Assets/Plugins/UniRx/Scripts/Disposables/BooleanDisposable.cs" \\
  || miss "missing critical file: Assets/Plugins/UniRx/Scripts/Disposables/BooleanDisposable.cs"
test -f ".nuget/UniRx.nuspec" \\
  && ok ".nuget/UniRx.nuspec" \\
  || miss "missing critical file: .nuget/UniRx.nuspec"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 843 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~813d)"
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/neuecc/UniRx"
  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

UniRx is a C# port of Reactive Extensions (Rx) specifically adapted for Unity game engine, enabling composition of asynchronous and event-based operations using observable sequences and LINQ-style operators. It solves the core problem that Unity's coroutines lack composability, exception handling, and return values—UniRx provides a unified event stream abstraction for network calls, UI interactions, game loop events, and sensor data. Monolithic structure: Assembly-CSharp.csproj and Assembly-CSharp-Editor.csproj (the core UniRx library), Assets/ directory (Unity integration and examples), Analyzer/ subdirectory containing a separate Roslyn analyzer solution (HandleObservableAnalyzer.cs) for compile-time diagnostics, and .nuget/ for packaging. The library bundles Core (Rx port) + Platform Adaptor (MainThreadScheduler, FromCoroutine) + Framework (ObservableTriggers, ReactiveProperty).

👥Who it's for

Unity game developers building interactive applications who need to handle asynchronous operations (networking, user input, animations) without deeply nested coroutines or callback spaghetti. Also relevant to framework maintainers adding reactive capabilities to Unity projects.

🌱Maturity & risk

Production-ready and actively maintained but in maintenance mode. The repo shows a stable v7.1.0 release (per package.json), has CI configured (.circleci/config.yml), and includes a Roslyn analyzer (Analyzer/ directory). However, the README explicitly recommends the evolved successor Cysharp/R3 for new projects, indicating this is transitioning to legacy status while remaining stable.

Low technical risk for existing consumers but strategic risk due to official recommendation to migrate to R3. The codebase is single-maintainer (neuecc/Yoshifumi Kawai), and no recent commit data is visible in the file list. Dependencies are minimal (see package.json has empty 'dependencies' object), reducing supply-chain risk. Breaking changes are unlikely given the mature state, but new feature development has halted.

Active areas of work

Active development has shifted to R3; UniRx v7.1.0 (2018.3+) is the latest stable release. The codebase includes CI via CircleCI (.circleci/config.yml) but no recent build/commit data is present in the file list. The Analyzer subdirectory suggests ongoing refinement of developer experience through compile-time checks for unhandled observables.

🚀Get running

Check README for instructions.

Daily commands: This is a library, not an executable. To verify the build: dotnet build Assembly-CSharp.csproj. To use in Unity: import the Assets/ folder and create a MonoBehaviour that references UniRx observables. The .nuget/pack.bat and .nuget/push.bat scripts generate and publish NuGet packages.

🗺️Map of the codebase

  • Assets/Plugins/UniRx/Scripts/Asynchronous/WebRequestExtensions.cs — Core asynchronous extensions bridging Unity's WWW/WebRequest to observable streams; essential for async operations
  • Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs — Fundamental resource management pattern for cleaning up subscriptions; required by all observable chains
  • Assets/Plugins/UniRx/Scripts/Disposables/CancellationDisposable.cs — Cancellation token pattern implementation; critical for subscription lifecycle management
  • Assets/Plugins/UniRx/Scripts/Disposables/BooleanDisposable.cs — Simple disposable state tracker; used extensively in observable subscription cleanup
  • .nuget/UniRx.nuspec — Package metadata and dependency definitions; controls distribution and compatibility across platforms
  • Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs — Roslyn analyzer detecting unhandled observables; prevents common subscription memory leaks in production code
  • Assets/Plugins/UniRx/Examples/Sample12_ReactiveProperty.cs — Reference implementation of ReactiveProperty pattern; demonstrates core framework abstraction for reactive state

🧩Components & responsibilities

  • Observable<T> Core — undefined

🛠️How to make changes

Add a New Observable Extension for Unity Component

  1. Create a new static extension method file in Assets/Plugins/UniRx/Scripts/ following the pattern of WebRequestExtensions.cs (Assets/Plugins/UniRx/Scripts/Asynchronous/WebRequestExtensions.cs)
  2. Implement IObservable<T> return type using Observable.Create() to wrap the Unity callback/coroutine (Assets/Plugins/UniRx/Examples/Sample02_ObservableTriggers.cs)
  3. Ensure proper disposal via return of IDisposable; reference CompositeDisposable pattern for multi-step cleanup (Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs)
  4. Create example usage in Assets/Plugins/UniRx/Examples/ with clear subscription and disposal patterns (Assets/Plugins/UniRx/Examples/Sample01_ObservableWWW.cs)

Add a ReactiveProperty-Based UI Binding

  1. Define ReactiveProperty<T> field matching Sample12_ReactiveProperty.cs pattern for two-way binding state (Assets/Plugins/UniRx/Examples/Sample12_ReactiveProperty.cs)
  2. Subscribe UI elements (buttons, toggles, text fields) using .Subscribe() and track with CompositeDisposable (Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs)
  3. Implement cleanup in OnDestroy() by calling .Dispose() on the CompositeDisposable (Assets/Plugins/UniRx/Examples/Sample13_ToDoApp.cs)

Extend Roslyn Analyzer for Custom Observable Patterns

  1. Study existing HandleObservableAnalyzer.cs implementation to understand DiagnosticDescriptor and syntax tree analysis (Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs)
  2. Add new analyzer rule class inheriting from base analyzer pattern; register in DiagnosticAnalyzer attribute (Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs)
  3. Write unit tests in HandleObservableAnalyzerTest.cs following CodeFixVerifier pattern (Analyzer/UniRxAnalyzer/UniRxAnalyzer.Test/HandleObservableAnalyzerTest.cs)
  4. Update Diagnostic.nuspec with new rule ID and increment version for NuGet distribution (Analyzer/UniRxAnalyzer/UniRxAnalyzer/Diagnostic.nuspec)

🔧Why these technologies

  • Reactive Extensions (Rx) pattern — Provides composable, declarative async/event handling without callback hell; avoids iOS IL2CPP compatibility issues of official Rx
  • IDisposable/Disposable pattern — Deterministic resource cleanup for subscriptions; prevents memory leaks in long-running games with many observers
  • Roslyn static analyzers — Compile-time detection of unhandled observables prevents subscription leaks from shipping to production
  • MainThreadScheduler — Ensures observable callbacks execute on Unity's main thread; critical for safe GameObject/MonoBehaviour manipulation
  • NuGet packaging — Cross-platform distribution for PC/Mac/Android/iOS/WebGL; standardized dependency management

⚖️Trade-offs already made

  • Reimplementation vs. wrapping official Rx

    • Why: Official Rx has iOS IL2CPP incompatibility and lacks Unity-specific features like MainThreadScheduler
    • Consequence: Maintenance burden of parallel Rx codebase, but eliminates runtime compatibility issues and enables game-specific optimizations
  • Cold observables (subscription-driven) as default

    • Why: Matches Rx specification and allows per-subscriber resource allocation
    • Consequence: Observable setup code re-runs for each subscriber; developers must understand subscription semantics
  • Manual IDisposable management required by consumers

    • Why: Provides explicit control and deterministic cleanup timing
    • Consequence: Higher risk of subscription leaks if developers forget to dispose; Roslyn analyzer mitigates but requires adoption
  • Coroutine-to-Observable bridge (FromCoroutine)

    • Why: Allows gradual migration from legacy coroutine code to reactive patterns
    • Consequence: Adds abstraction overhead; not suitable for performance-critical per-frame logic

🚫Non-goals (don't propose these)

  • Real-time hot-reload of game code during play
  • Automatic memory management without explicit disposal
  • Direct support for C# async/await (separate UniRx.Async package)
  • Thread-safe cross-thread observable composition (designed for single-threaded Unity main thread)
  • Fluent UI builder DSL (framework only provides ReactiveProperty binding primitives)

🪤Traps & gotchas

No build-time or runtime dependencies declared, but the library requires .NET Framework 3.5+ compatibility for IL2CPP (check Unity version constraints: 2018.3+). The Analyzer is a separate Visual Studio extension (.vsix) and must be installed separately for IDE warnings. No environment variables or external services required. Coroutine integration (FromCoroutine) is Unity-specific and will fail outside the game loop context.

🏗️Architecture

💡Concepts to learn

  • Observable/IObserver Pattern — The foundation of UniRx—understanding push-based event streams (Observable) and their consumers (IObserver) is essential to using or extending the library
  • Scheduler Abstraction — UniRx provides MainThreadScheduler and other schedulers to ensure thread safety in Unity's single-threaded engine; critical for avoiding race conditions and IL2CPP issues
  • Reactive Composition / LINQ Operators — UniRx chains observables through map, filter, merge, etc. using LINQ syntax—this composability solves the monolithic coroutine problem in Unity
  • IDisposable Subscription Management — Observables must be unsubscribed to prevent memory leaks; the Analyzer checks for unhandled IDisposable returns, a UniRx-specific pain point in Unity
  • IL2CPP Compatibility — UniRx was designed to work with Unity's IL2CPP ahead-of-time compiler used on mobile; the official Rx did not, making this a core differentiator
  • Roslyn Analyzers — The HandleObservableAnalyzer (Analyzer/) provides compile-time diagnostics for UniRx best practices, catching subscription leaks before runtime
  • Hot vs. Cold Observables — UniRx distinguishes between ReplaySubject (hot, caches), Observable.Create (cold, lazy)—understanding this prevents missed events or unexpected subscriptions in game loops
  • Cysharp/R3 — Officially recommended successor to UniRx with modern C#, better performance, and full async/await integration—use this for new Unity projects
  • Cysharp/UniTask — Companion async/await library for Unity (separated from UniRx v7.0+); provides lightweight task-based async patterns complementary to observables
  • reactivex/rx.net — Official Reactive Extensions for .NET—UniRx is a port of this but with Unity-specific adaptations and IL2CPP compatibility fixes
  • dotnet/reactive — Modern successor to Rx.NET under .NET Foundation; provides reference implementations and API design that UniRx follows
  • facebook/RxJava — Java/Android port of Rx from the same family; useful for understanding Rx design patterns and operator semantics across languages

🪄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 UniRxAnalyzer.HandleObservableAnalyzer

The analyzer exists (Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs) but HandleObservableAnalyzerTest.cs appears minimal. This analyzer is critical for catching unsubscribed observables—a common source of memory leaks in Rx code. Expanding test coverage with edge cases (nested subscriptions, disposable patterns, async operations) would prevent regressions and improve code quality for all users.

  • [ ] Review HandleObservableAnalyzer.cs to understand all diagnostic codes and rules it enforces
  • [ ] Expand Analyzer/UniRxAnalyzer/UniRxAnalyzer.Test/HandleObservableAnalyzerTest.cs with test cases for: chained subscriptions, using statements, IDisposable patterns, and false-positive scenarios
  • [ ] Add integration tests that verify the analyzer correctly identifies unhandled observables in realistic Unity subscription patterns

Add GitHub Actions CI workflow for multi-platform .NET assembly builds

The repo has CircleCI config (.circleci/config.yml) but no GitHub Actions workflow. Given UniRx targets multiple platforms (PC/Mac/Android/iOS/WebGL), adding a GitHub Actions workflow to build and test both the main assembly (Assembly-CSharp.csproj) and the analyzer (Analyzer/UniRxAnalyzer/UniRxAnalyzer.csproj) on each PR would catch cross-platform compatibility issues early, especially around IL2CPP edge cases mentioned in the README.

  • [ ] Create .github/workflows/build.yml to compile Assembly-CSharp.csproj and verify no breaking changes
  • [ ] Add build step for Analyzer/UniRxAnalyzer/UniRxAnalyzer.csproj and run Analyzer/UniRxAnalyzer/UniRxAnalyzer.Test tests
  • [ ] Configure matrix builds for .NET Framework 4.6+ and ensure NuGet dependencies resolve correctly

Document analyzer rules and add code-fix examples in Docs section

The analyzer has tools/install.ps1 and tools/uninstall.ps1, plus Diagnostic.nuspec, but there's no documentation explaining what HandleObservableAnalyzer detects or how developers should fix violations. Since the README redirects users to R3 but this repo is still maintained, adding a ANALYZER.md documenting each diagnostic code (e.g., 'URX001: Observable not subscribed') with before/after code examples would help existing users understand and fix warnings.

  • [ ] Create Analyzer/ANALYZER.md documenting all diagnostic codes emitted by HandleObservableAnalyzer.cs
  • [ ] Include concrete C# examples showing problematic patterns and recommended fixes (e.g., using 'AddTo()' pattern, proper Dispose)
  • [ ] Add reference to analyzer docs in the main README.md under a 'Tools & Analyzers' section

🌿Good first issues

  • Add unit tests for edge cases in Analyzer/UniRxAnalyzer/UniRxAnalyzer.Test/HandleObservableAnalyzerTest.cs (currently only one test file visible)—test disposal patterns, nested subscriptions, and error cases
  • Document scheduler selection patterns: create a guide in the repo explaining when to use MainThreadScheduler vs. ThreadPoolScheduler vs. ImmediateScheduler for different Unity scenarios (network I/O, physics, animations)
  • Extend HandleObservableAnalyzer to detect 'fire-and-forget' subscriptions in MonoBehaviour.OnDestroy (common memory leak pattern in Unity); add test cases in the .Test project

Top contributors

Click to expand

📝Recent commits

Click to expand

🔒Security observations

The UniRx codebase presents moderate security concerns primarily due to its unmaintained status and outdated target platform specifications. The library is no longer actively developed, with the author recommending migration to the successor project Cysharp/R3. Key risks include lack of security patch updates, outdated Unity version targets, and potential unpatched vulnerabilities in dependencies. The codebase structure itself does not show obvious injection vulnerabilities, hardcoded credentials, or exposed secrets based on the provided file listing. However, the deprecated status significantly impacts the overall security posture. Organizations using this library should prioritize migration to maintained alternatives or conduct thorough security audits if continued use is necessary. The empty dependencies declaration reduces direct dependency risks but makes it difficult to assess the full attack surface.

  • Medium · Outdated Unity Target Version — Package.json - unity field. The package specifies Unity 2018.3 as the minimum version, which is significantly outdated (released in 2018). This version is no longer supported and may contain unpatched security vulnerabilities in the Unity engine itself. Fix: Update the minimum Unity version to a currently supported LTS version (e.g., 2020.3 LTS or later) and test compatibility accordingly.
  • Medium · Deprecated Project Detected - Unmaintained Library — README.md. The README explicitly states that the author has started distributing an evolved version in Cysharp/R3 and recommends using it instead. This indicates UniRx is no longer actively maintained. Using unmaintained libraries can pose security risks due to lack of security patches and bug fixes. Fix: Migrate to the actively maintained Cysharp/R3 library as recommended by the original author, or thoroughly audit UniRx for vulnerabilities before continued use.
  • Low · Missing Dependency Version Pinning — Package.json - dependencies field. The package.json shows an empty dependencies object. While this reduces dependency chain attack surface, it's unusual for a library of this complexity. If there are undeclared runtime dependencies, they could be missed during security audits. Fix: Explicitly document all dependencies with specific versions. If there are truly no external dependencies, document this decision and maintain it.
  • Low · NuGet Build Artifacts in Repository — .nuget/ directory. The .nuget directory contains NuGet.exe and configuration files. Storing build tools in the repository can increase repository size and may pose maintenance issues, though it's a relatively low security risk. Fix: Consider using NuGet restoration tools instead of committing binaries. Document the build process clearly.
  • Low · Visual Studio Metadata in Repository — .vs/ directory. The .vs directory containing Visual Studio cache and metadata files is present in the repository. This should typically be gitignored to prevent committing user-specific or generated files. Fix: Add .vs/ directory to .gitignore if not already present, and remove from repository history.

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.

Mixed signals · neuecc/UniRx — RepoPilot