Skip to content

Implementations ​

LIVR is a specification, so you need an implementation for your language. All of them use the same rules format and return the same error codes. The latest version of the specification is 2.0; the previous one was 0.4.

JavaScript

LIVR 2.0Test suite: 70/70
npm
livrv2.12.1
Docs
js.livr-spec.org
Maintainer
@koorchik
Last activity
Oct 2026 ★ 185

Reference implementation. Sync and async validators, TypeScript type inference.

Java

LIVR 2.0Test suite: 70/70
Maven Central
io.github.vlbaluk:validator-livrv2.0.2
Maintainer
@vlbaluk
Last activity
Oct 2026 ★ 14

Returns the standard error codes, but wraps each one together with the invalid value: {"code": "REQUIRED", "fieldValue": …}.

Raku

LIVR 2.0Test suite: 70/70
raku.land
LIVR
Maintainer
@koorchik
Last activity
Oct 2026 ★ 6

Formerly Perl 6.

Dart

LIVR 2.0Test suite: 70/70
pub.dev
livrv0.1.0
Maintainer
@koorchik
Last activity
Oct 2026

Rust

LIVR 2.0Test suite: 70/70
crates.io
livrv0.1.0
Maintainer
@koorchik
Last activity
Oct 2026

Swift

LIVR 2.0Test suite: 63/70 (v1.0.5)
CocoaPods
Livrv1.0.4
Maintainer
@olxbr
Last activity
Jul 2026 ★ 8

Python

LIVR 2.0Test suite: 56/70
PyPI
LIVRv2.0.1
Maintainer
@asholok
Last activity
Dec 2017 ★ 26

Package versions and repository activity are refreshed every time the site is built.

Test suite results ​

Every implementation is checked against the shared test suite. Every week, and whenever the specification changes, CI installs each implementation the way a user would and runs all test cases against it.

ImplementationTested versionPassedDetails
JavaScript2.12.170 / 70All cases pass
Perl2.170 / 70All cases pass
PHPdev-master@93e31c968 / 68All cases pass
2 cases not counted
  • negative/22-not_empty_list
    PHP decodes {} and [] to the same array, so an empty object can't be told apart from an empty list. php-validator-livr's own copy of the test suite adjusts this case.
  • negative/27-any_object
    PHP decodes {} and [] to the same array, so an empty object can't be told apart from an empty list. php-validator-livr's own copy of the test suite adjusts this case.
Java2.0.270 / 70

Errors are returned as {"code": …, "fieldValue": …} objects instead of plain error codes (the library adds the invalid value to every error), so only the codes are compared.

All cases pass
Ruby2.1.070 / 70All cases pass
Erlang · Olifer2.0.2@aef75c570 / 70

Not published on hex; built from the repository.

All cases pass
Raku2.2.170 / 70

Run on Rakudo Star 2024.02: LIVR 2.1.0 no longer compiles on current Rakudo (a rx:P5 regex in LIVR::Rules::Special).

All cases pass
Dart0.1.070 / 70All cases pass
Rust0.1.070 / 70All cases pass
Gov2.0.0+incompatible66 / 70
4 failing cases
  • positive/16-email
    expected no errors, got {"email10":"WRONG_EMAIL","email11":"WRONG_EMAIL","email12":"WRONG_EMAIL","email13":"WRONG_EMAIL","email20":"WRONG_EMAIL","email21":"WRONG_EMAIL","email22":"WRONG_EMAIL","email23":"WRONG_EMAIL","email25":"WRONG_EMAIL","email26":"WRONG_EMAIL","email4":"WRONG…
  • negative/21-list_of_different_objects
    exception: interface conversion: interface {} is []interface {}, not string
  • negative/28-variable_object
    exception: interface conversion: interface {} is map[string]interface {}, not string
  • negative/29-or
    expected errors {"id1-1":"NOT_POSITIVE_INTEGER","id2-1":"NOT_POSITIVE_INTEGER","id3-1":"WRONG_EMAIL","id4-1":"CANNOT_BE_EMPTY","id4-2":"REQUIRED","products":[{"name":"REQUIRED","product_type":"NOT_ALLOWED_VALUE"},{"name":"REQUIRED"}]}, got {"id1-1":"NOT_POSITIVE_INTEGER","id2-1":…
Lua0.5.164 / 68

Installed with the optional lrexlib-pcre2 and luautf8 rocks, which the `like` rule and Unicode-aware to_lc/to_uc need.

4 failing cases
  • positive/16-email
    expected no errors, got {"email10":"WRONG_EMAIL","email25":"WRONG_EMAIL","email22":"WRONG_EMAIL","email23":"WRONG_EMAIL","email26":"WRONG_EMAIL","email7":"WRONG_EMAIL","email20":"WRONG_EMAIL","email8":"WRONG_EMAIL","email21":"WRONG_EMAIL","email12":"WRONG_EMAIL","email13":"WRONG_…
  • negative/16-email
    expected errors {"email5":"WRONG_EMAIL","email18":"WRONG_EMAIL","value_is_empty_array":"FORMAT_ERROR","value_is_empty_hash":"FORMAT_ERROR","email23":"WRONG_EMAIL","email3":"WRONG_EMAIL","email26":"WRONG_EMAIL","value_is_array":"FORMAT_ERROR","email15":"WRONG_EMAIL","email9":"WRON…
  • negative/21-list_of_different_objects
    expected errors {"order_id":"NOT_POSITIVE_INTEGER","only_wrong_items":["FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR"],"null_item":["FORMAT_ERROR"],"selector_is_builtin_property":["FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR"],"selector_i…
  • negative/29-or
    expected errors {"id2-1":"NOT_POSITIVE_INTEGER","id1-1":"NOT_POSITIVE_INTEGER","products":[{"product_type":"NOT_ALLOWED_VALUE","name":"REQUIRED"},{"name":"REQUIRED"}],"id4-1":"CANNOT_BE_EMPTY","id3-1":"WRONG_EMAIL","id4-2":"REQUIRED"}, got {"id2-1":"NOT_POSITIVE_INTEGER","id1-1":…
2 cases not counted
  • negative/22-not_empty_list
    Lua decodes {} and [] to the same empty table, so an empty object can't be told apart from an empty list. lua-LIVR's own copy of the test suite adjusts this case.
  • negative/27-any_object
    Lua decodes {} and [] to the same empty table, so an empty object can't be told apart from an empty list. lua-LIVR's own copy of the test suite adjusts this case.
Swift1.0.5@a36235363 / 70

Apple platforms only: it relies on NSPredicate format strings, which Foundation on Linux doesn't provide. Built from source in Swift 4.2 language mode on macOS.

7 failing cases
  • positive/16-email
    expected no errors, got {"email7":"WRONG_EMAIL","email8":"WRONG_EMAIL","email10":"WRONG_EMAIL","email12":"WRONG_EMAIL","email13":"WRONG_EMAIL","email20":"WRONG_EMAIL","email21":"WRONG_EMAIL","email22":"WRONG_EMAIL","email23":"WRONG_EMAIL","email25":"WRONG_EMAIL","email26":"WRONG_…
  • positive/18-nested_object
    expected output {"address":{"building":10,"country":"Ukraine","street":"10","zip":12345},"builtin_names":{"constructor":"Constructor value","toString":"ToString value"},"should_be_empty":{},"should_not_be_errored":""}, got {"address":{"building":10,"country":"Ukraine","street":"1…
  • positive/30-trim
    expected output {"decimal_value":"1.2","list_of_string_values":["value1",{"key":"123"},"value2"],"object":{"string_value":"some value"},"string_value":"value","unicode_string":"Привет"}, got {"decimal_value":1.2,"list_of_string_values":["value1",{"key":"123"},"value2"],"object":{…
  • negative/16-email
    expected errors {"email1":"WRONG_EMAIL","email2":"WRONG_EMAIL","email3":"WRONG_EMAIL","email4":"WRONG_EMAIL","email5":"WRONG_EMAIL","email6":"WRONG_EMAIL","email7":"WRONG_EMAIL","email8":"WRONG_EMAIL","email9":"WRONG_EMAIL","email10":"WRONG_EMAIL","email11":"WRONG_EMAIL","email12…
  • negative/21-list_of_different_objects
    expected errors {"null_item":["FORMAT_ERROR"],"only_wrong_items":["FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR","FORMAT_ERROR"],"order_id":"NOT_POSITIVE_INTEGER","products":[{"material_id":"NOT_POSITIVE_INTEGER","quantity":"REQUIRED"},{"warehouse_id":"NOT_POSITIVE_I…
  • negative/24-iso_date
    expected errors {"iso_date1":"WRONG_DATE","iso_date2":"WRONG_DATE","iso_date3":"WRONG_DATE","iso_date4":"WRONG_DATE","iso_date5":"WRONG_DATE","iso_date6":"WRONG_DATE","iso_date7":"WRONG_DATE","iso_date8":"WRONG_DATE","iso_date9":"WRONG_DATE","like_iso_date":"WRONG_DATE","value_is…
  • negative/29-or
    expected errors {"id1-1":"NOT_POSITIVE_INTEGER","id2-1":"NOT_POSITIVE_INTEGER","id3-1":"WRONG_EMAIL","id4-1":"CANNOT_BE_EMPTY","id4-2":"REQUIRED","products":[{"name":"REQUIRED","product_type":"NOT_ALLOWED_VALUE"},{"name":"REQUIRED"}]}, got {"id1-1":"NOT_POSITIVE_INTEGER","id2-1":…
Erlang · Liver1.1.061 / 70

Validated with liver's `rule_set => livr_spec` mode.

liver has no API for registering data-defined rule aliases, so the alias cases fail.

9 failing cases
Python2.0.156 / 70
14 failing cases
  • positive/17-equal_to_field
    expected no errors, got {"number_as_string": "FIELDS_NOT_EQUAL"}
  • positive/18-nested_object
    expected output {"address": {"building": 10, "country": "Ukraine", "street": "10", "zip": 12345}, "builtin_names": {"constructor": "Constructor value", "toString": "ToString value"}, "should_be_empty": {}, "should_not_be_errored": ""}, got {"address": {"building": 10, "country": …
  • positive/33-remove
    expected output {"list_of_string_values": ["value1", {"key": "123"}, "value"], "object": {"string_value": "Vluelue Vlue"}, "string_value": "aluevaluealue"}, got {"list_of_string_values": ["value1", {"key": "123"}, "value"], "object": {"string_value": "V- V"}, "string_value": "alu…
  • positive/34-leave_only
    expected output {"list_of_string_values": ["", {"key": "123"}, "23"], "object": {"string_value": "a-vaa"}, "string_value": "Vl l Vl"}, got {"list_of_string_values": ["", {"key": "123"}, "23"], "object": {"string_value": "aluevaluealue"}, "string_value": "Vl l Vl"}
  • negative/12-positive_decimal
    expected errors {"number1": "NOT_POSITIVE_DECIMAL", "number2": "NOT_POSITIVE_DECIMAL", "number3": "NOT_POSITIVE_DECIMAL", "number4": "NOT_POSITIVE_DECIMAL", "value_is_array": "FORMAT_ERROR", "value_is_empty_array": "FORMAT_ERROR", "value_is_empty_hash": "FORMAT_ERROR", "value_is_…
  • negative/16-email
    expected errors {"email1": "WRONG_EMAIL", "email10": "WRONG_EMAIL", "email11": "WRONG_EMAIL", "email12": "WRONG_EMAIL", "email13": "WRONG_EMAIL", "email14": "WRONG_EMAIL", "email15": "WRONG_EMAIL", "email16": "WRONG_EMAIL", "email17": "WRONG_EMAIL", "email18": "WRONG_EMAIL", "ema…
  • negative/17-equal_to_field
    exception: KeyError: 'missing_field'
  • negative/19-list_of
    expected errors {"product_ids1": ["NOT_POSITIVE_INTEGER", "REQUIRED", null, "TOO_HIGH"], "product_ids2": ["NOT_POSITIVE_INTEGER", "REQUIRED", null, "TOO_HIGH"], "product_ids3": ["NOT_POSITIVE_INTEGER", null, null, null], "user_ids": "FORMAT_ERROR"}, got {"product_ids1": ["NOT_POS…
  • negative/21-list_of_different_objects
    exception: TypeError: argument of type 'int' is not iterable
  • negative/23-url
    expected errors {"url1": "WRONG_URL", "url2": "WRONG_URL", "url3": "WRONG_URL", "url4": "WRONG_URL", "url5": "WRONG_URL", "value_is_array": "FORMAT_ERROR", "value_is_empty_array": "FORMAT_ERROR", "value_is_empty_hash": "FORMAT_ERROR", "value_is_hash": "FORMAT_ERROR"}, got {"url1"…
  • negative/24-iso_date
    expected errors {"iso_date1": "WRONG_DATE", "iso_date2": "WRONG_DATE", "iso_date3": "WRONG_DATE", "iso_date4": "WRONG_DATE", "iso_date5": "WRONG_DATE", "iso_date6": "WRONG_DATE", "iso_date7": "WRONG_DATE", "iso_date8": "WRONG_DATE", "iso_date9": "WRONG_DATE", "like_iso_date": "WR…
  • negative/28-variable_object
    exception: KeyError: 'product_type'
  • negative/29-or
    expected errors {"id1-1": "NOT_POSITIVE_INTEGER", "id2-1": "NOT_POSITIVE_INTEGER", "id3-1": "WRONG_EMAIL", "id4-1": "CANNOT_BE_EMPTY", "id4-2": "REQUIRED", "products": [{"name": "REQUIRED", "product_type": "NOT_ALLOWED_VALUE"}, {"name": "REQUIRED"}]}, got {"id1-1": "NOT_POSITIVE_…
  • aliases_positive/01-adult_age
    expected output {"age1": 32, "age1_custom_error": 37, "age2": 33, "age2_custom_error": 38, "age3": 35, "age3_custom_error": 100, "age4": 36, "age4_custom_error": 110, "empty_age": ""}, got {"age1": 32, "age1_custom_error": 37, "age2": 33, "age2_custom_error": 38, "age3": 35, "age…

Results of running the LIVR test suite (70 cases) against the latest version of each implementation: the published package, or the default branch when it is not published. Checked on October 29, 2026. The runners live in the conformance/ directory. Some failures come from newer test cases that were added after an implementation's last release. Cases that an implementation can't pass because of its language (for example, PHP and Lua decode {} and [] to the same value) are not counted, so its score is out of the remaining cases.

Add your implementation ​

Wrote a LIVR implementation? Great!

  1. Check that it passes the test suite, see Create own implementation.
  2. Add it to docs/data/implementations.json and, if you can, add a test suite runner to conformance/.
  3. Run npm run readme to update the list in the repository README and open a pull request.