$npx -y skills add samber/cc-skills-golang --skill golang-samber-roReactive streams and event-driven programming in Golang using samber/ro — ReactiveX implementation with 150+ type-safe operators, cold/hot observables, 5 subject types (Publish, Behavior, Replay, Async, Unicast), declarative pipelines via Pipe, 40+ plugins (HTTP, cron, fsnotify,
| 1 | **Persona:** You are a Go engineer who reaches for reactive streams when data flows asynchronously or infinitely. You use samber/ro to build declarative pipelines instead of manual goroutine/channel wiring, but you know when a simple slice + samber/lo is enough. |
| 2 | |
| 3 | **Thinking mode:** Use `ultrathink` when designing advanced reactive pipelines or choosing between cold/hot observables, subjects, and combining operators. Wrong architecture leads to resource leaks or missed events. |
| 4 | |
| 5 | # samber/ro — Reactive Streams for Go |
| 6 | |
| 7 | Go implementation of [ReactiveX](https://reactivex.io/). Generics-first, type-safe, composable pipelines for asynchronous data streams with automatic backpressure, error propagation, context integration, and resource cleanup. 150+ operators, 5 subject types, 40+ plugins. |
| 8 | |
| 9 | **Official Resources:** |
| 10 | |
| 11 | - [github.com/samber/ro](https://github.com/samber/ro) |
| 12 | - [ro.samber.dev](https://ro.samber.dev) |
| 13 | - [pkg.go.dev/github.com/samber/ro](https://pkg.go.dev/github.com/samber/ro) |
| 14 | |
| 15 | This skill is not exhaustive. Please refer to library documentation and code examples for more information. For Go package docs, symbols, versions, importers, and known vulnerabilities, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`) — prefer it over Context7 for Go package facts. To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See `samber/cc-skills-golang@golang-gopls` skill (`gopls`). Context7 remains a fallback for docs not indexed on pkg.go.dev. |
| 16 | |
| 17 | ## Why samber/ro (Streams vs Slices) |
| 18 | |
| 19 | Go channels + goroutines become unwieldy for complex async pipelines: manual channel closures, verbose goroutine lifecycle, error propagation across nested selects, and no composable operators. `samber/ro` solves this with declarative, chainable stream operators. |
| 20 | |
| 21 | **When to use which tool:** |
| 22 | |
| 23 | | Scenario | Tool | Why | |
| 24 | | --- | --- | --- | |
| 25 | | Transform a slice (map, filter, reduce) | `samber/lo` | Finite, synchronous, eager — no stream overhead needed | |
| 26 | | Simple goroutine fan-out with error handling | `errgroup` | Standard lib, lightweight, sufficient for bounded concurrency | |
| 27 | | Infinite event stream (WebSocket, tickers, file watcher) | `samber/ro` | Declarative pipeline with backpressure, retry, timeout, combine | |
| 28 | | Real-time data enrichment from multiple async sources | `samber/ro` | CombineLatest/Zip compose dependent streams without manual select | |
| 29 | | Pub/sub with multiple consumers sharing one source | `samber/ro` | Hot observables (Share/Subjects) handle multicast natively | |
| 30 | |
| 31 | **Key differences: lo vs ro** |
| 32 | |
| 33 | | Aspect | `samber/lo` | `samber/ro` | |
| 34 | | --- | --- | --- | |
| 35 | | Data | Finite slices | Infinite streams | |
| 36 | | Execution | Synchronous, blocking | Asynchronous, non-blocking | |
| 37 | | Evaluation | Eager (allocates intermediate slices) | Lazy (processes items as they arrive) | |
| 38 | | Timing | Immediate | Time-aware (delay, throttle, interval, timeout) | |
| 39 | | Error model | Return `(T, error)` per call | Error channel propagates through pipeline | |
| 40 | | Use case | Collection transforms | Event-driven, real-time, async pipelines | |
| 41 | |
| 42 | ## Installation |
| 43 | |
| 44 | ```bash |
| 45 | go get github.com/samber/ro |
| 46 | ``` |
| 47 | |
| 48 | ## Core Concepts |
| 49 | |
| 50 | Four building blocks: |
| 51 | |
| 52 | 1. **Observable** — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch |
| 53 | 2. **Observer** — a consumer with three callbacks: `onNext(T)`, `onError(error)`, `onComplete()` |
| 54 | 3. **Operator** — a function that transforms an observable into another observable, chained via `Pipe` |
| 55 | 4. **Subscription** — the connection between observable and observer. Call `.Wait()` to block or `.Unsubscribe()` to cancel |
| 56 | |
| 57 | ```go |
| 58 | observable := ro.Pipe2( |
| 59 | ro.RangeWithInterval(0, 5, 1*time.Se |