Iron
Strong type constraints for Scala
Install / Use
/learn @Iltotore/IronREADME

Iron is a lightweight library for refined types in Scala 3.
It enables attaching constraints/assertions to types, to enforce properties and forbid invalid values.
- Catch bugs. In the spirit of static typing, use more specific types to avoid invalid values.
- Compile-time and runtime. Evaluate constraints at compile time, or explicitly check them at runtime (e.g. for a form).
- Seamless. Iron types are subtypes of their unrefined versions, meaning you can easily add or remove them.
- No black magic. Use Scala 3's powerful inline, types and restricted macros for consistent behaviour and rules. No unexpected behaviour.
- Extendable. Easily create your own constraints or integrations using classic typeclasses.
To learn more about Iron, see the microsite.
Example
import io.github.iltotore.iron.*
import io.github.iltotore.iron.constraint.numeric.*
def log(x: Double :| Positive): Double =
Math.log(x) //Used like a normal `Double`
log(1.0) //Automatically verified at compile time.
log(-1.0) //Compile-time error: Should be strictly positive
val runtimeValue: Double = ???
log(runtimeValue.refineUnsafe) //Explicitly refine your external values at runtime.
runtimeValue.refineEither.map(log) //Use monadic style for functional validation
runtimeValue.refineEither[Positive].map(log) //More explicitly
Helpful error messages
Iron provides useful errors when a constraint does not pass:
log(-1.0)
-- Constraint Error --------------------------------------------------------
Could not satisfy a constraint for type scala.Double.
Value: -1.0
Message: Should be strictly positive
----------------------------------------------------------------------------
Or when it cannot be verified:
val runtimeValue: Double = ???
log(runtimeValue)
-- Constraint Error --------------------------------------------------------
Cannot refine non full inlined input at compile-time.
To test a constraint at runtime, use the `refine` extension method.
Note: Due to a Scala limitation, already-refined types cannot be tested at compile-time (unless proven by an `Implication`).
Inlined input: runtimeValue
----------------------------------------------------------------------------
Import in your project
SBT:
libraryDependencies += "io.github.iltotore" %% "iron" % "version"
Mill:
mvn"io.github.iltotore::iron:version"
Note: replace version with the version of Iron.
Platform support
| Module | JVM | JS | Native | |-----------------|-----|----|--------| | iron | ✔️ | ✔️ | ✔️ | | iron-borer | ✔️ | ✔️ | ❌ | | iron-cats | ✔️ | ✔️ | ✔️ | | iron-circe | ✔️ | ✔️ | ✔️ | | iron-ciris | ✔️ | ✔️ | ✔️ | | iron-chimney | ✔️ | ✔️ | ✔️ | | iron-decline | ✔️ | ✔️ | ✔️ | | iron-doobie | ✔️ | ❌ | ❌ | | iron-dynosaur | ✔️ | ✔️ | ❌ | | iron-jsoniter | ✔️ | ✔️ | ✔️ | | iron-pureconfig | ✔️ | ❌️ | ❌️ | | iron-scalacheck | ✔️ | ✔️ | ❌ | | iron-scodec | ✔️ | ✔️ | ✔️ | | iron-skunk | ✔️ | ✔️ | ✔️ | | iron-upickle | ✔️ | ✔️ | ✔️ | | iron-zio | ✔️ | ✔️ | ❌ | | iron-zio-json | ✔️ | ✔️ | ❌ | | iron-play-json | ✔️ | ✔️ | ❌ |
Adopters
Here is a non-exhaustive list of projects using Iron.
Submit a PR to add your project or company to the list.
Companies
Other projects
Useful links
Related Skills
node-connect
330.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
81.3kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
330.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
81.3kCommit, push, and open a PR
