JSV is a JSON Schema validator for Elixir, designed for modern applications. It provides full compliance with the latest JSON Schema specifications while offering a seamless, Elixir-native developer experience.
Key Features
- Full Specification Compliance: 100% support for Draft 2020-12
(including
$dynamicRef,$dynamicAnchor, and all vocabularies) and Draft 7. - High Performance: Schemas can be pre-compiled into an optimized internal representation. Build your validation roots at compile-time for near-zero runtime overhead.
- Elixir-Native Schemas: Use
defschemato define schemas as Elixir modules. Supports automatic casting to Elixir structs with default values. - Advanced Casting & Transformation:
- Built-in support for casting to
Date,DateTime,Duration, andDecimal. - Extensible casting system using the
jsv-castkeyword anddefcastmacros.
- Built-in support for casting to
- Extensible Resolution: Fetch remote schemas via HTTP or resolve them from local files and directories using custom or built-in resolvers.
- Flexible Workflows: Supports schemas as atoms or binaries, from Elixir code, JSON files, or the network. JSV supports many ways to work with schemas.
- Extensible Vocabularies: Thanks to features of Draft 2020-12, custom meta-schemas with custom schema keywords are supported out of the box.
- Functional Builder API: Compose schemas dynamically using a functional API.
- Rich Error Handling: Detailed validation errors that can be easily normalized into JSON-compatible structures for API responses.
- Complete support in Oaskit: Oaskit is an OpenAPI 3.1 validator for Phoenix and is entirely built on JSV.
Documentation
Comprehensive guides and API documentation are available on hexdocs.pm.
Supported Dialects
JSV supports 100% of features from Draft 2020-12 and Draft 7 as verified by the JSON Schema Compliance Test Suite.
Installation
Add jsv to your mix.exs:
def deps do [ {:jsv, "~> 0.18"}, ] end
Optional Dependencies
JSV integrates with popular Elixir libraries to provide enhanced functionality:
def deps do [ # JSV Supports Decimal and will validate Decimal structs as numbers. {:decimal, "~> 2.0"}, # Required for resolving schemas via HTTP on Elixir < 1.18. {:jason, "~> 1.0"}, # OR {:poison, "~> 6.0"} ] end
Usage
Simple Validation
schema = %{ type: :object, properties: %{ name: %{type: :string} }, required: [:name] } root = JSV.build!(schema) case JSV.validate(%{"name" => "Alice"}, root) do # %{"name" => "Alice"} {:ok, data} -> IO.inspect(data) {:error, err} -> IO.inspect(JSV.normalize_error(err)) end
Module-Based Schemas
Define your business objects and validation logic in one place:
defmodule MyApp.User do use JSV.Schema defschema %{ type: :object, properties: %{ name: string(minLength: 1), age: integer(minimum: 0, default: 18) }, required: [:name] } end # Build at compile-time for maximum performance root = JSV.build!(MyApp.User) # Casting to structs is enabled by default %MyApp.User{name: "Alice", age: 18} = JSV.validate!(%{"name" => "Alice"}, root)
Pydantic style modules
use JSV.Schema defschema MyApp.Data.Food, ~SD""" A Tasty dish, hopefully """, name: string(), origin: string() defschema MyApp.Data.Profile, ~SD""" Information about a user profile """, name: string(), birthdate: optional(date()), favorite_food: MyApp.Data.Food defschema MyApp.Data.User, ~SD""" System user information """, profile: MyApp.Data.Profile, role: string_enum_to_atom([:admin, :writer, :reader]) data = %{ "profile" => %{ "name" => "Alice", "birthdate" => "1994-01-08", "favorite_food" => %{ "name" => "Pad Thai", "origin" => "Thailand" } }, "role" => "admin" } root = JSV.build!(MyApp.Data.User, formats: true) JSV.validate!(data, root, cast_formats: true)
With this simple module form you can define many struct schemas in a compact way. The code above will cast the data (and the birthdate as well):
%MyApp.Data.User{ profile: %MyApp.Data.Profile{ birthdate: ~D[1994-01-08], favorite_food: %MyApp.Data.Food{name: "Pad Thai", origin: "Thailand"}, name: "Alice" }, role: :admin }
Contributing
Please ensure your changes include thorough tests and follow the existing documentation style.
License
JSV is released under the Apache License Version 2.0.