Changelog
View SourceAll notable changes to this project will be documented in this file.
0.10.7 - 2025-11-16
Added
- Recipes guide with common use cases and examples of
Zoiusage.
0.10.6 - 2025-11-13
Added
Zoi.one_of/2type to accept a value that matches exactly one of the provided literal values.
0.10.5 - 2025-11-13
Changed
Zoi.enum/2typespec for binary now returnsbinary()instead of literals.
0.10.4 - 2025-11-10
Changed
- Fix
Zoi.Struct.enforce_keys/1to work whenZoi.default/2wraps aZoi.optional/2type
0.10.3 - 2025-11-10
Added
- wrap
Zoi.Type.t()intoZoi.schema()type - Group guides on hexdocs
0.10.2 - 2025-11-10
Added
Zoi.Schema.traverse/2for recursively walking and transforming schema structures. This function applies a transformation to all nested fields while leaving the root schema unchanged, making it easy to apply operations like coercion, nullish, or defaults across an entire schema tree.Zoi.coerce/1helper function to enable type coercion on schemas that support it.
Changed
Zoi.transform/2andZoi.refine/2are now chained in the order they were added, allowing more flexible validation and transformation flows.
0.10.1 - 2025-11-09
Added
Zoi.describe/1now supportsZoi.struct/2type.
0.10.0 - 2025-11-09
Added
Zoi.Formmodule withprepare/1andparse/2functions for seamless Phoenix form integration.Phoenix.HTML.FormDataprotocol implementation forZoi.Context, enabling Phoenix form rendering without losing the original params.- Partial parsing data is now preserved inside
%Zoi.Context{}(and surfaced through forms) even when validation fails, allowing Phoenix forms to keep previously valid entries. - Keyword schemas defined with another schema as the value now keep the successfully parsed entries even if a sibling entry fails validation.
Zoi.Form.prepare/1now forces coercion on every nested field so Phoenix form strings are cast into their target types automatically.Zoi.Form.parse/2automatically normalizes LiveView's map-based array format (with numeric string keys) into regular lists inctx.input, eliminating the need for manual conversion when manipulating array fields dynamically.- Architecture diagram in main module documentation (
Zoi) showing the parsing flow and validation pipeline with Mermaid visualization.
Changed
- Achieved 100% test coverage across the entire codebase (previously 99.8%).
0.9.1 - 2025-11-06
Added
Zoi.JSONSchemanow acceptsZoi.decimal/1, converting it totype: "number".
0.9.0 - 2025-11-06
Added
Zoi.array/2now accepts:coerceoption to forceMapandTupletypes into an array.
Changed
Zoi.type_spec/1for object with string keys now returns genericmap()type spec due to how Elixir handles this type internally.
0.9.0-rc.1 - 2025-11-04
Added
Zoi.object/2andZoi.keyword/2now accept:empty_valuesoption to define which values are considered empty when parsing objects and keyword lists. By default, this option is set to[], meaning no values are considered empty. You can customize this option to include values likenil, empty strings (""), or any other value you want to treat as empty and it will return a:requirederror when those values are encountered for required fields.
0.9.0-rc.0 - 2025-11-04
Changed
- All errors have been reworked to include more context on the error
codeandissue. Now errors will have the following structure (example):
%Zoi.Error{
code: :invalid_type,
issue: {"invalid type: expected string", [expected: :string]},
message: "invalid type: expected string",
path: [:user, :name]
}And it's also possible to have errors with dynamic messages:
%Zoi.Error{
code: :invalid_literal,
message: "invalid literal: expected true",
issue: {"invalid literal: expected %{expected}", [expected: true]},
path: []
}This will give more flexibility when handling errors programmatically, and better support with tools such as Gettext for localization.
- Removed
Zoi.gt/3andZoi.lt/3refinements for strings. UseZoi.min/3andZoi.max/3instead. - Allow all refinements to accept custom error messages.
Zoi.url/2now uses elixir's built-inURI.parse/1for URL validation.
0.8.4 - 2025-11-01
Changed
- Fix nested
Zoi.keyword/2error when parsing invalid values - Fix
Zoi.Describewhen dealing withDecimaloptional dependency
0.8.3 - 2025-10-31
Added
- All types now implements the
Inspectprotocol. This should improve the ergonomics when working with Zoi types in IEx or when inspecting/debugging it's types.
0.8.2 - 2025-10-30
Added
Zoi.non_negative/2refinement for numbers to accept values from 0 and aboveZoi.describe/1returns a structured documentation for keyword and object types
Changed
Zoi.keyword/2now can accept a schema in the first argument to validate the values of the keyword listZoi.keyword/2type_spec now reflects correctly the keyword list definition
0.8.1 - 2025-10-27
Changed
- Update readme with new metadata examples and reference to main api
0.8.0 - 2025-10-26
Added
Zoi.nullish/2type to acceptnilor a value of a specific type@specfor all public functions@typedocfor all public typesZoi.description/1option to add description metadata to types for documentation purposesZoi.example/1option to add example metadata to types for documentation purposes
Changed
Zoi.to_json_schema/1now readsdescription,exampleopts from types to include them in the generated JSON Schema
0.7.4 - 2025-10-25
Changed
Zoi.regex/3fix regex compilation, now theregex.optsare properly handled
0.7.3 - 2025-10-20
Added
Zoi.email/1now acceptspatternoption to customize the email regex
Changed
Zoi.enum/2now acceptscoerceoption to coerce values to the key or to the value
0.7.2 - 2025-10-13
Added
- Fixed example in
guides/using_zoi_to_generate_openapi_specs.md
0.7.1 - 2025-10-12
Added
Zoi.to_json_schema/1support for metadata (e.g., example, description)guides/quickstart_guide.mdadded to the documentation
0.7.0 - 2025-10-10
Added
Zoi.to_json_schema/1function to convertZoischemas to JSON Schema format
Changed
Zoi.array/2fixed path in errors when parsing arraysZoi.regex/2fixed regex compile errors when used in module attributes
0.6.6 - 2025-10-08
Added
Zoi.metadata/1- option to add metadata to types for documentation purposes
Changed
Zoi.example/1deprecated in favor ofZoi.metadata/1
0.6.5 - 2025-10-07
Added
Zoi.example/1option to add example values to types for documentation and testing purposes
0.6.4 - 2025-09-30
Added
Zoi.downcase/1refinement to validate if a string is in lowercaseZoi.upcase/1refinement to validate if a string is in uppercaseZoi.hex/1refinement to validate if a string is a valid hexadecimal
0.6.3 - 2025-09-27
Added
keysinZoi.object/2data structureZoi.struct/2type to parse structs and maps into structsZoi.Structmodule with helper functions to work with structs. This module offers two main functions:Zoi.Struct.enforce_keys/1: List of keys that must be present in the structZoi.Struct.struct_keys/1: List of keys and their default values to be used withdefstruct
0.6.2 - 2025-09-26
Added
Zoi.literal/2type to accept only a specific literal value
Changed
- Refactor all errors to be generated on type creation instead of parsing time
0.6.1 - 2025-09-08
Added
Zoi.null/1type to accept onlynilvaluesZoi.positive/1refinement for numbers to accept only positive valuesZoi.negative/1refinement for numbers to accept only negative values
0.6.0 - 2025-09-07
Added
Zoi.required/2type to enforce presence of a value inkeywordandobjecttypes
Changed
Zoi.object/2now usesmfato call innertransformfunctionZoi.keyword/2have all fields set as optional by default, useZoi.required/2to enforce presence of a value
0.5.7 - 2025-09-06
Changed
Zoi.parse!/3Error message
0.5.6 - 2025-09-05
Added
Zoi.parse!/3function that raises an error if parsing failsZoi.type_spec/2function that returns the Elixir type spec for a given Zoi schema, implemented for all types
0.5.5 - 2025-09-03
Added
Zoi.keyword/2type
Changed
Zoi.struct/2now works with the newZoi.keyword/2type- Improved
Zoi.transform/2documentation
0.5.4 - 2025-08-29
Added
- Guide for converting keys from maps
- Guide for generating schema from JSON structure
0.5.3 - 2025-08-29
Changed
- Fix
transformandrefinementtypes
0.5.2 - 2025-08-28
Added
Zoi.prettify_errors/2added docsZoi.extend/3type
Changed
Zoi.map/3now parses key and value types correctly- Fix encapsulated types ignoring refinements and transforms when parsing
0.5.1 - 2025-08-17
Changed
Zoi.prettify_errors/1don't return\nat the end of the string anymore
0.5.0 - 2025-08-17
Added
Zoi.atom/1typeZoi.string_boolean/1typeZoi.union/2custom error messagesZoi.intersection/2custom error messagesZoi.to_struct/2transform
Changed
Zoi.boolean/1does not coerce values besides "true" and "false" anymore. For coercion of other values, useZoi.string_boolean/1type.
0.4.0 - 2025-08-14
Added
Zoi.Contextmodule to provide context when parsing data
Changed
Zoi.object/2will not automatically parse objects with inputs that differ from the string/atom keys map format. For example:
schema = Zoi.object(%{
name: Zoi.string(),
age: Zoi.integer()
})
Zoi.object(schema, %{"name" => "John", "age" => 30})
{:error, _errors}To make this API work, you can pass coerce: true option to Zoi.object/2. This will make the object parser to check from the Map input if the keys are strings or atoms and fetch it's values automatically.
schema = Zoi.object(%{
name: Zoi.string(),
age: Zoi.integer()
})
Zoi.object(schema, %{"name" => "John", "age" => 30}, coerce: true)
{:ok, %{name: "John", age: 30}}0.3.4 - 2025-08-09
Added
Zoi.min/2,Zoi.max/2,Zoi.gt/2,Zoi.gte/2,Zoi.lt/2,Zoi.lte/2refinements forZoi.time/1typeZoi.min/2,Zoi.max/2,Zoi.gt/2,Zoi.gte/2,Zoi.lt/2,Zoi.lte/2refinements forZoi.date/1typeZoi.min/2,Zoi.max/2,Zoi.gt/2,Zoi.gte/2,Zoi.lt/2,Zoi.lte/2refinements forZoi.datetime/1typeZoi.min/2,Zoi.max/2,Zoi.gt/2,Zoi.gte/2,Zoi.lt/2,Zoi.lte/2refinements forZoi.naive_datetime/1type
0.3.3 - 2025-08-09
Added
Zoi.time/1typeZoi.date/1typeZoi.datetime/1typeZoi.naive_datetime/1type
0.3.2 - 2025-08-09
Added
Zoi.decimal/1typeZoi.min/2,Zoi.max/2,Zoi.gt/2,Zoi.gte/2,Zoi.lt/2,Zoi.lte/2refinements forZoi.decimal/1type
0.3.1 - 2025-08-08
Added
Zoi.ISO.time/1typeZoi.ISO.date/1typeZoi.ISO.datetime/1typeZoi.ISO.to_time_struct/1transformZoi.ISO.to_date_struct/1transformZoi.ISO.to_datetime_struct/1transformZoi.ISO.to_naive_datetime/1transformZoi.prettify_errors/1function to format errors in a human-readable way
0.3.0 - 2025-08-07
Added
Zoi.email/0formatZoi.url/0formatZoi.uuid/1format
Changed
- Removed
Zoi.email/1, now useZoi.email/0that will automatically use theZoi.string/1type - All refinements now accept a
:messageoption to customize the error message
0.2.3 - 2025-08-06
Added
Zoi.map/3typeZoi.intersection/2typeZoi.gt/2refinementZoi.gte/2refinementZoi.lt/2refinementZoi.lte/2refinement
0.2.2 - 2025-08-06
Added
- Guides for using
Zoiin Phoenix controllers - New
Zoi.tuple/2type - New
Zoi.any/1type - New
Zoi.nullable/2type
Changed
- Improved error messages for all validations and types
Zoi.treefy_errors/1now returns a more human-readable structureZoi.optional/2cannot acceptnilas a value anymore. UseZoi.nullable/2instead.Zoi.optional/2insideZoi.object/2now handles optional fields correctly
0.2.1 - 2025-08-06
Added
- Custom error messages for primitive types
Changed
Zoi.number/2now returns proper error message
0.2.0 - 2025-08-05
Added
mfatoZoi.refine/2andZoi.transform/2functions- accumulator errors to
Zoi.refine/2andZoi.transform/2functions Zoi.array/2typeZoi.length/2,Zoi.min/2andZoi.max/2validators for arrays
Changed
- errors are now returned as a list of
%Zoi.Error{}structs