Iltotore/iron
Strong type constraints for Scala
{ "createdAt": "2021-01-13T11:48:58Z", "defaultBranch": "main", "description": "Strong type constraints for Scala", "fullName": "Iltotore/iron", "homepage": "https://iltotore.github.io/iron/docs/", "language": "Scala", "name": "iron", "pushedAt": "2025-11-24T09:03:12Z", "stargazersCount": 534, "topics": [ "assert", "functional-programming", "refinement-types", "scala", "types" ], "updatedAt": "2025-11-24T09:03:08Z", "url": "https://github.com/Iltotore/iron"}
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
Section titled “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 validationruntimeValue.refineEither[Positive].map(log) //More explicitlyHelpful error messages
Section titled “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.0Message: 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
Section titled “Import in your project”SBT:
libraryDependencies += "io.github.iltotore" %% "iron" % "version"Mill:
ivy"io.github.iltotore::iron:version"Note: replace version with the version of Iron.
Platform support
Section titled “Platform support”| Module | JVM | JS | Native |
|---|---|---|---|
| iron | ✔️ | ✔️ | ✔️ |
| iron-borer | ✔️ | ✔️ | ❌ |
| iron-cats | ✔️ | ✔️ | ✔️ |
| iron-circe | ✔️ | ✔️ | ✔️ |
| iron-ciris | ✔️ | ✔️ | ✔️ |
| iron-decline | ✔️ | ✔️ | ✔️ |
| iron-doobie | ✔️ | ❌ | ❌ |
| iron-jsoniter | ✔️ | ✔️ | ✔️ |
| iron-pureconfig | ✔️ | ❌️ | ❌️ |
| iron-scalacheck | ✔️ | ✔️ | ❌ |
| iron-scodec | ✔️ | ✔️ | ✔️ |
| iron-skunk | ✔️ | ✔️ | ✔️ |
| iron-upickle | ✔️ | ✔️ | ✔️ |
| iron-zio | ✔️ | ✔️ | ❌ |
| iron-zio-json | ✔️ | ✔️ | ❌ |
| iron-play-json | ✔️ | ✔️ | ❌ |
Adopters
Section titled “Adopters”Here is a non-exhaustive list of projects using Iron.
Submit a PR to add your project or company to the list.