neuecc/UniRx
Reactive Extensions for Unity
Stale — last commit 2y ago
worst of 4 axeslast commit was 2y ago; top contributor handles 93% of recent commits…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 2y ago; no CI workflows detected
- ✓6 active contributors
- ✓MIT licensed
- ⚠Stale — last commit 2y ago
Show 3 more →Show less
- ⚠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 Concerns → Mixed if: 1 commit in the last 365 days
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy 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.
[](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:
- 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. - 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.
- 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 |
#!/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).
⚡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 operationsAssets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs— Fundamental resource management pattern for cleaning up subscriptions; required by all observable chainsAssets/Plugins/UniRx/Scripts/Disposables/CancellationDisposable.cs— Cancellation token pattern implementation; critical for subscription lifecycle managementAssets/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 platformsAnalyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs— Roslyn analyzer detecting unhandled observables; prevents common subscription memory leaks in production codeAssets/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
- 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) - Implement IObservable<T> return type using Observable.Create() to wrap the Unity callback/coroutine (
Assets/Plugins/UniRx/Examples/Sample02_ObservableTriggers.cs) - Ensure proper disposal via return of IDisposable; reference CompositeDisposable pattern for multi-step cleanup (
Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs) - 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
- Define ReactiveProperty<T> field matching Sample12_ReactiveProperty.cs pattern for two-way binding state (
Assets/Plugins/UniRx/Examples/Sample12_ReactiveProperty.cs) - Subscribe UI elements (buttons, toggles, text fields) using .Subscribe() and track with CompositeDisposable (
Assets/Plugins/UniRx/Scripts/Disposables/CompositeDisposable.cs) - Implement cleanup in OnDestroy() by calling .Dispose() on the CompositeDisposable (
Assets/Plugins/UniRx/Examples/Sample13_ToDoApp.cs)
Extend Roslyn Analyzer for Custom Observable Patterns
- Study existing HandleObservableAnalyzer.cs implementation to understand DiagnosticDescriptor and syntax tree analysis (
Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs) - Add new analyzer rule class inheriting from base analyzer pattern; register in DiagnosticAnalyzer attribute (
Analyzer/UniRxAnalyzer/UniRxAnalyzer/HandleObservableAnalyzer.cs) - Write unit tests in HandleObservableAnalyzerTest.cs following CodeFixVerifier pattern (
Analyzer/UniRxAnalyzer/UniRxAnalyzer.Test/HandleObservableAnalyzerTest.cs) - 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
🔗Related repos
Cysharp/R3— Officially recommended successor to UniRx with modern C#, better performance, and full async/await integration—use this for new Unity projectsCysharp/UniTask— Companion async/await library for Unity (separated from UniRx v7.0+); provides lightweight task-based async patterns complementary to observablesreactivex/rx.net— Official Reactive Extensions for .NET—UniRx is a port of this but with Unity-specific adaptations and IL2CPP compatibility fixesdotnet/reactive— Modern successor to Rx.NET under .NET Foundation; provides reference implementations and API design that UniRx followsfacebook/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
Top contributors
- @neuecc — 93 commits
- @shiena — 2 commits
- @TORISOUP — 2 commits
- @5argon — 1 commits
- @Reqweldzen — 1 commits
📝Recent commits
Click to expand
Recent commits
6baeccf— Update README.md (neuecc)7cce378— Update README.md (neuecc)284d5c5— Merge pull request #453 from shiena/upm (neuecc)ae0a082— Add UPM Package document (shiena)c244f9a— Add package.json (shiena)66205df— (neuecc)0cb5009— (neuecc)ce5e875— (neuecc)02d4bdf— (neuecc)e6fc1ed— (neuecc)
🔒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.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.