All suggestions welcome :)!

If you’d like to contribute, see the list of issues and pick one! Or report your own. If you have an idea you’d like to discuss, that’s always a good option.

If you are having doubts on the why or how something works, don’t hesitate to ask a question on discourse or via github. This probably means that the documentation, scaladocs or code is unclear and can be improved for the benefit of all.



Scala 3 introduces enum, which can be used to represent sealed hierarchies with simpler syntax, or actual “true” enumerations, that is parameterless enums or sealed traits with only case objects as children. Tapir needs to treat the latter differently, in order to allow using OpenAPI enum elements and derive JSON codecs which represent them as simple values (without discriminator). Let’s use the name enumeration in Tapir codebase to represent these “true” enumerations and avoid ambiguity.

JDK version

To ensure that Tapir can be used in a wide range of projects, the CI job uses JDK11 for most of the modules. There are exceptions (like netty-server-sync and nima-server) which require JDK version >= 21. This requirement is adressed by the build matrix in .github/workflows/ci.yml, which runs separate builds on a newer Java version, and sets a ONLY_LOOM env variable, used by build.sbt to recognise that it should limit the scope of an aggregated task to these projects only. For local development, feel free to use any JDK >= 11. You can be on JDK 21, then with missing ONLY_LOOM variable you can still run sbt tasks on projects excluded from aggegate build, for example:

// etc.


Tuple-concatenating code is copied from akka-http

Parts of generic derivation configuration is copied from circe

Implementation of mirror for union and intersection types are originally implemented by Iltotore in this gist

Tapir logo & stickers have been drawn by impurepics.