Source profileQuality 92/100Review permissions

omarluq/librecode/.librecode/skills/golang-samber-ro/SKILL.md

golang-samber-ro

Reactive 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, JSON, logging), automatic backpressure, error propagation, and Go context integration. Apply when using or adopting samber/ro, when the codebase imports github.com/samber/ro, or when building asynchronous event-driven pi

Source repository stars
29
Declared platforms
1
Static risk flags
1
Last source update
2026-08-25
Source checked
2026-08-25

Decision brief

What it does: where it fits

Go implementation of ReactiveX. 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.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeDeclaredSource recordInstall path and trigger
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/omarluq/librecode --skill ".librecode/skills/golang-samber-ro"
    Safe inspection promptEditorial

    Inspect the Agent Skill "golang-samber-ro" from https://github.com/omarluq/librecode/blob/55976d67b4363001b349a5adb9f9b87b27d0bfcd/.librecode/skills/golang-samber-ro/SKILL.md at commit 55976d67b4363001b349a5adb9f9b87b27d0bfcd. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Why samber/ro (Streams vs Slices)

      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.

      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 wit…Key differences: lo vs ro
    2. 02

      Installation

      Review the “Installation” section in the pinned source before continuing.

      Review and apply the “Installation” source section.
    3. 03

      Core Concepts

      1. Observable — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch 2. Observer — a consumer with three callbacks: onNext(T), onError(error), onComplete() 3. Operator — a function that transforms an observable i…

      Observable — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratchObserver — a consumer with three callbacks: onNext(T), onError(error), onComplete()Operator — a function that transforms an observable into another observable, chained via Pipe
    4. 04

      Cold vs Hot Observables

      Cold (default): each .Subscribe() starts a new independent execution. Safe and predictable — use by default.

      Cold (default): each .Subscribe() starts a new independent execution. Safe and predictable — use by default.Hot: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.For subject details and hot observable patterns, see Subjects Guide.
    5. 05

      Operator Quick Reference

      Use typed Pipe2, Pipe3 ... Pipe25 for compile-time type safety across operator chains. The untyped Pipe uses any and loses type checking.

      Use typed Pipe2, Pipe3 ... Pipe25 for compile-time type safety across operator chains. The untyped Pipe uses any and loses type checking.For the complete operator catalog (150+ operators with signatures), see Operators Guide.

    Permission review

    Static risk signals and limitations

    Runs scripts

    medium · line 46

    The documentation asks the agent to run terminal commands or scripts.

    go get github.com/samber/ro

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score92/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars29SourceRepository attention, not individual Skill quality
    Compatibility1 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    omarluq/librecode
    Skill path
    .librecode/skills/golang-samber-ro/SKILL.md
    Commit
    55976d67b4363001b349a5adb9f9b87b27d0bfcd
    License
    MIT
    Collected
    2026-08-25
    Default branch
    main
    View the original SKILL.md

    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.

    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.

    samber/ro — Reactive Streams for Go

    Go implementation of ReactiveX. 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.

    Official Resources:

    This skill is not exhaustive. Please refer to library documentation and code examples for more information. Context7 can help as a discoverability platform.

    Why samber/ro (Streams vs Slices)

    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.

    When to use which tool:

    ScenarioToolWhy
    Transform a slice (map, filter, reduce)samber/loFinite, synchronous, eager — no stream overhead needed
    Simple goroutine fan-out with error handlingerrgroupStandard lib, lightweight, sufficient for bounded concurrency
    Infinite event stream (WebSocket, tickers, file watcher)samber/roDeclarative pipeline with backpressure, retry, timeout, combine
    Real-time data enrichment from multiple async sourcessamber/roCombineLatest/Zip compose dependent streams without manual select
    Pub/sub with multiple consumers sharing one sourcesamber/roHot observables (Share/Subjects) handle multicast natively

    Key differences: lo vs ro

    Aspectsamber/losamber/ro
    DataFinite slicesInfinite streams
    ExecutionSynchronous, blockingAsynchronous, non-blocking
    EvaluationEager (allocates intermediate slices)Lazy (processes items as they arrive)
    TimingImmediateTime-aware (delay, throttle, interval, timeout)
    Error modelReturn (T, error) per callError channel propagates through pipeline
    Use caseCollection transformsEvent-driven, real-time, async pipelines

    Installation

    go get github.com/samber/ro
    

    Core Concepts

    Four building blocks:

    1. Observable — a data source that emits values over time. Cold by default: each subscriber triggers independent execution from scratch
    2. Observer — a consumer with three callbacks: onNext(T), onError(error), onComplete()
    3. Operator — a function that transforms an observable into another observable, chained via Pipe
    4. Subscription — the connection between observable and observer. Call .Wait() to block or .Unsubscribe() to cancel
    observable := ro.Pipe2(
        ro.RangeWithInterval(0, 5, 1*time.Second),
        ro.Filter(func(x int) bool { return x%2 == 0 }),
        ro.Map(func(x int) string { return fmt.Sprintf("even-%d", x) }),
    )
    
    observable.Subscribe(ro.NewObserver(
        func(s string) { fmt.Println(s) },      // onNext
        func(err error) { log.Println(err) },    // onError
        func() { fmt.Println("Done!") },         // onComplete
    ))
    // Output: "even-0", "even-2", "even-4", "Done!"
    
    // Or collect synchronously:
    values, err := ro.Collect(observable)
    

    Cold vs Hot Observables

    Cold (default): each .Subscribe() starts a new independent execution. Safe and predictable — use by default.

    Hot: multiple subscribers share a single execution. Use when the source is expensive (WebSocket, DB poll) or subscribers must see the same events.

    Convert withBehavior
    Share()Cold → hot with reference counting. Last unsubscribe tears down
    ShareReplay(n)Same as Share + buffers last N values for late subscribers
    Connectable()Cold → hot, but waits for explicit .Connect() call
    SubjectsNatively hot — call .Send(), .Error(), .Complete() directly
    SubjectConstructorReplay behavior
    PublishSubjectNewPublishSubject[T]()None — late subscribers miss past events
    BehaviorSubjectNewBehaviorSubject[T](initial)Replays last value to new subscribers
    ReplaySubjectNewReplaySubject[T](bufferSize)Replays last N values
    AsyncSubjectNewAsyncSubject[T]()Emits only last value, only on complete
    UnicastSubjectNewUnicastSubject[T](bufferSize)Single subscriber only

    For subject details and hot observable patterns, see Subjects Guide.

    Operator Quick Reference

    CategoryKey operatorsPurpose
    CreationJust, FromSlice, FromChannel, Range, Interval, Defer, FutureCreate observables from various sources
    TransformMap, MapErr, FlatMap, Scan, Reduce, GroupByTransform or accumulate stream values
    FilterFilter, Take, TakeLast, Skip, Distinct, Find, First, LastSelectively emit values
    CombineMerge, Concat, Zip2Zip6, CombineLatest2CombineLatest5, RaceMerge multiple observables
    ErrorCatch, OnErrorReturn, OnErrorResumeNextWith, Retry, RetryWithConfigRecover from errors
    TimingDelay, DelayEach, Timeout, ThrottleTime, SampleTime, BufferWithTimeControl emission timing
    Side effectTap/Do, TapOnNext, TapOnError, TapOnCompleteObserve without altering stream
    TerminalCollect, ToSlice, ToChannel, ToMapConsume stream into Go types

    Use typed Pipe2, Pipe3 ... Pipe25 for compile-time type safety across operator chains. The untyped Pipe uses any and loses type checking.

    For the complete operator catalog (150+ operators with signatures), see Operators Guide.

    Common Mistakes

    MistakeWhy it failsFix
    Using ro.OnNext() without error handlerErrors are silently dropped — bugs hide in productionUse ro.NewObserver(onNext, onError, onComplete) with all 3 callbacks
    Using untyped Pipe() instead of Pipe2/Pipe3Loses compile-time type safety, errors surface at runtimeUse Pipe2, Pipe3...Pipe25 for typed operator chains
    Forgetting .Unsubscribe() on infinite streamsGoroutine leak — the observable runs foreverUse TakeUntil(signal), context cancellation, or explicit Unsubscribe()
    Using Share() when cold is sufficientUnnecessary complexity, harder to reason about lifecycleUse hot observables only when multiple consumers need the same stream
    Using samber/ro for finite slice transformsStream overhead (goroutines, subscriptions) for a synchronous operationUse samber/lo — it's simpler, faster, and purpose-built for slices
    Not propagating context for cancellationStreams ignore shutdown signals, causing resource leaks on terminationChain ContextWithTimeout or ThrowOnContextCancel in the pipeline

    Best Practices

    1. Always handle all three events — use NewObserver(onNext, onError, onComplete), not just OnNext. Unhandled errors cause silent data loss
    2. Use Collect() for synchronous consumption — when the stream is finite and you need []T, Collect blocks until complete and returns the slice + error
    3. Prefer typed Pipe functionsPipe2, Pipe3...Pipe25 catch type mismatches at compile time. Reserve untyped Pipe for dynamic operator chains
    4. Bound infinite streams — use Take(n), TakeUntil(signal), Timeout(d), or context cancellation. Unbounded streams leak goroutines
    5. Use Tap/Do for observability — log, trace, or meter emissions without altering the stream. Chain TapOnError for error monitoring
    6. Prefer samber/lo for simple transforms — if the data is a finite slice and you need Map/Filter/Reduce, use lo. Reach for ro when data arrives over time, from multiple sources, or needs retry/timeout/backpressure

    Plugin Ecosystem

    40+ plugins extend ro with domain-specific operators:

    CategoryPluginsImport path prefix
    EncodingJSON, CSV, Base64, Gobplugins/encoding/...
    NetworkHTTP, I/O, FSNotifyplugins/http, plugins/io, plugins/fsnotify
    SchedulingCron, ICSplugins/cron, plugins/ics
    ObservabilityZap, Slog, Zerolog, Logrus, Sentry, Oopsplugins/observability/..., plugins/samber/oops
    Rate limitingNative, Ululeplugins/ratelimit/...
    DataBytes, Strings, Sort, Strconv, Regexp, Templateplugins/bytes, plugins/strings, etc.
    SystemProcess, Signalplugins/proc, plugins/signal

    For the full plugin catalog with import paths and usage examples, see Plugin Ecosystem.

    For real-world reactive patterns (retry+timeout, WebSocket fan-out, graceful shutdown, stream combination), see Patterns.

    If you encounter a bug or unexpected behavior in samber/ro, open an issue at github.com/samber/ro/issues.

    Cross-References

    • → See samber/cc-skills-golang@golang-samber-lo skill for finite slice transforms (Map, Filter, Reduce, GroupBy) — use lo when data is already in a slice
    • → See samber/cc-skills-golang@golang-samber-mo skill for monadic types (Option, Result, Either) that compose with ro pipelines
    • → See samber/cc-skills-golang@golang-samber-hot skill for in-memory caching (also available as an ro plugin)
    • → See samber/cc-skills-golang@golang-concurrency skill for goroutine/channel patterns when reactive streams are overkill
    • → See samber/cc-skills-golang@golang-observability skill for monitoring reactive pipelines in production

    Frequently asked questions

    What to verify before installation and use

    What does the golang-samber-ro source document cover?

    Go implementation of ReactiveX. 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.

    How do I install golang-samber-ro?

    The source record exposes this install command: npx skills add https://github.com/omarluq/librecode --skill ".librecode/skills/golang-samber-ro". Inspect the command and pinned source before running it.

    Which Agent platforms does the source record declare?

    The pinned source record declares support for: claude code.

    Which permission-related actions were detected?

    Static rules flagged exec-script in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing