Maybe https://github.com/corenting/immutabledict:
Important differences:
__init__ versus __new__. IDK why immutabledict uses __new__. It's decidedly less convenient for subclassing and in no way is __new__ needed over __init__.
- JAX compatibility
Maybe https://flax.readthedocs.io/en/latest/api_reference/flax.core.frozen_dict.html
This might be the best option, if we could get them to spin it off into a separate package.