Open-source project
DavyJonesLocker/client_side_validations avatar
DavyJonesLocker/client_side_validations

ClientSideValidations: Rails Validation Rules That Run in the Browser

Client Side Validations made easy for Ruby on Rails

2,682 stars395 forksRubyMIT

At a glance

What is it?
ClientSideValidations mirrors ActiveModel validation rules into the browser so Rails 7.2 and 8.x forms fail fast without a round trip. It is a good fit for standard validations on standard form builders, and a poor fit for anything driven by conditional callbacks or non-Rails front ends.
Who is it for?
Adopt ClientSideValidations if your forms are built with Rails form builders and your validations are plain ActiveModel rules such as presence, length, format and uniqueness. Skip it if your rules depend on :if or :unless callbacks, if your forms are rendered by a JavaScript framework, or if you are not ready to audit custom validators for the 24.x DOM API.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 6 days ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What ClientSideValidations actually solves for Rails forms

A Rails form with ActiveModel validations gives the user nothing until submit. The request goes out, the controller runs valid?, the page re-renders with error markup, and the user finds out about a missing field after a full round trip. ClientSideValidations closes that gap by reading the validation rules already declared on the model and applying the same rules in the browser. The README states the goal plainly: automatically extract and apply validation rules defined on the server to the client. The audience is Rails developers on 7.2 and 8.x who use the standard form builders and want inline error feedback without writing a second set of rules in JavaScript. The project's stated goals also include matching the server-side error rendering as closely as possible, which matters more than it sounds: if the client and server disagree on how an error looks, users see the page flicker on submit. It is not a general-purpose validation library. It is a bridge between ActiveModel and the DOM, and it assumes Rails on both ends.

How the rules get from ActiveModel to the browser

The mechanism is extraction, not duplication. The gem reads the validators attached to your model and serialises them into attributes on the rendered form fields. The JavaScript package then reads those attributes, builds a validator per field, and runs it on the events it listens to. The README lists nested field validation, custom validations, client side validation callbacks and a plugin system for additional FormBuilders and ORMs as goals, which tells you the extraction layer is meant to be extended rather than hardcoded to one builder. The design decision worth noting is goal three: where a server-side rule cannot work on the client, such as conditional callbacks like :if or :unless, the project does not attempt a client side validation and falls back to the server. That is the honest choice, and it is also the source of the most common surprise. A field guarded by a condition will simply not validate in the browser, and the user will only learn about the error on submit. If your model leans heavily on conditional validations, a large share of your form will behave exactly like it did before you installed the gem.

Installing the gem and wiring up the JavaScript

Add the gem to your Gemfile and run the installer. The installer writes config/initializers/client_side_validations.rb.

ruby
gem 'client_side_validations'
bash
bundle install
rails g client_side_validations:install

The README notes that if you use Spring you should run spring stop. The JavaScript side depends on your stack. With Webpacker, add the npm package and import it in your pack. ClientSideValidations no longer depends on jQuery, so a jquery-rails install kept around only for this gem can go.

bash
yarn add @client-side-validations/client-side-validations
js
import '@client-side-validations/client-side-validations'

With Sprockets, require the asset instead. The order matters for Turbo and Turbolinks users: the README says to import the package after @hotwired/turbo-rails, or to require it after Turbolinks.start(), so it can detect window.Turbo or window.Turbolinks and attach its handlers. If you would rather vendor the asset files, the generator rails g client_side_validations:copy_assets copies them into your project, and the README warns you will need to re-run it on every update. After that, render a normal Rails form and the fields pick up the extracted rules.

The 24.x API break is the real upgrade cost

Version 24.x removed the jQuery plugin methods and replaced them with a DOM-first API. If you call ClientSideValidations.enable(form), validate(form), isValid(form, validators), disable(form) or reset(form), those methods now take native DOM elements and DOM collections. They do not accept jQuery objects or CSS selector strings. Custom validators, form builders and callbacks also receive native DOM nodes instead of jQuery wrappers, so code that reached for jQuery methods has to move to .value, .form, .closest() and querySelector(). Local validators are called as (element, options); form callbacks receive (form, eventData); element callbacks receive either (element, message, callback) or (element, callback) depending on the event. The runtime also renamed its state attributes under a csv namespace. data-changed becomes data-csv-changed, data-valid becomes data-csv-valid, data-validate becomes data-csv-validate and data-not-locally-unique becomes data-csv-not-locally-unique, with matching dataset properties such as element.dataset.csvChanged. Note that csvChanged is stored as the strings 'true' and 'false', not booleans. jQuery namespaced events are gone too: instead of $(form).on('form:validate:before.ClientSideValidations', handler) you use form.addEventListener('form:validate:before', handler) and keep the handler reference for removeEventListener. The native events are form:validate:before, form:validate:after, form:validate:pass, form:validate:fail, element:validate:before, element:validate:after, element:validate:pass and element:validate:fail. If you are already on 23.x, the README frames the 24.x step as updating local uniqueness integrations.

Where ClientSideValidations is the wrong tool

The conditional-callback fallback is the biggest one, and it is by design rather than a bug. Any rule behind :if or :unless runs only on the server, so the inline feedback users expect does not appear for those fields. Uniqueness validations are the second limitation. The project has a concept of local uniqueness, which the 24.x notes treat as an integration you may need to update, but a uniqueness check that depends on the current state of the database cannot be settled in the browser. The gem can only do what a client can do. Third, the whole approach assumes Rails renders the form. If you are building a React or Vue front end that talks to a Rails JSON API, there are no server-rendered fields for the extractor to annotate, and the plugin system for additional FormBuilders does not change that. Fourth, the browser target list in package.json is broad (Chrome and Firefox 60 and up, Safari and iOS 12 and up), and the Node engine requirement is 18.12 or later, so an old build pipeline is a separate obstacle. Finally, the README does not document rollback, so plan the upgrade as a one-way step within a release branch.

Compared with plain HTML constraint validation

The obvious alternative is the browser's own constraint validation: required, maxlength, pattern and friends, or a small hand-written script. The difference in approach is where the rules live. HTML attributes are declared once per field in the view, so the same rule exists in the model and in the template, and the two drift the moment someone edits one. ClientSideValidations keeps the model as the single source and extracts from it, which is why nested fields and custom validators are on the goal list. The trade is control: HTML constraint validation works without a gem, without a build step and without a Rails version constraint, and its messages come from the browser locale. ClientSideValidations gives you Rails-style error rendering that matches the server, and it costs you an initializer, an npm or Sprockets asset, and a migration whenever the public API changes, as it did in 24.x. For a small form with three fields, the HTML attributes are less machinery. For a large Rails application where the same validation logic is repeated across dozens of forms, the extraction approach is the one that stays consistent.

Editorial conclusion

Adopt ClientSideValidations if your forms are built with Rails form builders and your validations are plain ActiveModel rules such as presence, length, format and uniqueness. Skip it if your rules depend on :if or :unless callbacks, if your forms are rendered by a JavaScript framework, or if you are not ready to audit custom validators for the 24.x DOM API. Before upgrading, read the 24.x migration section and grep your codebase for data-changed, data-valid, data-validate and data-not-locally-unique, because those attributes are now namespaced under csv.

Frequently asked questions

What is the difference between client-side and server-side validation in ClientSideValidations?

The gem extracts the validation rules defined on your ActiveModel models and applies them in the browser, while the server still runs the original validations on submit. When a rule cannot work on the client, such as a conditional callback using :if or :unless, the project skips the client side check and falls back to the server.

Does ClientSideValidations still require jQuery?

No. The README states that ClientSideValidations no longer depends on jQuery, and that if you installed jquery-rails, jquery_ujs or custom jQuery startup code only for this gem, you can remove that integration when upgrading to 24.x.

Which Rails versions does the ClientSideValidations gem support?

The README describes it as made easy for Rails 7.2 and 8.x applications. The npm package description uses the same wording.

How do I install the client side validations gem in a Rails app?

Add gem 'client_side_validations' to your Gemfile, run bundle install, then run rails g client_side_validations:install, which writes config/initializers/client_side_validations.rb. The JavaScript side is added separately, either through yarn with @client-side-validations/client-side-validations or through Sprockets with //= require rails.validations.

What changed in ClientSideValidations 24.x?

The jQuery plugin methods were removed in favour of a DOM-first API that accepts native DOM elements, not jQuery objects or CSS selector strings. Validation state attributes were renamed under a csv namespace, for example data-changed becomes data-csv-changed, and jQuery namespaced events were replaced with plain native DOM custom events.

Official sources

  1. DavyJonesLocker/client_side_validations on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/davyjoneslocker-client-side-validations.svg)](https://hysenlabs.com/projects/davyjoneslocker-client-side-validations)