Well, every language requires you to write serialization code unless you have the rare case where your datastructures line up 1:1 with your serialized structure over the wire. And the 1:1 case is already trivial with Elm. So I don't really understand the complaint.
Frankly, with something like serde in Rust, it's such a pain to deviate from the 1:1 case that you tend to stick to the 1:1 datastructure despite how suboptimal it is, maybe manually transforming it after parse time if you can be bothered. I don't find that to be any superior to Elm's simple combinators.
My experience with Elm's codecs is that there's a small learning curve if the concept is new to you. And then after some real world experience you wonder how it was ever alien at all. I wish I had it in every other language I've worked with.