A Go toolkit for building concurrent programs using composable, channel-based pipelines with automatic error propagation.
Rill is a lightweight Go library that simplifies concurrent programming by providing composable functions that operate on channels. It enables developers to build complex concurrent pipelines from simple, reusable parts while preserving Go's natural channel semantics and backpressure behavior. The library reduces boilerplate and provides structured error handling and concurrency control for channel-based operations.
Go developers building concurrent applications that involve stream processing, parallel job execution, or real-time event handling, especially those who want to manage goroutines and channels with less boilerplate. It's suitable for engineers working on data pipelines, API integrations, or systems requiring ordered fan-in and batching.
Developers choose Rill over alternatives because it offers a composable, channel-centric API that integrates seamlessly with Go's concurrency model, providing automatic error propagation, fine-grained concurrency control, and support for infinite streams without external dependencies. Its unique selling point is enabling complex pipeline topologies (DAGs) with reusable functions while maintaining backpressure and context integration.
Go toolkit for clean, composable, channel-based concurrency
Open-Awesome is built by the community, for the community. Submit a project, suggest an awesome list, or help improve the catalog on GitHub.
Functions take and return channels, enabling Unix-like piping that reduces boilerplate and enhances code clarity, as shown in the quick start example with chained Map and ForEach operations.
Each operation allows specifying concurrency levels, such as parallel mapping with configurable worker counts, giving precise control over resource usage without manual goroutine management.
Errors automatically flow through pipelines and can be handled in a single place via blocking functions like Err or ForEach, simplifying error handling compared to scattered error channels.
With zero external dependencies and a small API, Rill is easy to integrate into existing Go projects without adding bloat, as emphasized in the features section.
Supports batching, ordered fan-in, and flatMap for complex scenarios like real-time data processing with timeout-based batching, demonstrated in the README examples.
Rill is context-agnostic, requiring developers to explicitly handle context cancellation in user-defined functions, adding boilerplate for proper pipeline termination and error handling.
Heavy reliance on Go channel semantics means users must understand channel behavior, backpressure, and goroutine lifecycle to avoid leaks or deadlocks, which can be challenging for newcomers.
As a dependency-free library, Rill doesn't integrate with third-party concurrency frameworks or tools, potentially necessitating custom code for advanced use cases like distributed tracing.
For trivial concurrency tasks, the pipeline abstraction can introduce unnecessary complexity and slight performance overhead compared to direct goroutine and channel usage.