dry-schema is a validation library for data structures. It ships with a set of many built-in predicates and powerful macros that allow you to define even complex validation logic with very concise syntax.

Main focus of this library is on:

  • Data structure validation
  • Value types validation

dry-schema is also used as the schema engine in dry-validation

Unique features

There are a few features of dry-schema that make it unique:

  • Structural validation where key presence can be verified separately from values. This removes ambiguity related to “presence” validation where you don’t know if value is indeed nil or if a key is missing in the input hash
  • Pre-coercion validation using filtering rules
  • Explicit coercion logic - rather than implementing complex generic coercions, dry-schema uses coercion types from dry-types which are faster and more strict than generic coercions
  • Support for validating array elements with convenient access to error messages
  • Powerful introspection - you have access to key maps and detailed Rule AST
  • Performance - multiple times faster than validations based on ActiveModel and strong parameters
  • Configurable, localized error messages with or without I18n gem

When to use?

Always and everywhere. This is a general-purpose data validation library that can be used for many things and it’s multiple times faster than ActiveRecord/ActiveModel::Validations and strong-parameters.

Possible use-cases include validation of:

  • Form params
  • “GET” params
  • JSON documents
  • YAML documents
  • Application configuration (ie stored in ENV)
  • Replacement for strong-parameters
  • etc.

Quick start

require 'dry/schema'

UserSchema = Dry::Schema.Params do


  required(:address).hash do

  name: 'Jane',
  email: '',
  address: { street: 'Street 1', city: 'NYC', zipcode: '1234' }

# #<Dry::Schema::Result{:name=>"Jane", :email=>"", :address=>{:street=>"Street 1", :city=>"NYC", :zipcode=>"1234"}} errors={:age=>["age is missing"]}>