Introduction
Uni is the standard library Scala 3 didn't ship with.
Logging, object wiring, JSON & MessagePack, reactive streams, HTTP clients and servers, RPC, and a browser UI toolkit — small, composable pieces that work identically on the JVM, in the browser and Node.js (Scala.js), and as native binaries (Scala Native), with almost no external dependencies.
It distills the most-used building blocks of the Airframe ecosystem into one cohesive, Scala-3-first library.
Get going in 30 seconds
Add one dependency (Installation) and you have all of it — no à-la-carte modules to assemble.
A quick taste
Object wiring, structured logging, and lifecycle management — three things you usually reach for three libraries for — in a handful of lines:
import wvlet.uni.design.Design
import wvlet.uni.log.LogSupport
class GreeterService extends LogSupport:
def greet(name: String): String =
info(s"Greeting ${name}") // logs with source file + line
s"Hello, ${name}!"
@main def main =
Design.newDesign
.bindSingleton[GreeterService]
.build[GreeterService] { greeter => // wired, started, and cleaned up
println(greeter.greet("Uni"))
}Why Uni?
- 🪶 Minimal dependencies — foundational utilities without dragging in a heavy framework.
- 🌍 One codebase, three runtimes — the same source compiles for JVM, Scala.js, and Scala Native.
- 🧩 Composable — small, focused APIs designed to combine, not to lock you in.
- ⚡ Scala 3 first — built around
derives,given, enums, and macros. - 🔋 Production-tested — battle-hardened code, refined from the Airframe ecosystem.
Uni and Airframe
Uni is the Scala 3 successor of Airframe. The two projects have different goals:
- Uni supports only Scala 3. Dropping Scala 2 lets it make full use of Scala 3 features in its APIs and implementation. It also bundles the core utilities into a few modules (
uni,uni-netty,uni-test) instead of manyairframe-*artifacts. - Airframe supports both Scala 2 and Scala 3, and it remains maintained. There is no plan to deprecate it.
Which one should I use?
For a new Scala 3 project, use Uni. If your project still needs Scala 2, or you depend on Airframe modules that Uni doesn't cover, keep using Airframe. See the Airframe migration table for how APIs map between them.
What's inside
Core
| Module | Description |
|---|---|
| Design | Object wiring with lifecycle management |
| Logging | Logging with source-location tracking |
| Surface | Compile-time type introspection |
| FileSystem | Cross-platform file I/O with IOPath |
Data & Serialization
| Module | Description |
|---|---|
| JSON | Pure-Scala JSON parser and DSL |
| MessagePack | Compact binary serialization |
| Weaver | Derivation-based codecs — JSON / MessagePack / Map from one derives Weaver |
Async & Control Flow
| Module | Description |
|---|---|
| Rx | Reactive streams and async data flows |
| Control | Retry, circuit breaker, rate limiter, cache, resources |
| BackgroundTask | Cancellable, progress-pollable background workers |
HTTP & RPC
| Module | Description |
|---|---|
| HTTP | Cross-platform client and server (Netty / Node.js / Native) |
| RPC | Type-safe remote calls, with client code generation |
| WebSocket | Cross-platform bidirectional WebSocket client |
| Server-Sent Events | One-way server→client streaming |
UI & CLI
| Module | Description |
|---|---|
| CLI | Terminal styling, progress bars, command launching |
| Web UI | Reactive browser UIs with RxElement (Scala.js) |
Testing
| Module | Description |
|---|---|
| UniTest | Lightweight, expressive, cross-platform test framework |
Next steps
- 📦 Installation — add Uni to your sbt / Scala CLI project
- 🧭 Design Principles — the architecture and the why
- 🔍 Core Utilities — start exploring the foundational APIs