In theory, Scala Pickling would be the direction of improvement in which the compiler presents type information and emits appropriate serialization and deserialization code into JSON or some binary format. However, in my own experience, there were major issues in the detail because it guessed how an object should be constructed, and it often guessed incorrectly. See A path forward for pickling Java objects · Issue #296 · scala/pickling · GitHub.
So generally I have felt more sympathetic to idea of data binding, defining the wire protocol first, and deriving the Java or Scala object second rather than the idea of trying to serialize everything. XML databinding is an example, but general IDL (interface description languages) such as Protobuf, Avro, and Apache Thrift are all pretty widely used, for good reasons. Fast runtime performance and safe route to evolving the datatype over time.
If we do go with serialization route, I hope we learn the lesson and use a serializer with static typeclass – as in fail at compile-time when it encounters a class that it’s unable to serialize into JSON. I am guessing there are lots of JSON serialization solutions to pick from like Circe, uPickle, and Play JSON.
There’s also Sauerkraut - “A revitalization of Pickling in the Scala 3 world.” by @jsuereth. I haven’t looked into the details, but maybe that will be the answer that combines the strengths of both worlds.