One answer I see used in various languages is to version each stable format. Later, when you change to a new format you write a translator that reads the older format and converts it to the new when loaded.
The translator is not only responsible for repackaging the data into the new format but also providing sensible defaults for new properties or merging extinct properties into existing ones if their meaning isn't meant to be lost.
You can keep creating new versions as long as you keep writing matching translators, the conversions will then happen serially from the first match up to your most recent (eg. v1 -> v2 -> v3 -> v4).
When the new data is saved out it automatically is set to the latest version. In this way writing a utility to bulk-translate all old data (for major releases) is as simple as a loop: