zio/izumi-reflect
{ "createdAt": "2020-02-17T12:25:42Z", "defaultBranch": "develop", "description": "TypeTag without scala-reflect. Supports Scala 2 and Scala 3.", "fullName": "zio/izumi-reflect", "homepage": "https://zio.dev/izumi-reflect", "language": "Scala", "name": "izumi-reflect", "pushedAt": "2025-11-26T22:29:19Z", "stargazersCount": 152, "topics": [], "updatedAt": "2025-11-26T22:29:22Z", "url": "https://github.com/zio/izumi-reflect"}[![Project stage][Stage]][Stage-Page]
Please consider supporting our work through GitHub Sponsors.
izumi-reflect
Section titled “izumi-reflect”@quote: Looks a bit similar to TypeTag
izumi-reflect is a fast, lightweight, portable and efficient alternative for TypeTag from scala-reflect.
izumi-reflect is a lightweight model of Scala type system and provides a simulator of the important parts of the Scala typechecker.
Why izumi-reflect
Section titled “Why izumi-reflect”izumi-reflectcompiles faster, runs a lot faster thanscala-reflectand is fully immutable and thread-safe,izumi-reflectsupports Scala 2.11, 2.12, 2.13 and Scala 3,izumi-reflectsupports Scala.js and Scala Native,izumi-reflectworks well with GraalVM Native Image,izumi-reflectallows you to obtain tags for unapplied type constructors (F[_]) and combine them at runtime.
Credits
Section titled “Credits”izumi-reflect has been created by Septimal Mind to power Izumi Project,
as a replacement for TypeTag in reaction to a lack of confirmed information about the future of scala-reflect/TypeTag in Scala 3 (Motivation), and donated to ZIO.
Limitations
Section titled “Limitations”izumi-reflect model of the Scala type system is not 100% precise, but “good enough” for the vast majority of the usecases.
Known limitations are:
- Recursive type bounds (F-bounded types) are not preserved and may produce false positives,
- Existential types, both written with wildcards and
forSomemay produce unexpected results, the support is limited, - Path-Dependent Types are based on variable names and may cause unexpected results when variables with different names have the same type or vice-versa (vs. Scala compiler)
- This-Types such as
X.this.typeare ignored and identical toX izumi-reflectis less powerful thanscala-reflect: it does not preserve fields and methods when it’s not necessary for equality and subtype checks, it does not preserve code trees, internal compiler data structures, etc.- There are some optimizations in place which reduce correctness, namely: subtype check for
scala.Matchablewill always return true, no distinction is made betweenscala.Anyandscala.AnyRef, no distinction is made betweenscala.Nothingandscala.Null. In other words, the library does not recognize thatNullis not a subtype ofAnyVals. - Lower bounds are not preserved in abstract higher-kinded type members which may produce false comparisons.
- Type and value members are not preserved in concrete types which may produce false comparisons with refined/structural types. (https://github.com/zio/izumi-reflect/issues/481)
Debugging
Section titled “Debugging”Set -Dizumi.reflect.debug.macro.rtti=true to enable debug output during compilation when tags are constructed and at runtime when they are compared.
sbt -Dizumi.reflect.debug.macro.rtti=trueTo see debug output when compiling in Intellij, add the above flag to VM options in [Preferences -> Build, Execution, Deployment -> Compiler -> Scala Compiler -> Scala Compile Server]!(jetbrains://idea/settings?name=Build%2C+Execution%2C+Deployment—Compiler—Scala+Compiler—Scala+Compile+Server)
You may also set it in .jvmopts file during development. (.jvmopts properties will not apply to Intellij compile server, only to sbt)
Set -Dizumi.reflect.debug.macro.rtti.assertions=true to enable additional assertions.
Other useful system properties are:
build.sbt is generated by sbtgen. During development you may not want to mess with ScalaJS and ScalaNative, you may generate a pure-JVM Scala project:
./sbtgen.scOnce you finished tinkering with the code you may want to generate full project and test it for all the platforms:
./sbtgen.sc --js --nativesbt +testTo develop using Scala 2 invoke sbtgen with a scala version argument:
./sbtgen.sc 2 // 2.13./sbtgen.sc 2.12 // 2.12Likewise with Scala 3:
./sbtgen.sc 3In Intellij, you may also set Scala version by changing the option sbt -> sbt settings -> Open cross-compiled projects Scala 3 / Scala 2 projects as:
Provided flake.nix can be used to set up the external dependencies necessary to build the project, such as sbt, JDK, coursier, etc:
nix developThe project’s CI is built with mudyla, you may reproduce CI build locally with:
nix develop --command mdl --github-actions :gen :testAvailable mudyla actions are defined in [.mdl/defs/*.md]!(.mdl/defs/)
- Kit Langton — Scala 3 Macro Fun (Open Source Hackery)
- Pavel Shirshov — Izumi Reflect: Scala Type System Model
See also
Section titled “See also”- Scala 3 only
- No support for subtype checks
- Type lambdas are not supported
- Preserves field information
- Scala 2 and Scala 3
- No support for subtype checks
- Preserves field information
And even more
Section titled “And even more”- https://github.com/gaeljw/typetrees - a very basic type tag substitute for Scala 3
- https://stackoverflow.com/questions/75752812/is-there-a-simple-scala-3-example-of-how-to-use-quoted-type-as-replacement-for - discussion on StackOverflow
- https://contributors.scala-lang.org/t/scala-3-and-reflection/3627 - original discussion on Scala Contributors forum
[Stage] !: https://img.shields.io/badge/Project%20Stage-Production%20Ready-brightgreen.svg [Stage-Page] !: https://github.com/zio/zio/wiki/Project-Stages
