I came to conclusion that even in fully-Scala projects it’s better to define enums using Java. Even third-party libraries that have support for Scala enums suffer from the fact that in runtime all Scala enums have the same type. So if you get some enum value - you have no way to tell to which enum type does it belong. Let me show you how bad it can be with json4s. If you have such enums:

object FooVersion extends Enumeration {
  val V1, V2, V3 = Value
object BarVersion extends Enumeration {
  val V1, V2, V3 = Value

and such formats:

implicit val formats = org.json4s.DefaultFormats +
  new org.json4s.ext.EnumNameSerializer(FooVersion) +
  new org.json4s.ext.EnumNameSerializer(BarVersion)

you will be able to serialize and deserizlize the data:

val d1 = SampleData(name = "first foo", version = FooVersion.V1)
println("original: " + d1)
val s1 = Serialization.write(d1)
println("serialized: " + s1)
val ds1 = Serialization.read[SampleData](s1)
println("deserialized: " + ds1)

and it will look the same:

original: SampleData(first foo,V1)
serialized: {"name":"first foo","version":"V1"}
deserialized: SampleData(first foo,V1)

but the objects are not going to be equal!

println("original == deserialized: " + (d1 == ds1))

prints following result:

original == deserialized: false

With debugger you may inspect private fields and discover that type of d1.version.scala$Enumeration$$OuterEnum is FooVersion$, and of ds1.version.scala$Enumeration$$OuterEnum - BarVersion$.