Cats: Where to start?

I know, I always say, I want to reduce external dependencies, but as it appears, Cats has solutions for many things in Scala.

I had a look at the Cats documentation and I walked through the tutorial of Cats Effects, but that was not much more than copy&paste and seeing what happens.

How did you start using Cats? And, even more important, how did you start to integrate it into existing codebases? Is it a good idea to just replace certain parts with Cats or should the whole application be re-developed around it? I feel a little lost but would like to start utilizing this library.

If here is not the right place to ask and talk about Cats, please let me know and I look into finding another forum, more suitable for this kind of topic.

Thank you all in advance!

1 Like

cats is a plain library and can be introduced to any existing application. It tends to spread like a wildfire, but organically so. :slight_smile: The book probably is a good start.

cats-effect is more framework-y. It is built on top of cats and it pretty much wants you to go all-in - if you use it, your main class is going to be an IOApp and all side-effecting code should be captured inside the corresponding abstractions. Of course you can interface with Future, etc., and you can call cats-effect code from plain Scala code, but at the end of the day you want your whole app to be in cats-effect.

I’d suggest to start with plain cats, experiment with standalone snippets, then gradually introduce it to some actual project. Once - or: if :wink: - you feel comfortable with cats, you can start looking into cats-effect.


Complementing @sangamon answer, I would like to share my story with the typelevel ecosystem, it may

During my first years learning Scala I found myself searching and searching again and again how to combine two Maps[String, Int] where for the same keys I wanted the values to be added together.
And the best answer was “Use the Monoid operator |+| provided by cats (actually scalaz by that time, but whatever)”. However, I always thought that adding a “big” library just for one method was not a good idea (I somewhat now regret that decision, because it wouldn’t have been just one thing).

At some point, I found myself with the necessity to encode some case classes as JSONs and send those through an HTTP endpoint. After googling I found that I could use circe for the first and http4s for the second and that it supported the former out of the box. Nevertheless, that implied using a lot of things like the mysterious IO monad and of course having cats in scope.
That moment was an inflexion point for me, I joined the gitter channel, started to watch a lot of talks, read the “Scala with cats” book, etc (it was also what later impulses me to answer questions like this one, or in SO; and to contribute to OSS projects. But, that is another story).

In summary, I first just read enough to make the code compile but then I got interested in this functional approach of doing things and wanted to understand even more. I started to use functions provided by cats in my code, i started to use the IO thing for more things and eventually I switched my main to be using IOApp. And then the next project I started I used cats-effect right from the beginning.


I agree that you may just add cats to a codebase and use it as a tool-box library (similar to the apache commons / utils in Java). As you become more familiar with the library you will see that you can use it in more places.

Latter, you may look into cats-effect, understand why it exists and which problems does it solves. If you are sold on the ideas of referential transparency & composition and agree that an IO Monad is a good way to handle side effects, then things like fs2, http4s, refined, shapeless, etc all make sense; since at the end all aim to the same objective, making it easier to reason about your code.