A comprehensive Elixir data validation library with flexible, composable validators
The package can be installed by adding valdi
to your list of dependencies in mix.exs
:
def deps do
[
{:valdi, "~> 0.5.0"}
]
end
Document can be found at https://hexdocs.pm/valdi.
- ✅ Type validation - validate data types including numbers, strings, lists, maps, structs, and Decimal types
- ✅ Constraint validation - validate ranges, lengths, formats, and inclusion/exclusion
- ✅ Flattened validators - use convenient aliases like
min
,max
,min_length
without nesting - ✅ Pattern matching - efficient validation dispatch using Elixir's pattern matching
- ✅ Composable - combine multiple validations in a single call
- ✅ Backward compatible - works with existing validation patterns
- ✅ Conditional type checking - skip type validation when not needed for better performance
- ✅ List and map validation - validate collections and structured data
- ✅ Custom validators - extend with your own validation functions
- ✅ Flexible error handling - option to ignore unknown validators
# Type validation
Valdi.validate("hello", type: :string)
#=> :ok
# Constraint validation without type checking (new!)
Valdi.validate("hello", min_length: 3, max_length: 10)
#=> :ok
# Combined validations
Valdi.validate(15, type: :integer, min: 10, max: 20, greater_than: 5)
#=> :ok
Instead of nested syntax:
# Old nested approach
Valdi.validate("test", type: :string, length: [min: 3, max: 10])
Valdi.validate(15, type: :integer, number: [min: 10, max: 20])
Use convenient flattened syntax:
# New flattened approach
Valdi.validate("test", type: :string, min_length: 3, max_length: 10)
Valdi.validate(15, type: :integer, min: 10, max: 20)
# Mix both styles
Valdi.validate(15, min: 10, number: [max: 20])
# Validate each item in a list
Valdi.validate_list([1, 2, 3], type: :integer, min: 0)
#=> :ok
# With errors showing item indexes
Valdi.validate_list([1, 2, 3], type: :integer, min: 2)
#=> {:error, [[0, "must be greater than or equal to 2"]]}
# Define validation schema
schema = %{
name: [type: :string, required: true, min_length: 2],
age: [type: :integer, min: 0, max: 150],
email: [type: :string, format: ~r/.+@.+/]
}
# Validate map data
Valdi.validate_map(%{name: "John", age: 30, email: "john@example.com"}, schema)
#=> :ok
Valdi.validate_map(%{name: "J", age: 30}, schema)
#=> {:error, %{name: "length must be greater than or equal to 2"}}
Each validator can be used independently:
Valdi.validate_type("hello", :string)
#=> :ok
Valdi.validate_number(15, min: 10, max: 20)
#=> :ok
Valdi.validate_length("hello", min: 3, max: 10)
#=> :ok
Valdi.validate_inclusion("red", ["red", "green", "blue"])
#=> :ok
type
- validate data typerequired
- ensure value is not nilformat
/pattern
- regex pattern matchingin
/enum
- value inclusion validationnot_in
- value exclusion validationfunc
- custom validation function
number
- numeric constraints (nested syntax)min
- minimum value (≥)max
- maximum value (≤)greater_than
- strictly greater than (>)less_than
- strictly less than (<)
length
- length constraints (nested syntax)min_length
- minimum lengthmax_length
- maximum lengthmin_items
- minimum array items (alias for min_length)max_items
- maximum array items (alias for max_length)
each
- validate each item in arraysdecimal
- decimal validation (deprecated, usenumber
instead)
Built-in types:
:boolean
,:integer
,:float
,:number
(int or float):string
,:binary
(string is binary alias):tuple
,:array
,:list
,:atom
,:function
,:map
:date
,:time
,:datetime
,:naive_datetime
,:utc_datetime
:keyword
,:decimal
Extended types:
{:array, type}
- typed arrays (e.g.,{:array, :string}
)struct
modules (e.g.,User
for%User{}
structs)
# Type validation examples
Valdi.validate(["one", "two", "three"], type: {:array, :string})
#=> :ok
Valdi.validate(%User{name: "John"}, type: User)
#=> :ok
Valdi.validate(~D[2023-10-11], type: :date)
#=> :ok
ignore_unknown: true
- skip unknown validators instead of returning errors
Valdi.validate("test", [type: :string, unknown_validator: :value], ignore_unknown: true)
#=> :ok
For detailed documentation, examples, and API reference, visit https://hexdocs.pm/valdi.