Scala in 2025

How to Start, What to Learn

Before we move on ☝️

Something too obvious? missing?
Let me know!

What is Scala?

  • Provides reliability through typesafety
  • Typed language that feels like dynamic one
  • Runs on JVM, JavaScript, and Native platforms

Academic Roots

  • Developed at EPFL, by Martin Odersky
  • Community-driven evolution rather than corporate interests

Why try Scala?

  1. Reliability through types
  2. Multi-Platform Support (JVM, JS, Native)
  3. Modern Features
  4. Ecosystem Diversity
  5. Career Growth

Is Scala still relevant?

Companies using Scala

Not a comprehensive list, last access 3.03.25, just a trainride of research 🚄

IDE Choice

IDE Choice: IntelliJ

  1. Download IntelliJ IDEA (Community or Ultimate)
  2. Install Scala plugin: Settings → Plugins → "Scala"

IntelliJ: Pros & Cons

✅ Familiar interface for Java/PyCharm users, rich features out of the box
❌ Compiler errors can be out of sync, non-open-source editor

IntelliJ: Install

https://www.jetbrains.com/help/idea/get-started-with-scala.html

IDE Choice: Metals

Language Server that works with VS Code, Vim, Emacs, and others.

Install through your editor's extension marketplace.

Metals: Pros & Cons

✅ Always in sync with compiler, supports latest features
❌ Experience varies between editors

Metals: Install

https://scalameta.org/metals/docs

Build Tools Overview

Manage dependencies, compile code, and run tests

scala-cli: The Simple Choice

  • ❌ Not technically a build tool
  • ✅ Nobody cares

scala-cli: The Simple Choice

Modern, user-friendly build tool designed for:

  • Single-file scripts
  • Small projects
  • Quick prototypes

scala-cli: Install

Just install Scala!

https://docs.scala-lang.org/getting-started/install-scala.html

scala-cli: Perfect for Learning

  1. // add dependencies
  2. //> using dep com.lihaoyi::pprint:0.9.0
  3. // define scala version
  4. //> using scala 3.3.5
  5. @main def hello() =
  6. pprint.log("No build config needed!")

scala-cli: Just run it

  1. # Run a single file
  2. scala Hello.scala
  3. scala-cli Hello.scala
  4. # ☝ if you installed from https://scala-cli.virtuslab.org/

sbt: The Power Tool

Industry standard build tool for:

  • Multi-module projects
  • Complex dependency management
  • Custom build tasks
  • Code generation

sbt: Project Structure

  1. build.sbt # build config
  2. project/
  3. build.properties # sbt version
  4. plugins.sbt # plugins
  5. src/
  6. main/
  7. scala/ # source code
  8. test/
  9. scala/ # test code

sbt: Configuration Example

  1. // build.sbt
  2. name := "my-project"
  3. version := "0.1.0"
  4. lazy val root = (project in file("."))
  5. .settings(
  6. scalaVersion := "3.3.1",
  7. libraryDependencies ++= Seq(
  8. "org.typelevel" %% "cats-effect" % "3.5.4",
  9. "org.scalatest" %% "scalatest" % "3.2.15" % Test
  10. )
  11. )

When to Use What?

    scala-cli
  • Learning Scala
  • Scripts & prototyping
  • Single-module applications
    sbt
  • Multi-module applications
  • Code generation
  • Managing CI/CD pipelines

Mill: Alternative

Flavors of Scala

Coding styles and frameworks

Cask: Flask but for Scala

Li Haoyi Style

Inspired by Python's Flask

https://com-lihaoyi.github.io/cask/

Li Haoyi Style: Getting Started

Create new directory and file:

  1. mkdir cask-demo
  2. cd cask-demo
  3. touch app.scala

Li Haoyi Style: Web Server with Cask

  1. //> using dep "com.lihaoyi::cask:0.9.2"
  2. object app extends cask.MainRoutes:
  3. @cask.post("/greet")
  4. def greet(name: String) = s"Hello, $name!"
  5. @cask.get("/users/:userId")
  6. def user(userId: Int) =
  7. val users = Map(1 -> "Alice", 2 -> "Bob")
  8. users.getOrElse(userId, "User not found")
  9. initialize()
  10. // Start server
  11. @main def run() =
  12. cask.main.Main.main(args = Array("app"))

Li Haoyi Style: Testing the API

Run with: scala-cli app.scala

  1. # Test the endpoints
  2. curl http://localhost:8080
  3. curl -X POST -d "name=John" http://localhost:8080/greet
  4. curl http://localhost:8080/users/1

Li Haoyi: Development platform

There's more: Scalatags, FastParse, uTest, uPickle, Ammonite, Sourcecode, Mill, PPrint, OS-Lib, Requests-Scala, Cask, MainArgs, ScalaSql

Read more in 12 years of the com.lihaoyi Scala Platform

Play Framework: Web Development

Full-stack framework with all of the components you need to build a Web Application or a REST service

Play Framework: Stack

Play Framework: Web Development

Start with sbt:

  1. sbt new play-scala-seed.g8
  2. cd play-scala-seed
  3. sbt run

Play Framework: Hello World

  1. // app/controllers/HelloController.scala
  2. package controllers
  3. import javax.inject._
  4. import play.api.mvc._
  5. @Singleton
  6. class HelloController @Inject()(val controllerComponents: ControllerComponents)
  7. extends BaseController {
  8. def hello() = Action { implicit request: Request[AnyContent] =>
  9. Ok("Hello, World!") // here goes your logic
  10. }
  11. }

Play Framework: Route Configuration

  1. # conf/routes
  2. GET /hello controllers.HelloController.hello()

Run sbt run and visit http://localhost:9000/hello to see your message!

Tapir

Programmer-friendly, reasonably type-safe API to expose, consume and document HTTP endpoints

Tapir: Dependencies

  1. //> using scala 3.6.3
  2. //> using dep com.softwaremill.sttp.tapir::tapir-http4s-server:1.11.15
  3. //> using dep org.http4s::http4s-ember-server:0.23.30
  4. //> using dep com.softwaremill.sttp.tapir::tapir-json-circe:1.11.15
  5. //> using dep ch.qos.logback:logback-classic:1.5.16

Tapir: Endpoint definition

  1. object Endpoints {
  2. val booksListing: PublicEndpoint[String, Unit, List[Book], Any] = endpoint.get
  3. .in("books" / "list" / query[String]("filter"))
  4. .out(jsonBody[List[Book]])
  5. val booksListingServerEndpoint: ServerEndpoint[Any, IO] =
  6. booksListing.serverLogicSuccess(filter => Library.books(filter))
  7. val all: List[ServerEndpoint[Any, IO]] = List(booksListingServerEndpoint)
  8. }
  9. object Library {
  10. case class Author(name: String)
  11. case class Book(title: String, year: Int, author: Author)
  12. def books(filter: String): IO[List[Book]] = /* irrelevant */
  13. }

Tapir: Main application

  1. object Main extends IOApp {
  2. override def run(args: List[String]): IO[ExitCode] =
  3. val routes = Http4sServerInterpreter[IO]().toRoutes(Endpoints.all)
  4. val port = sys.env
  5. .get("HTTP_PORT")
  6. .flatMap(_.toIntOption)
  7. .flatMap(Port.fromInt)
  8. .getOrElse(port"8080")
  9. EmberServerBuilder
  10. .default[IO]
  11. .withHost(Host.fromString("localhost").get)
  12. .withPort(port)
  13. .withHttpApp(Router("/" -> routes).orNotFound)
  14. .build
  15. .use{ server =>
  16. for
  17. _ <- IO.println(s"Server started at http://localhost:${server.address.getPort}. Press ENTER key to exit.")
  18. _ <- IO.readLine
  19. yield ()
  20. }.as(ExitCode.Success)
  21. }

Adopt Tapir!

https://adopt-tapir.softwaremill.com

Pekko

Concurrent, distributed, resilient systems with Actor model

Pekko: Actor Systems

Create new project:

  1. mkdir pekko-demo
  2. cd pekko-demo
  3. touch Counter.scala

Pekko: Message Protocol

  1. //> using dep "org.apache.pekko::pekko-actor-typed:1.0.2"
  2. import org.apache.pekko.actor.typed.{ActorRef, ActorSystem, Behavior}
  3. import org.apache.pekko.actor.typed.scaladsl.Behaviors
  4. object Counter:
  5. // Define messages our actor can receive
  6. enum Message:
  7. case Increment
  8. case GetValue(replyTo: ActorRef[Int])

Pekko: Actor Implementation

  1. object Counter:
  2. // Previous Message definition...
  3. def apply(): Behavior[Message] = counter(0)
  4. private def counter(value: Int): Behavior[Message] =
  5. Behaviors.receive { (context, message) =>
  6. message match
  7. case Message.Increment =>
  8. println(s"Incrementing counter to ${value + 1}")
  9. counter(value + 1)
  10. case Message.GetValue(replyTo) =>
  11. replyTo ! value
  12. Behaviors.same
  13. }

Pekko: Running the System

  1. @main def run() =
  2. // Create the actor system
  3. val system = ActorSystem(Counter(), "CounterSystem")
  4. // Create an actor to receive responses
  5. val printer = ActorSystem(
  6. Behaviors.receive[Int] { (context, msg) =>
  7. println(s"Current value: $msg")
  8. Behaviors.same
  9. },
  10. "printer"
  11. )
  12. // Send messages
  13. system ! Counter.Message.Increment
  14. system ! Counter.Message.Increment
  15. system ! Counter.Message.GetValue(printer.ref)
  16. // Keep the program running
  17. Thread.sleep(1000)
  18. // Shutdown
  19. system.terminate()
  20. printer.terminate()

Pekko: Running the Example

Run the program:

  1. scala-cli Counter.scala

Output:

  1. Incrementing counter to 1
  2. Incrementing counter to 2
  3. Current value: 2

Laminar: User Interfaces for Scala.js

Native Scala.js library for building user interfaces

Laminar: Example

Laminar: Example

  1. package example
  2. import com.raquo.laminar.api.L.{*, given}
  3. object CounterView {
  4. def apply(): HtmlElement = {
  5. div(
  6. cls("CounterView"),
  7. Counter(label = "Foo", initialStep = 1),
  8. )
  9. }
  10. /* Counter implementation */
  11. }

Laminar: Example

  1. package example
  2. import com.raquo.laminar.api.L.{*, given}
  3. object CounterView {
  4. def Counter(label: String, initialStep: Int): HtmlElement = {
  5. val allowedSteps = List(1, 2, 3, 5, 10)
  6. val stepVar = Var(initialStep)
  7. val diffBus = new EventBus[Int]
  8. val countSignal: Signal[Int] = diffBus.events.scanLeft(initial = 0)(_ + _)
  9. div(
  10. cls("Counter"),
  11. p(
  12. "Step: ",
  13. select(
  14. value <-- stepVar.signal.map(_.toString),
  15. onChange.mapToValue.map(_.toInt) --> stepVar,
  16. allowedSteps.map { step => option(value := step.toString, step) }
  17. )
  18. ),
  19. p(
  20. label + ": ",
  21. b(text <-- countSignal),
  22. " ",
  23. button("–", onClick.mapTo(-1 * stepVar.now()) --> diffBus),
  24. button("+", onClick(_.sample(stepVar.signal)) --> diffBus)
  25. )
  26. )
  27. }
  28. }

Laminar: Example

Scala.js: Resources

That's just the beginning!

Other Popular Flavors

  • Spark: Big data processing
  • Functional streams with FS2
  • Cats Effect: The pure asynchronous runtime for Scala
  • ZIO: Effect system with built-in dependency injection
  • Kyo: Novel approach based on algebraic effects
  • Gears: Experimental async programming for Scala
  • Casual FP: Mix and match functional concepts
  • Indigo: Make games with Scala
  • Souds of Scala: Build music applications
  • And a lot more

Learning

Learning is a process

There are plenty of ways to learn

  1. Courses
  2. Books
  3. Blogs
  4. Forums
  5. Meetups and conferences

Courses

Functional Programming in Scala Specialization

(a.k.a.) Coursera Course

Co-authored by Martin Odersky, author of Scala

Functional Programming in Scala Specialization

5 courses specialization

  1. Functional Programming Principles in Scala
  2. Functional Program Design in Scala
  1. Parallel programming
  2. Big Data Analysis with Scala and Spark
  3. Functional Programming in Scala Capstone

https://www.coursera.org/specializations/scala

Rock the JVM

Led by Daniel Ciocîrlan, offers Scala courses all proficiency levels

https://courses.rockthejvm.com

Rock the JVM: Discount code!

Rock the JVM: Discount code!

FUNCTIONAL_TALKS

Alvin's Courses

Created by Alvin Alexander, author of https://alvinalexander.com/,
"Functional Programming, Simplified", "Scala Cookbook"

Offers free Scala courses at https://www.learnscala.dev/

Youtube channels

Podcasts & talks

Scala Space · Scala for fun and profit · Softwafemill · Scaladays

Learning

Rock The Jvm · Jakub Kozłowski · Dev inside you · IntelliJ IDEA, a JetBrains IDE

And more https://www.nbshare.io/blog/best-scala-tutorials-on-youtube/

Books

Books

  • Programming in Scala
    Comprehensive guide by Martin Odersky

  • Scala for the impatient
    Compact introduction guide for those already competent in other languages like Java, C#, Python, JS or C++

  • Grokking functional programming
    by Michał Płachta easy way to learn functional programming for those familiar with the OOP ideas

  • Functional Programming Strategies In Scala with Cats
    by Noel Welsh, compendium on learning Cats library

Books

  • Functional programming in Scala
    a.k.a. "The red book", your go-to book for hands-on, advanced functional programming

  • Practical FP in Scala
    For those familiar with functional programming in Scala who are yet not confident about architecting an application from scratch

  • Functional Event-Driven Architecture
    Explore the event-driven architecture (EDA) in a purely functional way.

  • Many more https://docs.scala-lang.org/books.html https://whatpixel.com/best-scala-books/

Blogs

Blogs

Blogs

https://www.scalanews.net/Resources/Blog_Directory.html

Community

Your go-to list of forums, chat rooms, local user groups, and conferences

https://www.scala-lang.org/community

Forums

Scala on discord
Reddit r/scala
Scala Users Discourse
Scala Contributors Discourse
Scala Poland 🇵🇱 on Slack

Forums

IntelliJ · Scalameta · Play Framework · Typelevel · ZIO · Laminar · Smithy4s · indigo · Scala Space · Business4s · Creative Scala

Meetups 🎙️

  • London Scala User Group
  • Warsaw Scala Enthusiasts
  • Kraków Scala User Group
  • Wrocław Scala User Group
  • Bay Area Scala
  • SF Scala
  • Scala Bay
  • Atlanta Scala
  • Dallas Scala Enthusiasts
  • Functional World (online)

Meetups & conferences

Scalendar by Scalac

fill

News

Scala Times

by Softwaremill

https://scalatimes.com/

Scala Times

by Petr Zapletal

https://thisweekinscala.substack.com/

Scala Feed on Bluesky

by Michał Pawlik

https://bsky.app/profile/michal.pawlik.dev/feed/scala-feed

Wrapping up

Whatever they tell you online, this image does not present a monad

Start Your Journey

  1. Begin with scala-cli and simple scripts
  2. Pick a style that feels natural
  3. Learn by building real projects
  4. Join the community (Slack, Discord, Reddit)

Thank you!

Keep in touch! 🤝

Blog: blog.michal.pawlik.dev
Linkedin: Michał Pawlik
Github: majk-p
Bluesky: michal.pawlik.dev

Talk plan 1. Briefly what Scala is * OOP and FP * Multiplatform * Backed by academia, not corporations 2. IDEs * Intellij * How to install * Scala plugin (https://github.com/JetBrains/intellij-scala) * Pros (out of the box, familiar for Java devs/Pycharm users) * Cons (errors can be out of sync, non OSS editor) * Metals * How to install (Editor of choice) * Pros (in sync with the compiler, latest compiler features) * Cons (unequal experience across editors, requires reimport more often than intellij) 3. Build tools * What are they * sbt, scala-cli, just mention mill * scala-cli good enough for starters 4. Flavors of Scala * Good old OOP with https://www.playframework.com * Python like with Li Haoi https://www.lihaoyi.com/post/12yearsofthecomlihaoyiScalaPlatform.html * Direct style concurrency with Ox https://ox.softwaremill.com/latest * Hardcore FP with Cats Effect https://typelevel.org/cats-effect * Actors with Pekko/Akka * Many more * ZIO * Spark * Casual FP * Everything in between 5. Benefits of giving it a try (key takeaways) * Scala fits many problem spaces, perhaps it fits yours * Type system can make the experience safer and more pleasant * Multi-platforming across JVM, JS and Native is an added benefit * Learn a lot, broaden your horizons * Coding styles can be mixed ideas: * consider mentioning companies that use Scala * list learning resources, probably done best next to each subpoint of #4 todos: * validate code samples, perhaps extract them with mdoc * verify the dependencies, if they are necessary and on latest versions

Some research entry points: - https://en.wikipedia.org/wiki/Scala_(programming_language)#Companies - https://www.phind.com/search/cm7t37cup00002v6mor2h2097 - https://github.com/uhub/awesome-scala - https://www.perplexity.ai/search/i-m-working-on-an-introduction-GZXmiB0QTRqiG7.XyvUP3g - https://github.com/stkeky/best-of-scala

[Twitter/X](https://github.com/twitter/finagle) [The Guardian](https://github.com/guardian/grid) [Lichess](https://github.com/lichess-org/lila) [Netflix](https://github.com/Netflix/atlas) [Linkedin](https://github.com/linkedin/isolation-forest) [Coursera](https://github.com/coursera/courier) [Apple](https://jobs.apple.com/en-us/details/200589146/sr-development-data-engineer-music-books-podcasts-content-data-services?team=SFTWR) [SiriusXM](https://siriusxm.github.io/snapshot4s/) [Zalando](https://engineering.zalando.com/posts/2018/01/why-we-do-scala.html) [Morgan Stanley](https://github.com/morganstanley/optimus-cirrus) [JP Morgan](https://jpmc.fa.oraclecloud.com/hcmUI/CandidateExperience/en/sites/CX_1001/requisitions?keyword=Scala&mode=location) [HMRC and more of gov.uk](https://github.com/hmrc) [Duolingo](https://blog.duolingo.com/rewriting-duolingos-engine-in-scala/) [M1 Finance](https://github.com/m1finance) [LEGO](https://github.com/LEGO/woof) [Airbnb](https://github.com/airbnb/chronon) [Spotify](https://github.com/spotify/scio) [PayPal](https://github.com/paypal/squbs) [Softwaremill](https://github.com/softwaremill) [Virtuslab](https://virtuslab.com/expertise/scala/) [Databricks](https://github.com/databricks/sjsonnet) [Tesla](https://www.infoq.com/presentations/tesla-vpp/) [Workday](https://github.com/Workday/warp-core) [Disney Streaming](https://disneystreaming.github.io/smithy4s) [Salesforce](https://github.com/salesforce/orchard) [Thoughtworks](https://github.com/ThoughtWorksInc/Dsl.scala)

![bg right contain](./img/tapir.svg)

In my private opinion, two first should be mandatory. Even if you don't plan to use Scala professionally, it teaches you a lot about functional programming techinques

Paid, discount codes available