Top Related Projects
Asynchronous, Reactive Programming for Scala and Scala.js.
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Non-Blocking Reactive Foundation for the JVM
A boilerplate-free library for loading configuration files
Quick Overview
fs2 is a functional, effectful, and concurrent streaming library for Scala. It provides a set of abstractions and primitives for working with streams of data, allowing developers to build complex, composable, and efficient streaming applications.
Pros
- Functional and Composable: fs2 is built on a functional programming model, allowing developers to compose small, reusable stream processing components into larger, more complex applications.
- Concurrency and Parallelism: fs2 supports concurrent and parallel stream processing, enabling efficient utilization of system resources.
- Powerful Abstractions: fs2 provides a rich set of abstractions and primitives for working with streams, such as
Stream
,Pipe
, andResource
, which simplify the development of streaming applications. - Ecosystem Integration: fs2 integrates well with other Scala libraries and frameworks, such as Cats, Monix, and Akka, allowing developers to leverage a wide range of tools and libraries.
Cons
- Steep Learning Curve: The functional and concurrent nature of fs2 can make it challenging for developers new to functional programming and stream processing to get started.
- Performance Overhead: The abstraction and flexibility provided by fs2 may come with some performance overhead, especially for simple stream processing tasks.
- Limited Adoption: While fs2 is a popular library in the Scala ecosystem, it may not have the same level of adoption and community support as some other streaming libraries, such as Akka Streams.
- Complexity: The rich set of abstractions and features in fs2 can make it complex to understand and use, especially for more advanced use cases.
Code Examples
Here are a few examples of how to use fs2:
- Creating a simple stream:
import cats.effect.IO
import fs2.Stream
val simpleStream: Stream[IO, Int] = Stream.range(1, 11)
This creates a simple stream of integers from 1 to 10.
- Transforming a stream:
import cats.effect.IO
import fs2.Stream
val doubledStream: Stream[IO, Int] = Stream.range(1, 11).map(_ * 2)
This transforms the stream of integers by doubling each value.
- Combining streams:
import cats.effect.IO
import fs2.Stream
val firstStream: Stream[IO, Int] = Stream.range(1, 6)
val secondStream: Stream[IO, Int] = Stream.range(6, 11)
val combinedStream: Stream[IO, Int] = firstStream ++ secondStream
This combines two streams of integers into a single stream.
- Consuming a stream:
import cats.effect.IO
import fs2.Stream
val stream: Stream[IO, Int] = Stream.range(1, 11)
val result: IO[List[Int]] = stream.compile.toList
This consumes the stream of integers and collects the values into a list.
Getting Started
To get started with fs2, you can add the following dependency to your build.sbt
file:
libraryDependencies += "co.fs2" %% "fs2-core" % "3.2.4"
Then, you can import the necessary modules and start working with streams:
import cats.effect.IO
import fs2.Stream
val simpleStream: Stream[IO, Int] = Stream.range(1, 11)
val result: IO[List[Int]] = simpleStream.compile.toList
This will create a simple stream of integers from 1 to 10 and then collect the values into a list.
For more detailed information and examples, please refer to the fs2 documentation.
Competitor Comparisons
Asynchronous, Reactive Programming for Scala and Scala.js.
Pros of Monix
- Broader scope, offering a comprehensive toolkit for asynchronous programming
- Includes additional features like Task, Coeval, and reactive extensions
- Generally faster performance in benchmarks
Cons of Monix
- Steeper learning curve due to its larger API surface
- Less focus on pure functional programming principles
- Smaller community and ecosystem compared to FS2
Code Comparison
Monix Observable:
import monix.reactive.Observable
val obs = Observable.range(1, 10)
.map(_ * 2)
.filter(_ % 4 == 0)
FS2 Stream:
import fs2.Stream
val stream = Stream.range(1, 10)
.map(_ * 2)
.filter(_ % 4 == 0)
Both libraries provide similar functionality for creating and manipulating streams of data. The main differences lie in the broader ecosystem and design philosophy. Monix offers a more comprehensive toolkit for asynchronous programming, while FS2 focuses on pure functional streaming with a simpler API. The choice between them often depends on specific project requirements and team preferences.
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Pros of RxJava
- Extensive ecosystem and wide adoption across various platforms
- Rich set of operators for complex stream transformations
- Strong support for multithreading and concurrency
Cons of RxJava
- Steeper learning curve due to its large API surface
- Can be verbose for simple use cases
- Potential for memory leaks if not used carefully
Code Comparison
RxJava:
Observable.just(1, 2, 3, 4, 5)
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.subscribe(System.out::println);
fs2:
Stream(1, 2, 3, 4, 5)
.filter(_ % 2 == 0)
.map(_ * 2)
.foreach(println)
Key Differences
- fs2 is more focused on pure functional programming principles
- RxJava offers a broader range of operators and utilities
- fs2 integrates well with other Typelevel ecosystem libraries
- RxJava has better support for backpressure handling
Use Cases
- RxJava: Android development, reactive programming in Java ecosystems
- fs2: Scala projects, functional stream processing, integration with Cats
Both libraries provide powerful tools for stream processing and reactive programming, but cater to different programming paradigms and ecosystems.
Non-Blocking Reactive Foundation for the JVM
Pros of Reactor Core
- Designed for Java, offering seamless integration with Java ecosystem
- Extensive documentation and larger community support
- Built-in support for backpressure handling
Cons of Reactor Core
- Steeper learning curve due to more complex API
- Less functional programming paradigm compared to FS2
- Heavier runtime overhead in some scenarios
Code Comparison
FS2 (Scala):
import fs2.Stream
val stream = Stream(1, 2, 3)
.map(_ * 2)
.filter(_ > 3)
.fold(0)(_ + _)
Reactor Core (Java):
import reactor.core.publisher.Flux;
Flux<Integer> flux = Flux.just(1, 2, 3)
.map(i -> i * 2)
.filter(i -> i > 3)
.reduce(0, Integer::sum);
Both FS2 and Reactor Core are powerful libraries for reactive programming, but they cater to different ecosystems and programming paradigms. FS2 is more functional and Scala-oriented, while Reactor Core is designed for Java developers and offers a more imperative style. The choice between them often depends on the project's language, team expertise, and specific requirements.
A boilerplate-free library for loading configuration files
Pros of PureConfig
- Focused on configuration parsing and loading, making it more specialized for this task
- Supports a wide range of configuration formats (HOCON, JSON, YAML, Properties)
- Automatic derivation of config readers for case classes and sealed traits
Cons of PureConfig
- Limited to configuration handling, not a general-purpose streaming library
- May require additional dependencies for certain config formats
- Less flexibility for complex data processing scenarios
Code Comparison
PureConfig:
import pureconfig._
import pureconfig.generic.auto._
case class AppConfig(host: String, port: Int)
val config = ConfigSource.default.load[AppConfig]
FS2:
import fs2._
val stream = Stream.emit(1).repeat.take(5)
stream.compile.toList // List(1, 1, 1, 1, 1)
Key Differences
- Purpose: PureConfig is for configuration management, while FS2 is a streaming library
- Scope: PureConfig is more focused, FS2 is more general-purpose
- Use cases: PureConfig for app configuration, FS2 for data processing and I/O operations
- Learning curve: PureConfig may be easier to learn for its specific use case, while FS2 has a broader API to master
Conclusion
Choose PureConfig for straightforward configuration management in Scala projects. Opt for FS2 when dealing with streaming data, complex I/O operations, or building reactive applications. For projects requiring both configuration management and streaming capabilities, consider using both libraries together.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
FS2: Functional Streams for Scala
Overview
FS2 is a library for purely functional, effectful, and polymorphic stream processing library in the Scala programming language. Its design goals are compositionality, expressiveness, resource safety, and speed. The name is a modified acronym for Functional Streams for Scala (FSS, or FS2).
FS2 is available for Scala 2.12, Scala 2.13, Scala 3, and Scala.js and Scala Native.
FS2 is built upon two major functional libraries for Scala, Cats, and Cats-Effect.
Regardless of those dependencies, FS2 core types (streams and pulls) are polymorphic in the effect type (as long as it is compatible with cats-effect
typeclasses),
and thus FS2 can be used with other effect libraries, such as Monix.
Getting Started
Quick links:
Documentation and getting help
- There are Scaladoc API documentations for the library.
- The official guide is a good starting point for learning more about the library.
- The documentation page is intended to serve as a list of all references, including conference presentation recordings, academic papers, and blog posts, on the use and implementation of
fs2
. - The FAQ has frequently asked questions. Feel free to open issues or PRs with additions to the FAQ!
- Also feel free to come discuss and ask/answer questions in the Typelevel Discord channel and/or on StackOverflow using the tag FS2. Discord will generally get you a quicker answer.
Projects using FS2
You can find a list of libraries and integrations with data stores built on top of FS2 here: https://fs2.io/#/ecosystem.
If you have a project you'd like to include in this list, please open a PR or let us know in the Discord channel and we'll add a link to it.
Acknowledgments
Special thanks to YourKit for supporting this project's ongoing performance tuning efforts with licenses to their excellent product.
Code of Conduct
See the Code of Conduct.
Top Related Projects
Asynchronous, Reactive Programming for Scala and Scala.js.
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Non-Blocking Reactive Foundation for the JVM
A boilerplate-free library for loading configuration files
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot