필사 모드: Modern Scala 2026 — Scala 3.6 / 3.7 / ZIO 2 / Cats Effect 3 / Pekko / Tapir / Mill / Scala CLI Deep Dive
EnglishTable of Contents
1. Modern Scala in 2026 — The Scala 3 Era
Scala was once called "that weird language." Even in the early 2020s, people would say "Scala is hard," "Scala 2 compiles slowly," "the learning curve is too steep to roll out across a team." Scala in 2026 is a different beast. **Scala 3 has settled in**, build tools have diversified, **effect systems like ZIO and Cats Effect** have matured, and **Pekko has absorbed the Akka BSL license drama**. At the same time, Scala ideas are being re-exported into TypeScript via projects like **Effect.ts**.
This article is a deep dive into the Scala ecosystem as of May 2026.
The Big Currents Around Scala in 2026
| Current | Detail |
|---------|--------|
| Scala 3 stabilization | Scala 3.6 (Dec 2024) / 3.7 (Mar 2025) stable, Scala 4 preview in progress |
| Build tool diversification | sbt 2.x (slow transition), Mill (Li Haoyi), Scala CLI (scripts and POCs) |
| Effect system split | ZIO 2 vs Cats Effect 3 — two camps coexist |
| Akka aftermath | Akka moved to BSL (2022), Apache Pekko forked — now the de facto standard |
| Web framework maturity | http4s, Tapir, Play Framework 3 — a functional web stack |
| Other platforms | Scala.js (JS), Scala Native 0.5 (native binaries) |
| Data engineering | Apache Spark's core language — still a huge market |
| Idea exports | Effect.ts (TS), Iron (refined types), magnolify |
| Adoption | Lichess, parts of Toss, MegaZone, Septeni, Money Forward, etc. |
Why Scala Has Not Vanished
People have called "the end of Scala" several times. The 2026 Scala has a clear seat at the table.
- **Spark is effectively written in Scala** — the core of data engineering and ML pipelines
- **The language that best breaks through JVM expressiveness limits** — deeper FP than Kotlin, stronger types than Java
- **Effect systems (ZIO / Cats Effect) actually work** — industry-proven FP stacks
- **The cutting edge of type safety via Iron's refined types** — other languages have not caught up
- **Cases like Lichess where a single shop runs millions of users** — proof of Scala's real-world capability
Let's go through each piece.
2. Scala 3.6 (Dec 2024) / 3.7 (Mar 2025) — New Features
Scala 3 has been steadily evolving since its May 2021 launch. The 3.6 and 3.7 releases at the end of 2024 and the start of 2025 sent the signal "Scala 3 is truly stable."
Major Changes in Scala 3.6
In Scala 3.6 (December 8, 2024) the highlights are:
- **Quotes API stabilization** — macro authoring is much easier
- **Named tuples (experimental)** — labels for tuple fields, `(name = "Alice", age = 30)` instead of `("Alice", 30)`
- **Type ascription warnings** — warnings for ambiguous type ascriptions
- **`-Wunused` improvements** — refined warnings for unused imports and vars
- **Capture checking progress** — preview of a key Scala 4 feature
// Named tuples (experimental in 3.6, official in 4.0)
val person = (name = "Alice", age = 30)
val n: String = person.name // access by field name
val a: Int = person.age
// Function arguments as named tuples too
def greet(p: (name: String, age: Int)): String =
s"Hello $p.name, $p.age years old"
Changes in Scala 3.7
Scala 3.7 (March 27, 2025) is a minor release but full of meaningful improvements.
- **`@experimental` annotation cleanup** — clearer distinction between stable and experimental features
- **Best-effort compilation** — IDE auto-complete works even with some errors
- **Compile speed improvements** — the Scala 2 era reputation continues to fade
- **JDK 25 compatibility** — works with the latest LTS
- **New inline API** — fine-grained control over `inline def`
Compile Speed — The Biggest Complaint Is Fading
Scala 2.x had a notorious reputation for slow compiles. Scala 3.7 is faster thanks to:
| Technique | Effect |
|-----------|--------|
| Incremental compilation (Zinc) improvements | Only changed files recompile |
| Pickle cache | Type info reuse |
| Parallel compilation | Module-level parallelism |
| Using `bloop` | Background compile server |
It's still slower than Java or Kotlin, but the "go grab a soda while it compiles" days are over.
Migration Tooling
Scala 2 to 3 migration is automated by:
Scalafix - automated refactoring
sbt "scalafixAll dependency:Scala3RewriteFromScala2Old@org.scalameta:scalafix-rules:0.13.0"
Scala 3 compiler's auto-migration mode
scalac -source:3.0-migration MyFile.scala
scala-migrate CLI
cs install scala-migrate
scala-migrate migrate-build
Most Scala 2 code resolves to **80-90% automatic migration**.
3. Scala 4 Preview — What's Next
Scala 4 hasn't shipped yet, but **the preview has been active since late 2025**. The theme is "promote features that entered Scala 3 as experimental into official status."
What Scala 4 Aims For
- **Capture checking goes official** — tracking mutable resources, memory safety
- **Named tuples go official** — lightweight record types
- **Match types improvements** — type-level pattern matching
- **Implicit system simplification** — moving toward just `given` and `using`
- **Compiler internals cleanup** — TASTy format stabilization
What Is Capture Checking
This is the biggest change that entered Scala 3.x as experimental and goes official in Scala 4. The type system tracks "what resources a function captures."
// Scala 4 preview
// Declare that f captures the io resource
def withFile[T](path: String)(f: File^ => T): T = ???
// ^ capability
// The compiler guarantees captured resources don't leak outside
val data = withFile("a.txt") { file =>
file.readAll()
}
// Compile error: cannot return file
val leaked = withFile("a.txt") { file => file } // ERROR
This is **a similar idea to Rust's borrow checker** but runs on the JVM. It's essentially handling ZIO/Cats Effect `Resource` at the language level.
Scala 4 Release Timing
EPFL (where Scala was born) and the Scala Center have officially targeted "late 2026 to early 2027." That said, Scala follows a policy of "don't break compatibility just because the major version changes," so even when Scala 4 lands, most Scala 3 code will keep building.
4. sbt 2.x / Mill / Scala CLI — Build Tool Evolution
For a long time the Scala build tool was **sbt**. Powerful, but with a steep learning curve and notoriously painful debugging when something broke. The 2026 landscape looks different.
sbt 2.x — Slow Transition
sbt 2.x has been in RC since 2024, and as of May 2026 it still hasn't fully replaced 1.x. The main changes:
- **Build definitions can be written in Scala 3**
- **New plugin model** — fewer dependency conflicts
- **`Task` API cleanup**
- **Compile/run separation** — better incremental builds
// build.sbt (sbt 2.x style)
ThisBuild / scalaVersion := "3.7.0"
ThisBuild / version := "0.1.0-SNAPSHOT"
lazy val root = (project in file("."))
.settings(
name := "my-app",
libraryDependencies ++= Seq(
"dev.zio" %% "zio" % "2.1.10",
"org.scalatest" %% "scalatest" % "3.2.19" % Test
)
)
Mill — Li Haoyi's Alternative
[Mill](https://mill-build.com/) is a build tool by Li Haoyi. For people tired of sbt's "DSL magic," it defines builds as **plain Scala objects**.
// build.sc
object app extends ScalaModule {
def scalaVersion = "3.7.0"
def ivyDeps = Agg(
ivy"dev.zio::zio:2.1.10"
)
object test extends ScalaTests {
def ivyDeps = Agg(ivy"org.scalatest::scalatest:3.2.19")
def testFramework = "org.scalatest.tools.Framework"
}
}
Mill's strengths:
- **Explicit** — build logic is just Scala methods. No magic
- **Fast** — change detection is more accurate
- **Understandable errors** — easier to debug than sbt
Parts of Twitter and Databricks have reportedly migrated to Mill.
Scala CLI — The Right Answer for Scripts
Scala CLI is **the official tool from the Scala Center**, and it completely replaces sbt for small scripts, POCs, and learning.
Install
brew install Virtuslab/scala-cli/scala-cli
Single-file script
scala-cli run hello.scala
Declare dependencies inside the code
cat > script.scala <<'EOF'
//> using scala 3.7.0
//> using dep dev.zio::zio:2.1.10
object Main extends ZIOAppDefault:
def run = Console.printLine("Hello from Scala CLI")
EOF
scala-cli run script.scala
Package as a single native binary (via Scala Native)
scala-cli package --native --output myapp script.scala
Since 2024, Scala CLI has been **the official backend of the `scala` command**. Run `scala myfile.scala` and Scala CLI runs underneath.
Build Tool Comparison
| Item | sbt 2.x | Mill | Scala CLI |
|------|---------|------|-----------|
| Target | Large projects | Medium-large | Scripts and small apps |
| Build definition | `build.sbt` (DSL) | `build.sc` (Scala objects) | `using` directives |
| Learning curve | Steep | Medium | Almost none |
| Speed | Average | Fast | Very fast |
| Plugin ecosystem | Very rich | Average | Limited |
| Recommended for | Existing sbt projects | New projects | Learning and POCs |
5. ZIO 2 — The Functional Effect Camp
[ZIO](https://zio.dev) is the most popular functional effect library in Scala. As of May 2026, **ZIO 2.1.x** is the standard, and the ZIO 3 roadmap is public.
ZIO's Core Idea — `ZIO[R, E, A]`
A ZIO value carries **three type parameters**:
- `R` (Environment) — dependencies required for the effect to run
- `E` (Error) — the error type the effect can fail with
- `A` (Success) — the value type returned on success
// Returns Int but may fail with Throwable
val task1: ZIO[Any, Throwable, Int] = ZIO.attempt(42)
// Requires Database, can fail with AppError, returns User
val task2: ZIO[Database, AppError, User] =
ZIO.serviceWithZIO[Database](_.getUser(123))
// Composition
val task3: ZIO[Database, AppError, String] =
for {
user <- task2
_ <- Console.printLine(s"Got user: $user.name").orDie
} yield user.name
ZIO Layer — Dependency Injection
ZIO's most powerful piece is the **Layer system** — a functional take on Spring DI.
trait Database:
def getUser(id: Int): Task[User]
class LiveDatabase(config: DbConfig) extends Database:
def getUser(id: Int): Task[User] = ZIO.attempt(???)
object LiveDatabase:
val layer: ZLayer[DbConfig, Nothing, Database] =
ZLayer.fromFunction(LiveDatabase(_))
// Compose
val appLayer = DbConfig.layer >>> LiveDatabase.layer
New in ZIO 2
- **`Scope` for resource management** — `ZManaged` was removed for a simpler API
- **`ZStream` stabilization** — back-pressured stream processing
- **`ZIO.attemptBlocking`** — automatic isolation of blocking work
- **`ZIO.logSpan`** — distributed tracing integration
ZIO Ecosystem
| Library | Role |
|---------|------|
| zio-http | HTTP server and client |
| zio-json | JSON serialization |
| zio-config | Configuration |
| zio-quill | Compile-time SQL generation |
| zio-kafka | Kafka integration |
| zio-prelude | Functional data types |
| zio-schema | Schema-based serialization |
6. Cats Effect 3 — The Other Functional Camp
[Cats Effect](https://typelevel.org/cats-effect/) is the other pillar of Scala functional effects alongside ZIO. Built by the Typelevel camp (Cats, Cats Effect, http4s, doobie, etc.), it centers on **a simple `IO[A]` type**.
`IO[A]` — The Beauty of Simplicity
val program: IO[String] = for {
_ <- IO.println("Enter your name:")
name <- IO.readLine
_ <- IO.println(s"Hello, $name!")
} yield name
object Main extends IOApp.Simple:
def run: IO[Unit] = program.void
ZIO vs Cats Effect — How They Differ
| Item | ZIO 2 | Cats Effect 3 |
|------|-------|---------------|
| Core type | `ZIO[R, E, A]` | `IO[A]` |
| Error tracking | Explicit in the type (`E`) | All `Throwable` |
| Dependency injection | `Layer` system | typeclasses + `Resource` |
| Learning curve | Steep (3 type parameters) | Gentle (1 parameter) |
| Ecosystem | zio-* series | Typelevel camp |
| Philosophy | "All together inside ZIO" | "Compose small libraries" |
Cats Effect's Strengths
- **Typeclass-based** — decomposed into `MonadCancel`, `Concurrent`, `Async`
- **`Fiber` for concurrency** — lightweight green threads
- **`Resource[F, A]` for resource management** — functional try-with-resources
- **Loom compatible** — composes naturally with JDK 21+ virtual threads
// Safe resource management with Resource
val dbResource: Resource[IO, Connection] =
Resource.make(IO(openConnection()))(c => IO(c.close()))
val program: IO[Unit] =
dbResource.use { conn =>
IO(conn.query("SELECT 1"))
}
// conn.close() runs even on exception
Picking a Camp in Practice
In the field these patterns are common:
- **New teams** → ZIO 2 (rich learning material, natural DI)
- **Teams already on Typelevel** → Cats Effect 3
- **Neither** → start with `Future` or synchronous code and adopt later if needed
It has religious-war energy, so just go with whatever the team agrees on.
7. Pekko (Apache, Akka Fork) — After the BSL Drama
The most political and shocking event in the Scala ecosystem was **Akka's license change in September 2022**.
Akka Going BSL
Lightbend (Akka's creator) announced on September 7, 2022, that **Akka 2.7+ would move to BSL (Business Source License)**. The key conditions:
- Free for non-commercial use
- Commercial use is paid above a certain revenue threshold per year
- Converts to Apache 2.0 after three years (delayed open source)
This shocked the Scala community. Akka was the backbone of Play Framework, Lagom, Spark Streaming, and countless companies. **Lightbend's position was "the company has to survive for the library to survive,"** but the community reacted with "trust is broken."
The Birth of Apache Pekko
In late 2022, **Pekko** launched under the Apache Software Foundation. It's a fork of Akka 2.6.x and 100% Apache 2.0 licensed.
// Akka (BSL)
// Pekko (Apache 2.0) - nearly identical
object Greeter:
sealed trait Command
case class Greet(name: String) extends Command
def apply(): Behavior[Command] = Behaviors.receive { (ctx, msg) =>
msg match
case Greet(name) =>
ctx.log.info(s"Hello $name")
Behaviors.same
}
The only difference is the **package name `akka.*` to `org.apache.pekko.*`**. Migration is a one-line sed.
The 2026 Reality
- **New projects are nearly 100% Pekko** — no commercial license risk
- **Existing Akka users are still migrating to Pekko** — Lightbend's revenue recovered with BSL, but trust did not
- **Major Pekko releases are active** — the community is moving on its own
- **Play Framework 3 is also Pekko-based**
Where Pekko Is Used
- **Distributed systems** — actor-model based large-scale processing
- **Streaming** — Pekko Streams, Pekko Connectors (Kafka, Cassandra, etc.)
- **HTTP server** — Pekko HTTP
- **Event sourcing** — Pekko Persistence
For event-driven systems in 2026, Pekko is the de facto standard.
8. Play Framework 3 / http4s / Tapir — Web
The Scala web framework world settles into **three camps**.
Play Framework 3 — The Full-Stack Framework
[Play 3](https://www.playframework.com/) is a full-stack MVC framework like Rails. It was rebuilt on Pekko in late 2023.
// Play 3 controller
package controllers
@Singleton
class HomeController @Inject() (cc: ControllerComponents)
extends AbstractController(cc):
def index() = Action { implicit request =>
Ok("Hello from Play 3")
}
def user(id: Int) = Action.async { implicit request =>
userService.get(id).map(u => Ok(Json.toJson(u)))
}
Pros — full-stack, template engine, form validation, asset pipeline all included.
Cons — "not very functional," steep learning curve.
http4s — Functional Web
[http4s](https://http4s.org) is a **purely functional web server built on Cats Effect**.
val helloService = HttpRoutes.of[IO] {
case GET -> Root / "hello" / name =>
Ok(s"Hello, $name")
}.orNotFound
object Main extends IOApp.Simple:
def run = EmberServerBuilder
.default[IO]
.withHost(ipv4"0.0.0.0")
.withPort(port"8080")
.withHttpApp(helloService)
.build
.useForever
Pros — purely functional, clear behavior, natural Cats Effect integration.
Cons — looks like magic at first, middleware authoring is tricky.
Tapir — Type-Safe API Definitions
[Tapir](https://tapir.softwaremill.com) is the Scala community's secret weapon. **Define endpoints at the type level**, and code, clients, and OpenAPI specs are generated automatically.
case class User(id: Int, name: String)
// Define endpoint as a value
val getUser =
endpoint
.get
.in("users" / path[Int]("id"))
.out(jsonBody[User])
.errorOut(stringBody)
// Serve via http4s
val routes = Http4sServerInterpreter[IO]()
.toRoutes(getUser.serverLogic(id => IO.pure(Right(User(id, "Alice")))))
// Generate OpenAPI from the same definition
val docs = OpenAPIDocsInterpreter().toOpenAPI(getUser, "My API", "1.0")
println(docs.toYaml)
Define an endpoint once and you get:
- HTTP server routes
- Type-safe clients
- OpenAPI / Swagger spec
- Automatic docs
It's the cutting edge of backend interface definition.
Which Should You Pick
| Situation | Recommendation |
|-----------|----------------|
| Full-stack web app (with templates) | Play 3 |
| Functional microservice | http4s + Tapir |
| Large API + schema-first | Tapir + any backend |
| Actor-based concurrency | Pekko HTTP |
| New team, low learning overhead | Tapir + http4s |
9. Scala.js / Scala Native 0.5 — Other Platforms
Scala isn't only a JVM language. You can target JavaScript via **Scala.js** and LLVM-based native binaries via **Scala Native**.
Scala.js — Compile to JavaScript
[Scala.js](https://www.scala-js.org) compiles Scala to JavaScript. In 2026, 1.18.x is the standard, and interop with React, Vue, and other JS libraries is clean.
// Scala.js + Laminar (reactive UI)
val app = div(
h1("Hello Scala.js"),
button(
"Click me",
onClick --> { _ =>
println("Clicked!")
}
)
)
render(dom.document.getElementById("app"), app)
Pros — Scala's type system on the frontend, powerful dead-code elimination keeps bundles small.
Cons — JS interop is possible but you sometimes need to write type definitions yourself.
Scala Native 0.5 — LLVM Native
[Scala Native](https://scala-native.org) compiles Scala to LLVM IR and produces native binaries. **Since 0.5.x (2024) it's truly usable**.
// Hello, Scala Native
object Main:
def main(args: Array[String]): Unit =
stdio.printf(c"Hello from Scala Native! PID: %d\n", unistd.getpid())
Compile
scala-cli package --native --output myapp Main.scala
Run — starts instantly without the JVM
./myapp
Pros:
- **No JVM startup time** — ideal for CLI tools
- **Small memory footprint** — great for serverless like Lambda or Cloud Run
- **Choose your GC** — Boehm, Immix, Commix
- **Call C libraries directly**
Cons:
- Can't use all JVM libraries (reflection-dependent ones)
- Compilation through LLVM is slow
The Scala CLI + Scala Native combo is excellent for **single-binary CLI tools**. Tools like coursier and sbt-pack ship with this combination.
10. Spark Scala — Data Engineering
One of the biggest reasons Scala survived into 2026 is **Apache Spark**. Spark's core is written in Scala, and **the Scala API is the fastest and most expressive**.
Spark's Status
- Spark 3.5.x (2024) / Spark 4.0 (planned 2025)
- Python (PySpark) has the larger share, but **high-performance and complex transformations still go to Scala**
- Large data shops like Databricks and Palantir use Scala Spark as the main interface
Using Spark from Scala
val spark = SparkSession.builder
.appName("Example")
.master("local[*]")
.getOrCreate()
case class Transaction(userId: Int, amount: Double, ts: String)
val df = Seq(
Transaction(1, 100.0, "2026-01-01"),
Transaction(1, 200.0, "2026-01-02"),
Transaction(2, 50.0, "2026-01-01")
).toDF()
val agg = df
.groupBy("userId")
.agg(
sum("amount").as("total"),
count("*").as("tx_count")
)
.orderBy(desc("total"))
agg.show()
Frameless — Type-Safe Spark
[Frameless](https://typelevel.org/frameless/) wraps Spark's `DataFrame` in a type-safe API and catches column-name typos at compile time.
val ts: TypedDataset[Transaction] = TypedDataset.create(transactions)
val totals: TypedDataset[(Int, Double)] = ts
.groupBy(ts('userId))
.agg(sum(ts('amount)))
.as[(Int, Double)]
// Compile error: there is no 'amounnt' column
val bad = ts.select(ts('amounnt)) // doesn't compile
Frameless 0.16+ migrated to Scala 3 and is stable.
Should Data Engineers Learn Scala
- **PySpark owns ~60% of the market** — you can start with Python
- **But infra / platform teams are mostly Scala** — Databricks itself is Scala
- **Performance-critical transformations are clearly faster in Scala** — direct JVM calls avoid serialization overhead
- **Conclusion** — data analysts → Python, data infra / platform engineers → Scala
11. Effect.ts — Scala Ideas Ported to TypeScript
A fascinating mid-2020s phenomenon is that **Scala's ideas were re-exported into TypeScript**. The poster child is [Effect.ts](https://effect.website).
What Is Effect.ts
Effect.ts ports the core ideas of ZIO and Cats Effect to TypeScript.
// Effect.ts (TypeScript)
const program = Effect.gen(function* () {
yield* Console.log("Enter your name:")
const name = "Alice" // would be real input
yield* Console.log(`Hello, ${name}`)
return name
})
Effect.runPromise(program).then(console.log)
Compare with ZIO — practically the same structure:
// ZIO (Scala)
val program = for {
_ <- Console.printLine("Enter your name:")
name <- ZIO.succeed("Alice")
_ <- Console.printLine(s"Hello, $name")
} yield name
Runtime.default.unsafeRun(program)
Why This Happened
- **TypeScript's type system became expressive enough** — generics, conditional types, and `infer` let you track effects
- **JS async hell** — Promises and async/await hit a wall
- **More FP-leaning users coming to TS** — folks from Haskell and Scala backgrounds came to TS
- **Demand for standardized error handling** — patterns like `Either` and `Option` became popular in TS too
What This Means for Scala
- Proof that **Scala-born patterns transcend the language**
- Scala users on full-stack TS gigs can **reach naturally for Effect.ts**
- Conversely, TS devs deep in FP can **move naturally to Scala**
The Scala community takes pride in this — "our ideas became mainstream."
12. Iron — Refined Types
[Iron](https://github.com/Iltotore/iron) is a Scala 3 library that implements **refined types** — a tool for encoding constraints in types at compile time.
What Is a Refined Type
Encodes constraints like "an `Int` but positive" or "a `String` shaped like an email" into the type system.
// Positive integers
type PositiveInt = Int :| Positive
val age: PositiveInt = 30 // OK
val bad: PositiveInt = -5 // compile error
type Email = String :| Match["""[\w.+]+@[\w.]+"""]
val email: Email = "a@b.com" // OK
val notEmail: Email = "hello" // compile error
// In functions too
def sendEmail(to: Email, body: String :| MinLength[1]): Unit = ???
Iron's Strengths
- **Type-safe without runtime validation** — memory-compatible with plain `Int`/`String`
- **Compile-time checks via Scala 3 macros** — the compiler validates literals
- **Define arbitrary conditions** — encode domain rules in types
// User domain types
type UserId = Int :| Positive
type UserName = String :| (MinLength[2] & MaxLength[50])
case class User(id: UserId, name: UserName)
// Blocked at compile time
val u = User(0, "X")
// ERROR: 0 is not Positive, "X" is not MinLength[2]
Comparison With Other Languages
- TypeScript [Brand types](https://medium.com/@KevinBGreene/typescript-branded-types-and-the-pattern-for-domain-modeling-d016eb71affd) — a weaker version of Iron
- Rust's newtype pattern — similar intent, weaker validation
- Haskell refined types — the closest equivalent
- F# units of measure — partial overlap
Iron is **one of the most powerful type-safety tools Scala has in 2026**.
13. doobie / Slick — DB Libraries
Scala's DB libraries split mainly between **doobie** (functional) and **Slick** (SQL DSL).
doobie — Pure Functional JDBC
[doobie](https://typelevel.org/doobie/) wraps JDBC functionally on top of Cats Effect.
val xa = Transactor.fromDriverManager[IO](
driver = "org.postgresql.Driver",
url = "jdbc:postgresql:test",
user = "u",
password = "p",
logHandler = None
)
case class User(id: Int, name: String)
// SQL interpolation — type-checked at compile time
def findUser(id: Int): ConnectionIO[Option[User]] =
sql"SELECT id, name FROM users WHERE id = $id".query[User].option
val program: IO[Option[User]] = findUser(1).transact(xa)
Pros — SQL is SQL, type-safe, perfect Cats Effect integration.
Cons — you must know SQL well, no ORM auto-mapping.
Slick — Type-Safe SQL DSL
[Slick](https://scala-slick.org) expresses SQL as a Scala DSL. It's not an ORM — closer to a query builder.
class Users(tag: Tag) extends Table[(Int, String)](tag, "USERS"):
def id = column[Int]("ID", O.PrimaryKey)
def name = column[String]("NAME")
def * = (id, name)
val users = TableQuery[Users]
// Write SQL in Scala
val query = users
.filter(_.id === 1)
.map(_.name)
.result
val action = query
db.run(action).map(println)
Pros — safe queries without knowing SQL, IDE auto-complete.
Cons — DSL hits a wall on complex queries, debugging is hard.
Which to Pick
| Situation | Recommendation |
|-----------|----------------|
| Team knows SQL well | doobie |
| Migrating from ORM-comfortable team | Slick |
| Cats Effect stack | doobie (natural fit) |
| Complex dynamic queries | doobie (raw SQL freedom) |
| With automated migrations | Slick (strong codegen) |
Quill — Another Option
[Quill](https://zio.dev/zio-quill/) compiles Scala code to SQL at compile time — the ZIO camp's favorite option.
val ctx = new SqlMirrorContext(PostgresDialect, SnakeCase)
case class User(id: Int, name: String)
val q = quote {
query[User].filter(_.id == 1).map(_.name)
}
println(ctx.run(q).string)
// SELECT name FROM user WHERE id = 1
14. Lichess — A Chess Site Written in Scala
One of the most famous production systems built in Scala is [Lichess](https://lichess.org) — a 100% free, 100% open-source chess site with **millions of monthly active users**.
The Scale of Lichess
| Metric | Value (2025) |
|--------|--------------|
| Daily games | 7 million+ |
| Monthly active users | 100 million+ page views |
| Concurrent players | Tens of thousands |
| Staff | 3-4 full-time |
| Operating cost | ~$10,000/month (donation-funded) |
| Codebase | 100% Scala (backend) |
The efficiency is wild. While comparable sites employ dozens of engineers, Lichess runs on a small team and Scala.
Why Lichess Uses Scala (Summary of Thibault Duplessis Interviews)
- **The type system catches bugs at compile time** — essential when operations staff is small
- **Functional paradigm keeps concurrency safe** — handling tens of thousands of concurrent users safely
- **Akka (now Pekko) handles games as actors** — one actor per game
- **MongoDB + reactivemongo for async DB** — all Scala-friendly
Lichess's Tech Stack
- Language — Scala 3 (migration from Scala 2 completed in 2024)
- Web framework — Play Framework
- Actor model — Pekko (formerly Akka)
- DB — MongoDB
- Frontend — TypeScript (Snabbdom)
- Infra — bare-metal servers (OVH)
Takeaways
- Scala's expressiveness is **decisive when a small team runs a big system**
- The "startup = JS / Python" formula isn't absolute
- A model for open-source operations — all code is at [github.com/lichess-org](https://github.com/lichess-org)
Lichess is living proof for teams evaluating Scala that "this is possible."
15. Korea / Japan — Toss, MegaZone, Septeni, Money Forward
Scala isn't mainstream in Korea or Japan, but it's **actively used at specific companies**.
Scala Adoption in Korea
| Company | Use case | Notes |
|---------|----------|-------|
| Toss Payments | Some backends (settlement, statistics) | Core is Kotlin, parts are Scala |
| MegaZone Cloud | Data platform | Spark-based |
| Parts of LINE | Data engineering | Spark-centric |
| Parts of Kakao | Search and recommendation systems | Spark + Scala |
| Many data companies | Spark-based ETL | Scala is the de facto standard |
In Korea, Scala is alive in **the data-engineering and platform space**, while **pure backend has mostly moved to Kotlin/Java**.
Scala Adoption in Japan
Japan adopts Scala more actively than Korea.
| Company | Use case | Notes |
|---------|----------|-------|
| Septeni (CyberAgent group) | Ad-platform backends | Heavy Scala usage |
| Money Forward | Household finance and B2B accounting | Scala + Rails mix |
| freee | Parts of accounting SaaS | Some Scala modules |
| Chatwork | Chat SaaS | Scala + Pekko |
| CyberAgent (AbemaTV) | Parts of the video platform | Scala + Go |
| Dwango | Niconico Douga | History of Scala usage |
Japan has had an **active Scala community since the mid-2010s**, with conferences like ScalaMatsuri running every year.
Should You Learn Scala in East Asia
- **Pure backend developer** — Kotlin first, Scala optional
- **Data engineer** — Scala is a big weapon if you go deep on Spark
- **Want deep FP** — Scala is the best FP language on the JVM
- **Job market** — narrow in Korea, present and centered in Tokyo for Japan
Learning Resources (Korean / Japanese)
- [Scala School (Twitter, Korean translation)](https://twitter.github.io/scala_school/ko/index.html)
- [Programming in Scala (Odersky, Korean translation)](http://www.acornpub.co.kr/book/programming-in-scala-4e)
- Japanese — [Scala逆引きレシピ](https://www.shoeisha.co.jp/book/detail/9784798125411)
- [ScalaMatsuri](https://scalamatsuri.org) — Tokyo, annual
16. Who Should Pick Scala — Data / FP / JVM + ML
An honest take on who should learn Scala in 2026 and who shouldn't.
Scala Fits If
- **Data engineer** — environments centered on Spark
- **Deep FP** — drawn to Haskell or OCaml but need the JVM ecosystem
- **High-performance concurrency** — actor-based systems with Pekko
- **Type-safety frontier** — Iron, refined types, capture checking
- **Small team running a big system** — Lichess-level operational efficiency
- **ML on the JVM** — BigDL, Smile, Frameless
Scala Does Not Fit If
- **You need fast hiring** — Scala engineers are relatively rare
- **Simple CRUD backend** — Kotlin / Spring delivers much faster
- **You just joined a Java/Kotlin team** — political cost is high
- **Solo full-stack development** — the JS / TS ecosystem is richer
- **Cloud Native and Kubernetes tooling** — Go is the de facto standard
Suggested Learning Path
Beginner
↓
Small scripts with Scala CLI (1-2 weeks)
↓
"Programming in Scala 5th Edition" or
"Effective Programming in Scala" (Scala Center)
↓
Get comfortable with case class / sealed trait / for comprehension
↓
Pick a camp: ZIO or Cats Effect
↓
Real project — a small API with http4s + Tapir
↓
Expand to Pekko, Spark, Iron, doobie as needed
Position Against Other JVM Languages
| Language | Position | Relationship to Scala |
|----------|----------|-----------------------|
| Java | Rich, many companies | Scala complements — use Scala only where Java struggles |
| Kotlin | The new backend strong man | Lighter than Scala, weaker FP |
| Clojure | Lisp family, dynamic | Very different philosophy from Scala |
| Groovy | DSL niche | Scala is more powerful |
ML on the JVM
Python is the ML standard, but the JVM camp has:
| Library | Role |
|---------|------|
| BigDL | Distributed deep learning on Spark |
| Smile | Statistics and ML library |
| Frameless | Type-safe Spark |
| Deeplearning4j | DL on the JVM (Java-leaning) |
| ONNX Runtime Java | Train in Python, infer on the JVM |
The "train in Python, infer on the JVM" pattern is growing, and Scala handles that inference layer cleanly.
17. References
Scala Official
- [Scala homepage](https://www.scala-lang.org)
- [Scala 3 Reference](https://docs.scala-lang.org/scala3/reference/)
- [Scala 3.6 Release Notes](https://www.scala-lang.org/news/3.6.0/)
- [Scala 3.7 Release Notes](https://www.scala-lang.org/news/3.7.0/)
- [Scala Center](https://scala.epfl.ch)
Build Tools
- [sbt official](https://www.scala-sbt.org)
- [Mill build tool](https://mill-build.com)
- [Scala CLI](https://scala-cli.virtuslab.org)
- [Coursier](https://get-coursier.io)
Effect Systems
- [ZIO](https://zio.dev)
- [Cats Effect](https://typelevel.org/cats-effect/)
- [Typelevel](https://typelevel.org)
Actors and Concurrency
- [Apache Pekko](https://pekko.apache.org)
- [Akka (Lightbend, BSL)](https://akka.io)
- [Lightbend BSL announcement](https://www.lightbend.com/blog/why-we-are-changing-the-license-for-akka)
Web Frameworks
- [Play Framework](https://www.playframework.com)
- [http4s](https://http4s.org)
- [Tapir](https://tapir.softwaremill.com)
- [Scalatra](https://scalatra.org)
Other Platforms
- [Scala.js](https://www.scala-js.org)
- [Scala Native](https://scala-native.org)
- [Laminar (Scala.js UI)](https://laminar.dev)
Data
- [Apache Spark](https://spark.apache.org)
- [Frameless](https://typelevel.org/frameless/)
- [Smile (ML)](https://haifengl.github.io/)
- [BigDL](https://bigdl.readthedocs.io)
Type System
- [Iron (refined types)](https://github.com/Iltotore/iron)
- [Magnolify (typeclass derivation)](https://github.com/spotify/magnolify)
DB
- [doobie](https://typelevel.org/doobie/)
- [Slick](https://scala-slick.org)
- [Quill](https://zio.dev/zio-quill/)
Testing and Logging
- [ScalaTest](https://www.scalatest.org)
- [MUnit](https://scalameta.org/munit/)
- [Scribe (logging)](https://github.com/outr/scribe)
Effect.ts (Scala Influence)
- [Effect.ts homepage](https://effect.website)
- [Effect.ts vs ZIO comparison](https://effect.website/docs/why-effect)
Notable Production Cases
- [Lichess (Scala chess site)](https://lichess.org)
- [Lichess GitHub](https://github.com/lichess-org)
- [Lichess Thibault Duplessis blog](https://lichess.org/blog)
Conferences and Community
- [Scala Days](https://scaladays.org)
- [ScalaMatsuri (Tokyo)](https://scalamatsuri.org)
- [Scala Korea (Meetup)](https://www.meetup.com/scala-korea/)
Books
- "Programming in Scala, 5th Edition" — Martin Odersky et al.
- "Effective Programming in Scala" — Julien Richard-Foy (Scala Center)
- "Functional Programming in Scala, 2nd Edition" — Paul Chiusano, Runar Bjarnason
- "Zionomicon" — John A. De Goes, Adam Fraser (ZIO book, free)
현재 단락 (1/588)
Scala was once called "that weird language." Even in the early 2020s, people would say "Scala is har...