Skip to content

필사 모드: Modern Scala 2026 Deep Dive - Scala 3.6, ZIO 2, Cats Effect 3, Akka 23 to Apache Pekko, Mill, sbt, Laminar

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

Prologue — In 2026, Scala Became a Language of Choice, Not a Language of Difficulty

Back in 2020, Scala still carried the image of "powerful but complicated." `sbt` was the only build tool that mattered, implicit conversions froze IDEs, and Akka was effectively synonymous with the actor model on the JVM.

The 2026 landscape is entirely different.

- **Scala 3.6** has settled in as a stable LTS. Scala 2.13 to 3 migrations are nearly automated via `scala3-migrate`.

- **A three-way effect-system race** — Cats Effect 3.5 (Typelevel), ZIO 2.1 (John De Goes), and Kyo (Flavio Brasil) — has formed clear camps.

- After Lightbend moved Akka to **BSL** in 2022, the community migrated to **Apache Pekko 1.0**. Same code, different governance.

- **A three-way build-tool race** — sbt 1.10.5, Mill 0.12 (Lihaoyi), and scala-cli — has split by use case.

- **Scala.js frontends** — Laminar 17, Tyrian, Outwatch — have grown into "TypeScript alternatives."

- **Scala Native 0.5** plus **GraalVM Native Image** finally make AOT compilation practical.

Scala is no longer a synonym for "functional programming on the JVM." It is a toolbox. This article maps the whole toolbox at once.

> One-line summary: **"What do you want to prove, where will you run it, and which paradigm does your team know?"** These three questions decide 90 percent of your Scala tooling choices.

Chapter 1 · Scala 3 — How Dotty Survived

**Scala 3** shipped its stable release in May 2021. The former codename Dotty (Martin Odersky, EPFL) was an eight-year refactor that rewrote the language atop a brand-new type system. Built on DOT calculus (Dependent Object Types), it formalizes every corner case of the type system.

As of 2026 there are three coexisting LTS lines.

| Version | Status | Highlights |

| --- | --- | --- |

| Scala 3.3 LTS | Long-term support | Conservative stability, library compatibility |

| Scala 3.5 | next | Named tuples, indentation improvements |

| Scala 3.6 / 3.7 | latest | Capture checking, `given` clarifications, Quotes refresh |

**Scala 2.13** is not dead either. It remains the default target for large libraries such as Spark 3.5. Bidirectional compatibility (TASTy) between Scala 2.13 and 3 lets you mix versions inside one project.

> The real meaning of Scala 3 was not the syntax but the **type-system cleanup**. `implicit` was split into `given` / `using` / `extension`, structural types were tightened, and macros were re-designed via the Quotes API.

Chapter 2 · New Syntax in Scala 3.5 / 3.6 / 3.7 — From Named Tuples to Capture Checking

Representative new syntax.

// named tuples (Scala 3.5+) — anonymous-struct flavor

val person: (name: String, age: Int) = (name = "Yuna", age = 28)

val p2 = (name = "Min", age = 31)

val nm: String = person.name

// extension methods — successor to implicit class

extension (s: String)

def shout: String = s.toUpperCase + "!"

"hello".shout // "HELLO!"

// given / using — explicit form of 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 — sugar over sealed trait

enum Status:

case Active, Paused, Closed(reason: String)

// match types — type-level branching

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+) puts "which external resources does this function capture" into the type. It is experimental, but it is one of the threads pointing at future effect tracking — a stepping stone toward a hypothetical Scala 4.

Chapter 3 · Scala 2.13 to 3 Migration — Automation and Its Limits

In 2026, migrating a large code base to Scala 3 follows an almost standard procedure.

1. Run **`sbt-tasty-mima`** or **`mima`** for binary-compatibility checks.

2. Run **`scalafix`** rule sets (`Procedure.scala2`, `ExplicitResultTypes`, etc.) to auto-rewrite.

3. Run the **`scala3-migrate`** sbt plugin to patch implicits, default args, and type-parameter differences.

4. Keep building under Scala 2.13 with **`-Xsource:3`** and **`-Wconf`** enabled until warnings are zero.

5. Switch the compiler to Scala 3 and fix remaining errors manually.

// Scala 2.13 implicit class

implicit class StringOps(val s: String) extends AnyVal {

def shout: String = s.toUpperCase + "!"

}

// Scala 3 extension — auto-rewritten

extension (s: String)

def shout: String = s.toUpperCase + "!"

The hard areas are **macros** (Scala 2 def-macros to Scala 3 Quotes API), **HKT variance**, and **shapeless-style typeclass derivation** (now replaced by `Mirror`). If a code base leans heavily on these three, migration cost roughly doubles.

> Practical tip: migrate libraries first, applications last. Scala 3 can consume Scala 2.13 libraries, but the reverse is hard.

Chapter 4 · The Effect-System Three-Way Race — Cats Effect 3.5, ZIO 2.1, Kyo

The heart of functional Scala is the **effect system**. It expresses side effects (IO, concurrency, resources, errors) in types so that reasoning and testing become tractable.

| Library | Camp | Core abstraction | Character |

| --- | --- | --- | --- |

| Cats Effect 3.5 | Typelevel | `IO[A]`, `Resource[F, A]`, `Ref[F, A]` | Type-class based, pairs with fs2 |

| ZIO 2.1 | John De Goes | `ZIO[R, E, A]` | Monolithic, 3-track R/E/A |

| Kyo | Flavio Brasil | algebraic effects | Newest, handler based |

Cats Effect 3 packs every effect into a single `IO` type. ZIO exposes environment R, error E, and success A directly in the type. Kyo models algebraic effects (the Eff-monad family) and emphasizes handler composition.

// Cats Effect 3

val program: IO[Unit] =

for

_ <- Console[IO].println("name?")

n <- Console[IO].readLine

_ <- Console[IO].println(s"hi $n")

yield ()

// ZIO 2

val zioProg: ZIO[Any, java.io.IOException, Unit] =

for

_ <- Console.printLine("name?")

n <- Console.readLine

_ <- Console.printLine(s"hi $n")

yield ()

The choice is simple. **Type-class friendly plus library interop** picks Cats Effect. **Explicit environment plus integrated libraries** picks ZIO. **Latest effect theory plus light footprint** picks Kyo. Mixing two of them in one project is not recommended.

Chapter 5 · Cats Effect 3.5 — The Heart of the Typelevel Stack

**Cats Effect** (Typelevel, led by Daniel Spiewak) ships concurrency primitives — `IO`, `Resource`, `Ref`, `Deferred`, `Semaphore` — plus a fiber scheduler. A fiber is a cooperative concurrency unit lighter than an OS thread that can yield the JVM's native thread.

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's strength is **type-class composition**. A clean hierarchy — `Sync`, `Async`, `Concurrent`, `Temporal`, `MonadCancel` — lets a library demand only the minimum capability it needs. Doobie, http4s, and fs2 all sit on top of Cats Effect.

> Cats Effect follows a "compose small pieces" aesthetic. That is its biggest philosophical difference from ZIO.

Chapter 6 · ZIO 2.1 — A Monolithic Integrated Stack

**ZIO** (John A De Goes, Ziverge) embeds the environment in the effect type itself. `ZIO[R, E, A]` means "consume R, fail with E, or succeed with A."

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's strength is **batteries included**. ZIO HTTP, ZIO Schema, ZIO JSON, ZIO Streams, ZIO Test, ZIO Config — a uniformly designed library family forms one camp. The learning curve exists, but once settled you can write the whole stack with a single mental model.

> ZIO follows a "one bowl holds everything" aesthetic — the counterpoint to Cats Effect's compositional minimalism.

Chapter 7 · Kyo — The Newest Effect Library

**Kyo** (Flavio Brasil, ex-Twitter) models algebraic effects directly. Effects accumulate in the type and handlers process them. It is closer to Idris's effect system.

def program: Int < (IO & Abort[Throwable] & Async) =

for

_ <- IO(println("start"))

n <- Async.runFiber(IO(42)).await

yield n

`A < S` reads as "result A, with effects S." S is a composition of effects. It is a more general shape than ZIO's R/E/A three-track.

Kyo matured rapidly in 2024–2025 and is widely discussed as "the next-generation effect library" in 2026. Its library ecosystem is still smaller than Cats Effect or ZIO, however.

Chapter 8 · Akka 23.x to Apache Pekko 1.0 — Two Roads After a License Change

In September 2022 Lightbend switched **Akka 2.7 onward to BSL** (Business Source License). Non-commercial use stays free; commercial use is paid. The decision shocked the open-source community.

The reply was **Apache Pekko**, started under the ASF. It is a fork of Akka 2.6.x with the package renamed from `akka` to `org.apache.pekko`.

| Tool | License | Governance | Status |

| --- | --- | --- | --- |

| Akka 23.x | BSL 1.1 plus commercial | Lightbend | Active new features |

| Apache Pekko 1.0 | Apache 2.0 | ASF | Akka 2.6 compatible plus incremental growth |

Code migration is almost a package rename.

// Akka

// Apache Pekko

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

ctx.log.info(msg)

Behaviors.same

}

As of 2026 nearly all new projects choose Apache Pekko. Existing Akka users weigh license fees against migration cost and the trend leans toward migration.

> For libraries, license is identity. This episode proved how much the open-source community values **governance stability**.

Chapter 9 · Actors and Streams — The Core of Apache Pekko 1.0

The two pillars of Pekko (and Akka) are **typed actors** and **streams**.

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 are a fluent DSL on top of the Reactive Streams spec.

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 — only the license differs. Feature parity is one-to-one.

Chapter 10 · http4s, Tapir, ZIO HTTP — A Three-Way Scala HTTP Race

The main Scala HTTP candidates are three.

| Library | Camp | Character |

| --- | --- | --- |

| http4s 0.23+ | Typelevel | `HttpRoutes[F]`, type-safe, fs2 based |

| Tapir 1.x | softwaremill | Declarative endpoints, backend adapters |

| ZIO HTTP | ZIO | ZIO-native, high performance |

**http4s** is the canonical functional HTTP library.

val routes = HttpRoutes.of[IO] {

case GET -> Root / "hello" / name =>

Ok(s"hi $name")

}

**Tapir** declares endpoints as data and auto-generates OpenAPI, Swagger, and type-safe clients.

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

val getUser = endpoint

.get

.in("users" / path[Long]("id"))

.out(jsonBody[User])

.errorOut(stringBody)

**ZIO HTTP** combines ZIO-native routing with strong performance. zio-http often tops benchmarks.

Choose by camp. Cats Effect stack picks http4s. ZIO stack picks ZIO HTTP. If you want backend independence, pick Tapir.

Chapter 11 · sbt 1.10.5, Mill 0.12, scala-cli — A Three-Way Build-Tool Race

For a long time sbt was effectively the only choice. In 2026 three tools coexist.

| Tool | Author / Org | Strength | Weakness |

| --- | --- | --- | --- |

| sbt 1.10.5 | Lightbend then community | Best compatibility, rich plugins | Steep curve, slow |

| Mill 0.12 | Li Haoyi | Concise Scala DSL, fast incremental builds | Fewer plugins |

| scala-cli | Virtus Lab | Single-file script friendly | Not for large projects |

A `build.sbt` example.

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

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 declares dependencies at the top of the file.

//> using scala 3.6.0

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

object Hello extends IOApp.Simple:

def run = IO.println("hi")

scala-cli was adopted as the official Scala runner (`scala run`) in 2024. For small scripts, data analysis, and teaching it is the de-facto standard. Larger projects go to sbt or Mill.

Chapter 12 · Scala.js, Laminar 17, Tyrian — Frontends Written in Scala

**Scala.js** compiles Scala to JavaScript. As of 2026 it is mature and webpack/vite integration is smooth.

**Laminar 17** (Nikita Gazarov) is a reactive UI framework built on FRP. Signals and observables drive state.

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** ports the Elm Architecture (model-update-view) to Scala.js. It pairs with the Indigo game engine.

**Outwatch** (Cornerman) is built on observables, in the spirit of RxJS. **Lampagne** is a newer SSR-friendly framework.

Selection criteria:

- "Declarative UI like React or Solid" — Laminar

- "Unidirectional data flow like Elm" — Tyrian

- "Familiar RxJS plus a small bundle" — Outwatch

> Laminar is often called "the best frontend you can write in Scala." It is a serious alternative worth comparing against TypeScript.

Chapter 13 · Scala Native 0.5 plus GraalVM Native Image — Two Roads to AOT

The JVM starts slowly, which is fatal for CLIs and serverless. Two solutions exist.

| Tool | How | Character |

| --- | --- | --- |

| Scala Native 0.5 | Compile directly through an LLVM backend | No JVM, C interop, small binary |

| GraalVM Native Image | AOT the JVM bytecode | Standard Java/Scala, needs reflection config |

// Scala Native

object Hello:

def main(args: Array[String]): Unit =

println("hello native")

Scala Native — direct LLVM compile

sbt nativeLink

GraalVM Native Image — AOT from JVM bytecode

native-image -jar app.jar

Scala Native has restricted library compatibility. JVM-only libraries do not run. GraalVM runs nearly any Java library, but reflection and dynamic class loading need careful config.

To use Scala in serverless (AWS Lambda, GCP Cloud Run), one of the two is essentially required. Cold starts drop below 100 ms.

Chapter 14 · Apache Spark 3.5 and Flink Scala — Scala's Place in Big Data

**Apache Spark** is written in Scala, and its API still feels most natural in Scala.

| Spark version | Scala target | Notes |

| --- | --- | --- |

| Spark 3.5 | Scala 2.13 / 2.12 | The 2026 mainstream |

| Spark 4.0 (preview) | Scala 2.13 / 3 | Connect, Spark Connect |

val spark = SparkSession.builder

.appName("demo")

.master("local[*]")

.getOrCreate()

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

df.filter($"v" > 1).show()

**Apache Flink** also exposes a Scala API. In 2023 Flink demoted its Scala API to best-effort, but the community sustains it.

**Apache Beam** has its own SDK; Spotify's **Scio** is the most popular Scala wrapper.

Scala 2.13 will not disappear from big data soon. Full Scala 3 support in Spark needs more time.

Chapter 15 · JSON, Schema, Codecs — circe, jsoniter-scala, upickle

JSON libraries also split into camps.

| Library | Camp | Character |

| --- | --- | --- |

| circe | Typelevel | Functional, type-class derivation |

| jsoniter-scala | Plokhotnyuk | Macro-generated fastest codec |

| upickle | Li Haoyi | Simple, light dependencies |

| ZIO JSON | ZIO | ZIO native, schema integration |

// circe

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

given Encoder[User] = deriveEncoder

given Decoder[User] = deriveDecoder

// jsoniter-scala

given JsonValueCodec[User] = JsonCodecMaker.make

In benchmarks jsoniter-scala is the clear winner (sometimes faster than native `JSON.parse`). circe composes smoothly with other Typelevel libraries. upickle is lightest when you "just need JSON."

Chapter 16 · The Database Layer — Doobie 1.0, Skunk, Quill, ScalikeJDBC

**Doobie 1.0** (Typelevel) — a functional wrapper over JDBC. Natural SQL on Cats Effect.

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) implements the native Postgres protocol directly on top of nio, with no JDBC. Fastest and smallest.

**Quill 4.x** — write queries as Scala expressions and translate them to SQL at compile time. Type-safe but with a learning curve.

**ScalikeJDBC** — a thin wrapper closer to plain JDBC. Pick it for familiarity.

// Quill

val ctx = new PostgresJdbcContext(SnakeCase, "ctx")

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

ctx.run(users)

Selection criteria are the camp (Cats Effect, ZIO, independent) and "do you want to write SQL directly or use a Scala expression."

Chapter 17 · Testing — Munit, ScalaTest 3.2, ZIO Test, weaver-test

Test frameworks are equally rich.

| Framework | Camp | Character |

| --- | --- | --- |

| Munit | Scala team | Concise, JUnit compatible |

| ScalaTest 3.2 | Classic | Many styles (FunSuite, FlatSpec, ...) |

| ZIO Test | ZIO | ZIO native, environment injection |

| weaver-test | disneystreaming | Cats Effect native, parallel by default |

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

object MathSpec extends SimpleIOSuite:

pureTest("add"):

expect(1 + 2 == 3)

Munit is close to a default. The ZIO camp uses ZIO Test; the Cats Effect camp leans on weaver-test or Munit-CatsEffect.

Chapter 18 · Iron and refined — Constrain Values via Types

**refined** (fthomas) and **Iron** (Iltotore) add "type-level constraints to values." For instance, a type that only accepts positive integers.

// Iron (Scala 3)

type Age = Int :| Positive

val a: Age = 30 // OK

// val b: Age = -1 // compile error

// refined (Scala 2/3 compatible)

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

Iron is Scala 3-only — lighter and more IDE friendly. refined has Scala 2 compatibility and pairs with ZIO Prelude and others.

Encoding API invariants in types is core to functional Scala's aesthetic.

Chapter 19 · Real Adoption — Twitter to X, Databricks, Twilio, Disney+, SoFi

Representative companies running Scala in production.

| Company | How they use it |

| --- | --- |

| Twitter / X | Finagle, util, Finatra. Most infrastructure in Scala. Some moved to Rust in 2023 |

| Databricks | Spark *is* the company. Scala 2.12/2.13 at massive scale |

| Twilio | Parts of the messaging backend in Akka/Pekko |

| Foursquare | Location data processing in Scala |

| ING Bank | Payment backends on Cats Effect |

| SoFi | Fintech backends on ZIO |

| Disney+ | Streaming backend services. weaver-test originated at Disney |

| Iagon | Distributed storage, on Cats Effect |

| Apple | Parts of the Siri / iCloud backend |

| Netflix | Recommendations and streaming pieces (historically more) |

There are fewer "all Scala" companies and more "Scala in a specific domain" companies. This mirrors the maturity of other JVM languages such as Kotlin and Java 21. But in **data engineering, payment backends, and distributed systems**, Scala's place is solid.

Chapter 20 · Korean and Japanese Scala Communities

**Korea**:

- **ScalaKorea** — the Korean Scala user group. Kakao, LINE, Coupang, and Woowa Brothers are the core.

- **Kakao Brain / Kakao Pay** — Scala/Spark in data pipelines.

- **LINE** — parts of the messaging backend in Scala/Akka, with Scala 2.13/3 coexistence.

- **Coupang** — parts of data engineering.

- **Woowa Brothers** — catalog and batch services in Scala.

- **NHN Cloud / Naver** — Scala/Spark on top of Hadoop.

**Japan**:

- **ScalaMatsuri** — Asia's largest Scala conference, held annually in Tokyo.

- **Scala Tokyo** — the Tokyo Scala user group.

- **CyberAgent** — ad backends in Scala.

- **Septeni** — ad-tech domain.

- **Mercari** — parts of payments and settlement.

- **DMM.com** — parts of the backend.

- **NTT Communication Science Labs** — academic / research use.

East-Asia Scala adoption skews toward **data engineering, advertising, and payments**. Both Korea and Japan center on Spark/Akka workloads, while functional libraries (Cats Effect, ZIO) spread quickly through new projects.

Chapter 21 · Scala 3 Pitfalls and Best Practices

Common traps when moving to Scala 3 for the first time.

| Trap | Symptom | Mitigation |

| --- | --- | --- |

| Blindly rewriting every `implicit` as `given` | Semantics drift | Distinguish `using` / `extension` / `given` |

| Leaving Scala 2 macros as-is | Compile failure | Rewrite via Quotes API |

| Pulling in shapeless | Overkill on Scala 3 | Replace with `Mirror`-based derivation |

| Enabling capture checking too early | Library compatibility breaks | Off on LTS, on only for new modules |

| Mixing sbt, Mill, and scala-cli | Build cognitive dissonance | Pick one |

| Adding new code on Akka 23 | License burden | Write new code on Apache Pekko |

| Mixing effect camps | Conversion boilerplate explodes | Bridge Cats Effect and ZIO at the edges only |

| Reliance on reflective Java APIs | Native Image build fails | reflect-config or `@reflective` |

| Too many implicit conversions | Slow IDE, hard debugging | Prefer explicit conversion |

| Iron / refined everywhere | Long compile times | Apply only to domain invariants |

Scala 3 rewards "thoughtful simplicity" even more than the tooling improvements suggest.

Chapter 22 · The Next Five Years — Scala Settles In

A look at the next five years.

1. **Scala 3.3 LTS solidifies.** Nearly all new code targets 3, but Spark keeps Scala 2.13 libraries alive longer.

2. **Effect camps narrow.** Cats Effect and ZIO become the stable camps, and Kyo emerges as a future-standard candidate.

3. **Apache Pekko becomes the de-facto standard.** Commercial Akka licenses shrink to large enterprises only.

4. **Builds: sbt plus scala-cli as the duopoly** — Mill stays the specialty pick.

5. **Scala.js frameworks like Laminar and Tyrian** make full-stack Scala viable for small SaaS.

6. **Scala Native plus GraalVM** normalizes serverless and CLI Scala.

7. **Scala in the AI era** — data pipelines (Spark) become the standard for LLM indexing and embedding, while LLM clients emerge atop ZIO and Cats Effect.

8. **Standardization** — TASTy stabilizes, macro APIs stabilize, and library API-compatibility culture matures.

Scala is no longer "a complicated functional language." It is a toolbox. And that toolbox is becoming something an everyday engineer can pick up by choice.

Epilogue — Where Should You Start

If the toolset in this article feels overwhelming, here is a learning path.

1. **Language** — the official Scala 3 tutorial and the 5th edition of "Programming in Scala" (Odersky et al.).

2. **Builds** — try single-file scripts with scala-cli. Then move to sbt or Mill for multi-module projects.

3. **Effects** — pick Cats Effect or ZIO and write a small "Bookings"-style example.

4. **HTTP** — build a REST API with http4s or Tapir.

5. **Database** — connect to Postgres with Doobie or Skunk.

6. **Frontend** — build a one-page SPA with Scala.js plus Laminar.

7. **Production** — ship a small CLI compiled with Scala Native or GraalVM.

> "What do you want to prove, where will you run it, and which paradigm does your team know?" Hold these three questions while re-reading this article, and the tool choices become surprisingly clear.

— Modern Scala 2026, fin.

References

1. Odersky, M. et al. "Scala 3 Reference." [https://docs.scala-lang.org/scala3/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](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html)

3. Typelevel. "Cats Effect 3 Documentation." [https://typelevel.org/cats-effect/](https://typelevel.org/cats-effect/)

4. Ziverge. "ZIO 2 Documentation." [https://zio.dev/](https://zio.dev/)

5. Brasil, F. "Kyo Project." [https://github.com/getkyo/kyo](https://github.com/getkyo/kyo)

6. Lightbend. "Akka License Change Announcement." [https://www.lightbend.com/blog/why-we-are-changing-the-license-for-akka](https://www.lightbend.com/blog/why-we-are-changing-the-license-for-akka)

7. Apache Software Foundation. "Apache Pekko." [https://pekko.apache.org/](https://pekko.apache.org/)

8. http4s. "http4s Documentation." [https://http4s.org/](https://http4s.org/)

9. softwaremill. "Tapir Documentation." [https://tapir.softwaremill.com/](https://tapir.softwaremill.com/)

10. dream11. "ZIO HTTP." [https://zio.dev/zio-http/](https://zio.dev/zio-http/)

11. sbt Authors. "sbt Reference Manual." [https://www.scala-sbt.org/1.x/docs/](https://www.scala-sbt.org/1.x/docs/)

12. Haoyi, L. "Mill Build Tool." [https://mill-build.org/](https://mill-build.org/)

13. Virtus Lab. "scala-cli." [https://scala-cli.virtuslab.org/](https://scala-cli.virtuslab.org/)

14. Gazarov, N. "Laminar." [https://laminar.dev/](https://laminar.dev/)

15. PurpleKingdomGames. "Tyrian." [https://tyrian.indigoengine.io/](https://tyrian.indigoengine.io/)

16. Scala Native Team. "Scala Native 0.5." [https://scala-native.org/](https://scala-native.org/)

17. Apache Spark. "Spark Scala API." [https://spark.apache.org/docs/latest/api/scala/index.html](https://spark.apache.org/docs/latest/api/scala/index.html)

18. Plokhotnyuk, A. "jsoniter-scala." [https://github.com/plokhotnyuk/jsoniter-scala](https://github.com/plokhotnyuk/jsoniter-scala)

19. Typelevel. "Doobie." [https://tpolecat.github.io/doobie/](https://tpolecat.github.io/doobie/)

20. Typelevel. "Skunk." [https://typelevel.org/skunk/](https://typelevel.org/skunk/)

21. Scalameta. "Munit." [https://scalameta.org/munit/](https://scalameta.org/munit/)

22. Disney Streaming. "weaver-test." [https://disneystreaming.github.io/weaver-test/](https://disneystreaming.github.io/weaver-test/)

23. Iltotore. "Iron." [https://iltotore.github.io/iron/](https://iltotore.github.io/iron/)

24. ScalaMatsuri. "ScalaMatsuri Conference." [https://scalamatsuri.org/](https://scalamatsuri.org/)

25. Scala Center. "Scala Toolkit." [https://docs.scala-lang.org/toolkit/introduction.html](https://docs.scala-lang.org/toolkit/introduction.html)

현재 단락 (1/392)

Back in 2020, Scala still carried the image of "powerful but complicated." `sbt` was the only build ...

작성 글자: 0원문 글자: 23,286작성 단락: 0/392