Enumeratum 1.4: ValueEnums + Circe
It’s been a while since the last major release of Enumeratum, and in 1.4.0, minor changes include Play 2.5 support, integration library version bumps, and small internal refactorings. More excitingly though, the latest version adds support for a new kind of enumeration, ValueEnum, as well as an integration with the Circe JSON library.
Points of interest:
- Unlike other value enum implementations, Enumeration’s value enums perform uniqueness checks at compile time to make sure you have unique values across your enum members.
- Circe integration allows you to send and receive JSON data between your front end and your server using the same code

The 1.4.0 release page on Github has a more detailed list of changes, but we’ll specifically go through:
ValueEnums
What is a ValueEnum? It’s an enum that represents a primitive value (e.g. Int, Long, Short) instead of a String. I may have just made up the term, but it doesn’t matter as long as you know what I mean.
1 2 3 4 5 6 7 8 | |
This may sound mundane, since you can already build something like this yourself with the standard library’s Enumeration (or previous versions of Enumeratum ), but sometimes the most straightforward solutions are suboptimal.
The trouble with Enumeration
The standard lib’s Enumeration comes with the notion of a customisable id: Int on each member, which is a great starting point for implementing numbers-based enumerations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | |
This funny behaviour is caused by the fact that Enumeration#Values (First, Second, Third, Fourth) are not checked for unique ids at compile time, and are instantiated when their outer Enumeration object is lazily instantiated. When a Value is instantiated, its id is stuffed into a HashMap[Int, Value] after an assertion check that the id does not already exist in the map.
What has happend in the above example is the enumeration code compiles, but when we call Things.First, object Things gets instantiated, and throws an assertion error when val Fourth is being instantiated with an id of 3, which has already been assigned to Third and thus is already in the aforementioned HashMap. This prevents the singleton Things from getting instantiated, and the next time you try to use it, Scala will throw a NoClassDefFoundError.
One way to work around this is to write tests for every such Enumeration to make sure that no one working in the code base has fat-fingered any ids. I’m a big proponent of writing tests, but tests are also code and come with a maintenance and cognitive cost, so I would prefer not having to write tests to make sure my simple value enums can be safely initialised.
This kind of problem is not limited to Enumeration: careless implementation of something similar may result in arguably freakier outcomes such as silent failures (2 members with the same value but only one of the members can be retrieved by value).
ValueEnum
In version 1.4.0 of Enumeratum, we’ve introduced 3 pairs of traits: IntEnum and IntEnumEntry, LongEnum and LongEnumEntry, and ShortEnum and ShortEnumEntry. As their names suggest, these are value enum traits that allow you to create enums that are backed by Int, Long and Short respectively. Each pair extends ValueEnum and ValueEnumEntry. Note that this class hierarchy is a bit extensive for now, and it may be more streamlined in the future.
This is an example of how you would create an Long based value enum with Play integration (JSON readers and writers, Query string binders, Path binders, Form formatters, etc):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
The findValues method of ValueEnums works similarly to the findValues method of Enumeratum’s older Enum, except the macro will ensure that there is a literal value member or constructor for each enum entry and fails the compilation if more than one member shares the same value.
As the above example demonstrates, there are Play (and standalone Play-JSON) integrations available for this new kind of enum, as well as for UPickle, and Circe.
~~Note that this new feature is not yet available in Scala 2.10 and in the REPL due to Macro expansion differences~~ (update: now works in the REPL and is available for 2.10.x!).
Circe integration
Enumeratum 1.4.0 also adds support for serialising/deserialising to JSON using Circe, an up-and-coming performant and feature-filled JSON library published for both JVM and ScalaJS.
This is how you would use Circe with Enumeratum’s Enum (integrations for ValueEnum also exist)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Conclusion
Hopefully, Enumeratum’s new ValueEnum implementations will make development easier and safer for engineers out there who need to use value enumerations. Since uniqueness is checked at compile-time, you can save yourself the trouble of writing a bunch of pedantic tests. Circe is a promising JSON library that was really easy to integrate with and I look forward to taking advantage of the fact that it works on both server side and on the front end.
As always, if you have any problems, questions, suggestions, or better yet, PRs, please do not hesitate to get in touch on Github.