This gives us:
- Type safety
- Normalized conversation of values with
envToBoolean/String/Number
- Nested/complex config objects
- Validation
But we don't need to rely on zod to coerce the values.
One issue this doesn't resolve is different requirements per stage (e.g. some values not being required for development). But you could use this pattern to create per-stage schemas. Zod provides some useful schema "extension/modification" functions (e.g. z.extend
, z.pick
, z.omit
). So you could create a base schema with all the shared config requirements and then extend to create the per-stage schemas.