Skip to content

필사 모드: Modern Scala 2026 — Scala 3.6 / 3.7 / ZIO 2 / Cats Effect 3 / Pekko / Tapir / Mill / Scala CLI Deep Dive

English
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

Table 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

// Email

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...

작성 글자: 0원문 글자: 29,168작성 단락: 0/588