Skip to content
Published on

모던 Scala 2026 완벽 가이드 - Scala 3.6 · ZIO 2 · Cats Effect 3 · Akka 23 → Apache Pekko · Mill · sbt · Laminar 심층 분석

Authors

프롤로그 — 2026년, Scala는 '복잡한 언어'에서 '선택의 언어'가 되었다

2020년만 해도 Scala는 "강력하지만 복잡한 언어"라는 이미지가 강했다. 빌드는 sbt 한 권만이 정답이었고, implicit conversion으로 IDE가 멈췄으며, Akka가 사실상 액터 시스템의 동의어였다.

2026년의 풍경은 완전히 다르다.

  • Scala 3.6 이 안정 LTS로 자리잡았다. Scala 2.13 → 3 마이그레이션은 scala3-migrate로 거의 자동화됐다.
  • Effect system 삼국지 — Cats Effect 3.5(Typelevel), ZIO 2.1(John De Goes), Kyo(Flavio Brasil) — 가 명확한 진영을 형성했다.
  • Akka가 BSL 라이선스로 전환(2022)된 후 커뮤니티는 Apache Pekko 1.0으로 이주했다. 같은 코드, 다른 거버넌스.
  • 빌드 도구 3파전 — sbt 1.10.5, Mill 0.12(Lihaoyi), scala-cli — 가 용도별로 갈라졌다.
  • Scala.js 프론트엔드 — Laminar 17, Tyrian, Outwatch — 가 "TypeScript 대안"으로 자리잡았다.
  • Scala Native 0.5 + GraalVM Native Image 로 AOT 컴파일이 실용권에 들어왔다.

Scala는 더 이상 "JVM에서 함수형을 한다"의 동의어가 아니다. 도구다. 이 글은 그 도구 전체 지형을 한 번에 정리한다.

한 줄 요약: "무엇을 증명하고 싶고, 어디서 돌리며, 팀이 어떤 패러다임에 익숙한가." 이 세 질문이 Scala 도구 선택의 90%를 결정한다.


1장 · Scala 3 — Dotty가 살아남은 이야기

Scala 3 은 2021년 5월 안정판이 나왔다. 이전 코드네임 Dotty(Martin Odersky, EPFL)는 8년에 걸친 리팩토링 끝에 새로운 type system 위에 다시 쓰였다. DOT calculus(Dependent Object Types)를 기반으로, 타입 시스템의 모든 코너 케이스를 수학적으로 정리한 결과물이다.

2026년 시점 Scala 3은 세 가지 LTS 라인이 공존한다.

버전상태특징
Scala 3.3 LTS장기 지원보수적 안정성, 라이브러리 호환 보장
Scala 3.5nextnamed tuples, indentation 개선
Scala 3.6 / 3.7latestcapture checking, given 명시화, Quotes 정리

Scala 2.13 은 여전히 Spark 3.5 같은 대형 라이브러리의 기본 타깃이라 죽지 않는다. Scala 2.13 → 3 양방향 호환성(TASTy)을 통해 "한 프로젝트에 두 버전 혼용"이 가능하다.

Scala 3의 진짜 의미는 문법이 아니라 타입 시스템의 청소 였다. implicit이 given/using/extension으로 쪼개졌고, structural type이 정리됐고, macro가 Quotes API로 재설계됐다.


2장 · Scala 3.5 / 3.6 / 3.7의 새 문법 — Named Tuples부터 Capture Checking까지

대표적인 신문법.

// named tuples (Scala 3.5+) — 익명 구조체 같은 효과
val person: (name: String, age: Int) = (name = "Yuna", age = 28)
val p2 = (name = "Min", age = 31)
val nm: String = person.name

// extension methods — implicit class의 후계자
extension (s: String)
  def shout: String = s.toUpperCase + "!"

"hello".shout  // "HELLO!"

// given / using — implicit의 명시화
trait Show[A]:
  def show(a: A): String

given Show[Int] with
  def show(a: Int): String = s"int:$a"

def render[A](a: A)(using s: Show[A]): String = s.show(a)

// enum — sealed trait의 sugar
enum Status:
  case Active, Paused, Closed(reason: String)

// match types — 타입 레벨 분기
type Elem[X] = X match
  case String => Char
  case Array[t] => t

// inline + macros — Quotes API
inline def log(inline msg: String): Unit =
  ${ logImpl('msg) }

capture checking(Scala 3.6+)은 함수가 "어떤 외부 자원을 캡처하는지" 를 타입에 표시한다. 실험적이지만 effect tracking의 한 흐름이다. 미래의 Scala 4를 향한 포석이다.


3장 · Scala 2.13 → 3 마이그레이션 — 자동화의 한계와 현실

대형 코드베이스를 Scala 3으로 옮기는 길은 2026년 기준 사실상 정해진 절차를 따른다.

  1. sbt-tasty-mima 또는 mima 로 바이너리 호환성 검사.
  2. scalafix 룰셋(Procedure.scala2, ExplicitResultTypes 등)을 돌려 자동 변환.
  3. scala3-migrate sbt 플러그인으로 implicit, default args, type parameter 차이를 자동 패치.
  4. Scala 2.13에서 빌드되는 상태로 -Xsource:3-Wconf 를 켜고 경고 0을 만든다.
  5. Scala 3으로 컴파일러를 바꾸고 남은 에러를 손으로 고친다.
// Scala 2.13의 implicit class
implicit class StringOps(val s: String) extends AnyVal {
  def shout: String = s.toUpperCase + "!"
}

// Scala 3의 extension — 자동 변환됨
extension (s: String)
  def shout: String = s.toUpperCase + "!"

까다로운 영역은 macro(Scala 2의 def macros → Scala 3의 Quotes API), HKT 변성, shapeless 기반 typeclass derivation(이제 Mirror 로 대체)이다. 이 셋이 코드에 많으면 마이그레이션 비용이 두 배로 뛴다.

실무 팁: 라이브러리부터 옮기고 애플리케이션은 마지막에 옮긴다. Scala 3이 Scala 2.13 라이브러리를 쓰는 건 가능하지만, 그 반대는 어렵다.


4장 · Effect System 삼국지 — Cats Effect 3.5 · ZIO 2.1 · Kyo

Scala 함수형 진영의 핵심은 effect system이다. 부수효과(IO, 동시성, 자원, 에러)를 타입으로 표현해 추론과 테스트가 가능하게 만든다.

라이브러리진영핵심 추상특징
Cats Effect 3.5TypelevelIO[A], Resource[F, A], Ref[F, A]type-class 기반, fs2와 결합
ZIO 2.1John De GoesZIO[R, E, A]모놀리식, R/E/A 3-track
KyoFlavio Brasilalgebraic effects가장 최신, 핸들러 기반

Cats Effect 3은 IO 한 타입에 모든 effect를 담는다. ZIO는 environment R, error E, success A를 타입에 직접 노출한다. Kyo는 algebraic effects(Eff monad 가족)로 핸들러 합성을 강조한다.

// Cats Effect 3
import cats.effect.IO
import cats.effect.std.Console

val program: IO[Unit] =
  for
    _ <- Console[IO].println("name?")
    n <- Console[IO].readLine
    _ <- Console[IO].println(s"hi $n")
  yield ()

// ZIO 2
import zio.*

val zioProg: ZIO[Any, java.io.IOException, Unit] =
  for
    _ <- Console.printLine("name?")
    n <- Console.readLine
    _ <- Console.printLine(s"hi $n")
  yield ()

선택 기준은 단순하다. type-class 친화 + 라이브러리 호환 이면 Cats Effect. 명시적 environment + 통합 라이브러리 면 ZIO. 최신 효과론 + 가벼움 이면 Kyo. 한 프로젝트에 둘을 섞는 일은 권하지 않는다.


5장 · Cats Effect 3.5 — Typelevel 스택의 심장

Cats Effect(Typelevel, Daniel Spiewak 주도)는 IO, Resource, Ref, Deferred, Semaphore 같은 동시성 프리미티브와 fiber 스케줄러를 제공한다. fiber는 OS 스레드보다 가벼운 협력적 동시성 단위로, JVM의 native thread를 양보(yield)할 수 있다.

import cats.effect.{IO, Resource, ResourceApp}

object App extends ResourceApp.Forever:
  def run(args: List[String]): Resource[IO, Unit] =
    for
      _ <- Resource.eval(IO.println("start"))
      _ <- Resource.make(IO.pure(42))(_ => IO.println("close"))
    yield ()

Cats Effect의 강점은 타입클래스 합성이다. Sync, Async, Concurrent, Temporal, MonadCancel 같은 계층이 명확해서, 라이브러리가 "내가 필요한 능력 최소집합"만 요구할 수 있다. Doobie, http4s, fs2 같은 핵심 라이브러리가 전부 Cats Effect 위에 있다.

Cats Effect는 "조각조각 합성" 의 미학을 따른다. ZIO와 가장 큰 철학적 차이가 여기에 있다.


6장 · ZIO 2.1 — 모놀리식 통합 스택

ZIO(John A De Goes, Ziverge)는 effect 타입 자체에 environment를 넣는다. ZIO[R, E, A] 는 "R을 받아 E로 실패하거나 A로 성공" 한다.

import zio.*

trait UserRepo:
  def findById(id: Long): ZIO[Any, Throwable, Option[String]]

object UserRepo:
  val live: ZLayer[Any, Nothing, UserRepo] = ZLayer.succeed {
    new UserRepo:
      def findById(id: Long) = ZIO.succeed(Some(s"user-$id"))
  }

val app: ZIO[UserRepo, Throwable, Unit] =
  for
    repo <- ZIO.service[UserRepo]
    u    <- repo.findById(1L)
    _    <- Console.printLine(u.toString)
  yield ()

object Main extends ZIOAppDefault:
  def run = app.provide(UserRepo.live)

ZIO의 강점은 batteries-included 다. ZIO HTTP, ZIO Schema, ZIO JSON, ZIO Streams, ZIO Test, ZIO Config — 같은 디자인의 라이브러리 군이 한 진영을 이룬다. 학습 곡선이 있지만 정착하면 "한 가지 사고방식"으로 전체 스택을 짤 수 있다.

ZIO는 "한 그릇에 다 담는다" 의 미학을 따른다. Cats Effect의 합성주의와 대비된다.


7장 · Kyo — 가장 최신의 효과 라이브러리

Kyo(Flavio Brasil, ex-Twitter)는 algebraic effects를 직접 모델링한다. 효과를 타입에 누적하고 핸들러가 그것을 처리한다. Idris의 effect 시스템에 가깝다.

import kyo.*

def program: Int < (IO & Abort[Throwable] & Async) =
  for
    _ <- IO(println("start"))
    n <- Async.runFiber(IO(42)).await
  yield n

A < S 는 "A 결과, 효과 S" 라는 의미. S는 효과의 합성이다. ZIO의 R/E/A 3-track보다 더 일반화된 형태다.

Kyo는 2024~2025년에 빠르게 성숙했고, 2026년 시점 "차세대 효과 라이브러리"로 거론된다. 다만 라이브러리 생태계는 아직 Cats Effect/ZIO만큼 두텁지 않다.


8장 · Akka 23.x → Apache Pekko 1.0 — 라이선스가 갈라놓은 두 길

2022년 9월 Lightbend가 Akka 2.7부터 BSL(Business Source License) 로 라이선스를 변경했다. 비상업적 사용은 자유지만 상업적 사용은 유료. 이 결정은 오픈소스 진영에 큰 충격이었다.

대응으로 ASF(Apache Software Foundation) 산하에서 Apache Pekko 가 시작됐다. Akka 2.6.x 코드를 포크해서 패키지명만 akkaorg.apache.pekko 로 바꾼 버전이다.

도구라이선스거버넌스상태
Akka 23.xBSL 1.1 + 상업Lightbend신기능 활발
Apache Pekko 1.0Apache 2.0ASFAkka 2.6 호환 + 점진 확장

코드 마이그레이션은 거의 패키지명 치환이다.

// Akka
import akka.actor.typed.{ActorSystem, Behavior}
import akka.actor.typed.scaladsl.Behaviors

// Apache Pekko
import org.apache.pekko.actor.typed.{ActorSystem, Behavior}
import org.apache.pekko.actor.typed.scaladsl.Behaviors

val behavior: Behavior[String] = Behaviors.receive { (ctx, msg) =>
  ctx.log.info(msg)
  Behaviors.same
}

2026년 기준 새 프로젝트는 거의 대부분 Apache Pekko를 쓴다. 기존 Akka 사용 회사도 라이선스 비용 vs 마이그레이션 비용을 저울질해 옮기는 추세다.

라이브러리는 라이선스가 곧 정체성이다. 이 사건은 오픈소스 생태계가 "거버넌스 안정성"을 얼마나 중시하는지를 증명했다.


9장 · Actor와 Streams — Apache Pekko 1.0의 핵심

Pekko(Akka도 동일)의 두 축은 typed actorstreams다.

import org.apache.pekko.actor.typed.scaladsl.Behaviors
import org.apache.pekko.actor.typed.ActorSystem

enum Cmd:
  case Inc, Dec, Get(replyTo: org.apache.pekko.actor.typed.ActorRef[Int])

def counter(n: Int): org.apache.pekko.actor.typed.Behavior[Cmd] =
  Behaviors.receiveMessage {
    case Cmd.Inc => counter(n + 1)
    case Cmd.Dec => counter(n - 1)
    case Cmd.Get(r) =>
      r ! n
      Behaviors.same
  }

val sys = ActorSystem(counter(0), "demo")

Streams는 reactive streams 규격 위에 만들어진 fluent DSL이다.

import org.apache.pekko.stream.scaladsl.*
import org.apache.pekko.NotUsed

val source: Source[Int, NotUsed] = Source(1 to 10)
val flow: Flow[Int, Int, NotUsed]  = Flow[Int].map(_ * 2)
val sink: Sink[Int, scala.concurrent.Future[Int]] = Sink.fold(0)(_ + _)

val total = source.via(flow).runWith(sink)

Akka HTTP / Pekko HTTP, Akka Cluster / Pekko Cluster, Akka Persistence / Pekko Persistence — 라이선스 차이일 뿐 기능 매핑은 1:1이다.


10장 · http4s · Tapir · ZIO HTTP — Scala HTTP 라이브러리 3파전

Scala HTTP의 주력 후보는 셋.

라이브러리진영특징
http4s 0.23+TypelevelHttpRoutes[F] 타입 안전, fs2 기반
Tapir 1.xsoftwaremill선언형 endpoint, 백엔드 어댑터
ZIO HTTPZIOZIO 친화, 고성능

http4s 는 함수형 HTTP의 정석이다.

import cats.effect.IO
import org.http4s.*
import org.http4s.dsl.io.*

val routes = HttpRoutes.of[IO] {
  case GET -> Root / "hello" / name =>
    Ok(s"hi $name")
}

Tapir 는 endpoint를 데이터로 선언하고, OpenAPI/스웨거/타입 안전 클라이언트를 자동 생성한다.

import sttp.tapir.*
import sttp.tapir.json.circe.*

case class User(name: String, age: Int)

val getUser = endpoint
  .get
  .in("users" / path[Long]("id"))
  .out(jsonBody[User])
  .errorOut(stringBody)

ZIO HTTP 는 ZIO 친화 라우팅 + 고성능. zio-http는 벤치마크에서 자주 1위를 차지한다.

선택은 진영을 따른다. Cats Effect 스택이면 http4s, ZIO 스택이면 ZIO HTTP, 백엔드 독립성을 원하면 Tapir.


11장 · sbt 1.10.5 · Mill 0.12 · scala-cli — 빌드 도구 3파전

오래도록 sbt는 사실상 유일한 선택이었다. 2026년에는 세 가지가 공존한다.

도구작가/소속강점약점
sbt 1.10.5Lightbend → 커뮤니티가장 호환성 높음, 플러그인 풍부학습 곡선, 느림
Mill 0.12Li Haoyi간결한 Scala DSL, 빠른 점진 빌드플러그인 적음
scala-cliVirtus Lab단일 파일 스크립트 친화큰 프로젝트엔 부적합

build.sbt 예시.

// build.sbt
ThisBuild / scalaVersion := "3.6.0"
ThisBuild / organization := "example"

lazy val core = (project in file("core"))
  .settings(
    libraryDependencies ++= Seq(
      "org.typelevel" %% "cats-effect" % "3.5.4",
      "org.http4s" %% "http4s-ember-server" % "0.23.27"
    )
  )

Mill build.sc.

// build.sc
import mill._, scalalib._

object core extends ScalaModule {
  def scalaVersion = "3.6.0"
  def ivyDeps = Agg(
    ivy"org.typelevel::cats-effect:3.5.4",
    ivy"org.http4s::http4s-ember-server:0.23.27"
  )
}

scala-cli는 의존성을 파일 상단에 선언한다.

//> using scala 3.6.0
//> using dep org.typelevel::cats-effect:3.5.4

import cats.effect.{IO, IOApp}

object Hello extends IOApp.Simple:
  def run = IO.println("hi")

scala-cli는 2024년 Scala 공식 도구(scala run)로 채택됐다. 작은 스크립트, 데이터 분석, 학습용에 사실상 표준이다. 큰 프로젝트는 sbt 혹은 Mill로 간다.


12장 · Scala.js · Laminar 17 · Tyrian — Scala로 짜는 프론트엔드

Scala.js 는 Scala를 JavaScript로 컴파일한다. 2026년 기준 안정적이며 webpack/vite 통합도 매끄럽다.

Laminar 17(Nikita Gazarov) 은 reactive UI 프레임워크다. FRP(functional reactive programming) 기반으로, signal과 observable로 상태를 관리한다.

import com.raquo.laminar.api.L.*

val name = Var("")

val app = div(
  input(
    placeholder := "your name",
    onInput.mapToValue --> name
  ),
  span(
    "hi, ",
    child.text <-- name.signal
  )
)

render(dom.document.getElementById("root"), app)

Tyrian 은 Elm 아키텍처(model-update-view)를 Scala.js로 옮긴 프레임워크다. 게임 엔진 indigo와 짝을 이룬다.

Outwatch(Cornerman) 는 RxJS 같은 observable 기반이다. Lampagne 은 신생 SSR 친화 프레임워크.

선택 기준:

  • "React/Solid 같은 declarative UI" — Laminar
  • "Elm 같은 단방향 데이터 흐름" — Tyrian
  • "RxJS 익숙함 + 작은 번들" — Outwatch

Laminar는 "Scala로 짜는 가장 좋은 프론트엔드"라는 평가를 받는다. TypeScript 대안으로 진지하게 검토할 만하다.


13장 · Scala Native 0.5 + GraalVM Native Image — AOT의 두 길

JVM은 시작 시간이 느리다. CLI나 서버리스에서는 치명적이다. 해법이 두 가지.

도구어떻게특징
Scala Native 0.5LLVM 백엔드로 직접 컴파일JVM 없음, C 인터롭, 작은 바이너리
GraalVM Native ImageJVM 바이트코드 → AOTJava/Scala 그대로, reflection 설정 필요
// Scala Native
object Hello:
  def main(args: Array[String]): Unit =
    println("hello native")
# Scala Native — 직접 LLVM 컴파일
sbt nativeLink

# GraalVM Native Image — JVM 바이트코드 AOT
native-image -jar app.jar

Scala Native는 라이브러리 호환이 제한된다. JVM 의존 라이브러리는 안 돌아간다. GraalVM은 거의 모든 Java 라이브러리가 돌지만 reflection·동적 클래스 로딩 처리가 까다롭다.

서버리스(AWS Lambda, GCP Cloud Run)에서 Scala를 쓰려면 둘 중 하나가 필수다. 차가운 시작 시간이 100ms 이하로 떨어진다.


Apache Spark 은 Scala로 작성됐고, Spark API는 여전히 Scala가 가장 자연스럽다.

Spark 버전Scala 타깃비고
Spark 3.5Scala 2.13 / 2.122026년 주력
Spark 4.0(preview)Scala 2.13 / 3Connect, Spark Connect
import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder
  .appName("demo")
  .master("local[*]")
  .getOrCreate()

import spark.implicits.*

val df = Seq(("a", 1), ("b", 2)).toDF("k", "v")
df.filter($"v" > 1).show()

Apache Flink 도 Scala API를 제공한다. 2023년 Flink는 Scala API를 "best-effort" 로 격하했지만 커뮤니티가 유지하고 있다.

Apache Beam 은 자체 SDK가 있으며 Scio(Spotify의 Scala wrapper)가 가장 인기 있다.

빅데이터 영역에서 Scala 2.13은 당분간 사라지지 않는다. Spark가 Scala 3을 정식 지원하기까지는 시간이 더 필요하다.


15장 · JSON · Schema · Codec — circe · jsoniter-scala · upickle

JSON 라이브러리도 진영이 갈린다.

라이브러리진영특징
circeTypelevel함수형, type-class 기반 derivation
jsoniter-scalaPlokhotnyuk매크로로 생성한 가장 빠른 코덱
upickleLi Haoyi단순, 의존성 가벼움
ZIO JSONZIOZIO 친화, 스키마 통합
// circe
import io.circe.*, io.circe.generic.semiauto.*

case class User(name: String, age: Int)

given Encoder[User] = deriveEncoder
given Decoder[User] = deriveDecoder

// jsoniter-scala
import com.github.plokhotnyuk.jsoniter_scala.macros.*
import com.github.plokhotnyuk.jsoniter_scala.core.*

given JsonValueCodec[User] = JsonCodecMaker.make

벤치마크에서 jsoniter-scala가 단연 빠르다(JSON.parse보다 빠른 경우도). circe는 다른 Typelevel 라이브러리와 합성이 매끄럽다. upickle은 "그냥 JSON" 이 필요할 때 가장 가볍다.


16장 · DB 레이어 — Doobie 1.0 · Skunk · Quill · ScalikeJDBC

Doobie 1.0(Typelevel) — JDBC 위의 함수형 wrapper. Cats Effect 위에서 SQL을 자연스럽게.

import doobie.*, doobie.implicits.*
import cats.effect.IO

case class User(id: Long, name: String)

val xa = Transactor.fromDriverManager[IO](
  driver = "org.postgresql.Driver",
  url    = "jdbc:postgresql:db",
  user   = "u",
  pass   = "p",
  logHandler = None
)

val all: IO[List[User]] =
  sql"select id, name from users".query[User].to[List].transact(xa)

Skunk(Typelevel) — Postgres 네이티브 프로토콜을 직접 구현. JDBC 없이 nio 위에. 가장 빠르고 가장 작다.

Quill 4.x — 쿼리를 Scala 표현식으로 짜고 컴파일 타임에 SQL로 변환. type-safe 하지만 학습 곡선이 있다.

ScalikeJDBC — Java JDBC에 가장 가까운 얇은 wrapper. 익숙함을 원할 때.

// Quill
import io.getquill.*

val ctx = new PostgresJdbcContext(SnakeCase, "ctx")
import ctx.*

val users = quote { query[User].filter(_.age > 18) }
ctx.run(users)

선택 기준은 진영(Cats Effect/ZIO/독립)과 "SQL을 직접 쓸 것인가" vs "Scala 표현식으로 쓸 것인가"다.


17장 · 테스트 — Munit · ScalaTest 3.2 · ZIO Test · weaver-test

테스트 프레임워크도 풍부하다.

프레임워크진영특징
MunitScala 팀간결, JUnit 호환
ScalaTest 3.2클래식다양한 스타일(FunSuite, FlatSpec, ...)
ZIO TestZIOZIO 친화, environment 주입
weaver-testdisneystreamingCats Effect 친화, 병렬 기본
// Munit
class MathSpec extends munit.FunSuite:
  test("add"):
    assertEquals(1 + 2, 3)

// ScalaTest FunSuite
class MathSuite extends org.scalatest.funsuite.AnyFunSuite:
  test("add") { assert(1 + 2 == 3) }

// weaver-test
import weaver.*

object MathSpec extends SimpleIOSuite:
  pureTest("add"):
    expect(1 + 2 == 3)

Munit이 표준에 가깝다. ZIO 진영은 ZIO Test, Cats Effect 진영은 weaver-test 또는 Munit-CatsEffect를 자주 쓴다.


18장 · Iron · refined — 타입으로 값을 제약

refined(fthomas) 와 Iron(Iltotore) 은 "값에 타입 수준 제약" 을 더한다. 예를 들어 "양수만 받는 정수" 타입을 만들 수 있다.

// Iron (Scala 3)
import io.github.iltotore.iron.*
import io.github.iltotore.iron.constraint.numeric.*

type Age = Int :| Positive
val a: Age = 30           // OK
// val b: Age = -1         // compile error

// refined (Scala 2/3 호환)
import eu.timepit.refined.*
import eu.timepit.refined.api.Refined
import eu.timepit.refined.numeric.*

val x: Int Refined Positive = refineMV[Positive](42)

Iron은 Scala 3 전용으로 더 가볍고 IDE 친화적이다. refined는 Scala 2 호환성이 있고 ZIO Prelude 등과도 연동된다.

API 입출력의 invariants를 타입에 새기는 것은 함수형 Scala의 핵심 미학이다.


19장 · 실전 사용처 — Twitter→X, Databricks, Twilio, Disney+, SoFi

Scala를 실제 운영에 쓰는 대표 회사들.

회사어떻게 쓰는가
Twitter → XFinagle, util, Finatra. 대부분 인프라가 Scala. 2023년 일부 Rust 이행
DatabricksSpark가 곧 회사. Scala 2.12/2.13이 대규모 운영
Twilio메시징 백엔드 일부에 Akka/Pekko
Foursquare위치 데이터 처리에 Scala
ING Bank결제 백엔드, Cats Effect
SoFi핀테크 백엔드, ZIO
Disney+streaming 백엔드 일부. weaver-test는 Disney에서 나옴
Iagon분산 스토리지, Cats Effect
AppleSiri/iCloud 백엔드 일부
Netflix추천/스트림 일부(과거엔 더 많이 사용)

Scala는 "전부 Scala" 인 회사가 줄고, "특정 영역에 Scala" 인 회사가 늘었다. 이는 다른 JVM 언어(Kotlin, Java 21)의 성숙과도 관련 있다. 하지만 데이터 엔지니어링, 결제 백엔드, 분산 시스템 영역에서 Scala의 자리는 굳건하다.


20장 · 한국·일본의 Scala 커뮤니티

한국:

  • ScalaKorea — 한국 Scala 사용자 모임. 카카오·라인·쿠팡·우아한형제들이 핵심.
  • Kakao Brain / Kakao Pay — 데이터 파이프라인에 Scala/Spark.
  • LINE — 메시징 백엔드 일부에 Scala/Akka. Scala 2.13/3 혼용.
  • Coupang — 데이터 엔지니어링 일부.
  • 우아한형제들 — 카탈로그/배치에 Scala.
  • NHN Cloud / 네이버 — Hadoop 생태계 위에 Scala/Spark.

일본:

  • ScalaMatsuri — 도쿄에서 매년 열리는 아시아 최대 Scala 콘퍼런스.
  • Scala Tokyo — 도쿄 Scala 사용자 모임.
  • CyberAgent — 광고 백엔드에 Scala.
  • Septeni — 광고 도메인.
  • メルカリ / Mercari — 결제·정산 일부.
  • DMM.com — 일부 백엔드.
  • NTT 통신과학연구소 — 학술/연구.

동아시아의 Scala 사용은 데이터 엔지니어링·광고·결제 에 무게가 실린다. 한일 모두 Spark/Akka 사용처가 핵심이고, 함수형 라이브러리(Cats Effect/ZIO)는 신규 프로젝트에서 빠르게 확산 중이다.


21장 · Scala 3 함정과 모범 사례

처음 Scala 3로 옮길 때 빠지는 함정.

함정증상대처
implicit 무조건 given으로 옮기기의미가 바뀜using/extension/given 셋을 구분
Scala 2 macro 그대로 둠컴파일 안 됨Quotes API로 재작성
shapeless 도입Scala 3에서는 과잉Mirror 기반 derivation으로 대체
너무 빨리 capture checking 켜기라이브러리 호환 깨짐LTS에서는 끄고, 신규 모듈에서만 켠다
sbt + Mill + scala-cli 셋 다 섞기빌드 인지부조화하나로 통일
Akka 23 신코드 추가라이선스 계약 부담Apache Pekko로 신규 작성
Effect 진영 혼용변환 boilerplate 폭주Cats Effect ↔ ZIO 인터롭은 경계에서만
reflective Java API에 의존Native Image 컴파일 실패reflect-config 또는 @reflective
너무 많은 implicit conversionIDE 느려짐, 디버깅 어려움명시적 변환 권장
Iron/refined를 모든 곳에컴파일 시간 증가도메인 invariants에만

Scala 3은 도구가 좋아진 만큼 "신중한 단순함"을 더 보상한다.


22장 · 다음 5년 — Scala의 본격 정착

마지막으로 향후 5년의 흐름.

  1. Scala 3.3 LTS가 굳어진다. 신규 코드는 거의 모두 3로 옮겨가지만 Spark가 끌고 있는 2.13 라이브러리는 더 오래 살아남는다.
  2. Effect 진영이 좁혀진다. Cats Effect와 ZIO가 안정 진영을 형성하고, Kyo가 미래의 표준 후보로 부상한다.
  3. Apache Pekko가 사실상 표준이 된다. Akka 상업 라이선스는 대기업 한정으로 좁아진다.
  4. 빌드 도구는 sbt + scala-cli 양강 — Mill은 특정 팀의 선택.
  5. Laminar/Tyrian 같은 Scala.js 프레임워크 가 작은 SaaS의 풀스택 Scala를 가능하게 만든다.
  6. Scala Native + GraalVM 의 결합으로 서버리스/CLI Scala가 일반화.
  7. AI 시대 Scala — 데이터 파이프라인(Spark)이 LLM 인덱싱·임베딩 파이프의 표준이 되고, ZIO/Cats Effect 위의 LLM 클라이언트가 등장.
  8. 표준화 — TASTy 안정화, 매크로 API 안정화, library API 호환 문화 정착.

Scala는 더 이상 "복잡한 함수형 언어"가 아니다. 도구다. 그리고 그 도구는 점점 평범한 엔지니어가 선택지로 고를 만한 도구가 되어가고 있다.


에필로그 — 어디서부터 시작할까

이 글에서 다룬 도구가 너무 많다고 느껴지면, 다음 학습 경로를 추천한다.

  1. 언어 — Scala 3 공식 튜토리얼과 "Programming in Scala" (Odersky 외) 5판.
  2. 빌드 — scala-cli로 단일 파일 스크립트 실험. 그 다음 sbt 혹은 Mill로 멀티 모듈.
  3. Effect — Cats Effect 또는 ZIO 중 하나를 골라 "Bookings" 같은 작은 예제 작성.
  4. HTTP — http4s 또는 Tapir로 REST API 구현.
  5. DB — Doobie 또는 Skunk로 Postgres 연결.
  6. 프론트엔드 — Scala.js + Laminar로 SPA 한 페이지.
  7. 실전 — Scala Native나 GraalVM으로 작은 CLI 빌드.

"무엇을 증명하고 싶고, 어디서 돌리며, 팀이 어떤 패러다임에 익숙한가." 이 세 질문을 들고 다시 본문을 훑으면, 도구 선택은 의외로 명확해진다.

— Modern Scala 2026, 끝.


References

  1. Odersky, M. et al. "Scala 3 Reference." https://docs.scala-lang.org/scala3/reference/
  2. Scala Center. "Scala 3 Migration Guide." https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html
  3. Typelevel. "Cats Effect 3 Documentation." https://typelevel.org/cats-effect/
  4. Ziverge. "ZIO 2 Documentation." https://zio.dev/
  5. Brasil, F. "Kyo Project." https://github.com/getkyo/kyo
  6. Lightbend. "Akka License Change Announcement." https://www.lightbend.com/blog/why-we-are-changing-the-license-for-akka
  7. Apache Software Foundation. "Apache Pekko." https://pekko.apache.org/
  8. http4s. "http4s Documentation." https://http4s.org/
  9. softwaremill. "Tapir Documentation." https://tapir.softwaremill.com/
  10. dream11. "ZIO HTTP." https://zio.dev/zio-http/
  11. sbt Authors. "sbt Reference Manual." https://www.scala-sbt.org/1.x/docs/
  12. Haoyi, L. "Mill Build Tool." https://mill-build.org/
  13. Virtus Lab. "scala-cli." https://scala-cli.virtuslab.org/
  14. Gazarov, N. "Laminar." https://laminar.dev/
  15. PurpleKingdomGames. "Tyrian." https://tyrian.indigoengine.io/
  16. Scala Native Team. "Scala Native 0.5." https://scala-native.org/
  17. Apache Spark. "Spark Scala API." https://spark.apache.org/docs/latest/api/scala/index.html
  18. Plokhotnyuk, A. "jsoniter-scala." https://github.com/plokhotnyuk/jsoniter-scala
  19. Typelevel. "Doobie." https://tpolecat.github.io/doobie/
  20. Typelevel. "Skunk." https://typelevel.org/skunk/
  21. Scalameta. "Munit." https://scalameta.org/munit/
  22. Disney Streaming. "weaver-test." https://disneystreaming.github.io/weaver-test/
  23. Iltotore. "Iron." https://iltotore.github.io/iron/
  24. ScalaMatsuri. "ScalaMatsuri Conference." https://scalamatsuri.org/
  25. Scala Center. "Scala Toolkit." https://docs.scala-lang.org/toolkit/introduction.html