Nullifying Precipitation Machine


npm’s 2019 JavaScript ecosystem survey analysis is now available!Get your copy here »


1.2.4 • Public • Published


Master Next
Tests CI - Master CI - Next
Coverage codecov codecov
Dependency Analysis Master - Known Vulnerabilities Next -  Known Vulnerabilities

Recordari is a type and structure validation tool for configuration files.

const { Record, R } = require('Recordari');
// 1) Create a Record of how the configurations should look
const RConfig = Record('MyConfig', {
  port: R.Number.Natural,
  env: R.String.Either(['dev', 'prod']),
  loglevel: R.String.Either(['none', 'error', 'warn', 'info', 'debug'])
// 2) Test the actual configurations against the Record
const config = RConfig(require('config.json')); // Will throw if any of the constraints fail
// 3) You can use all of the properties on config without worrying about some of them not being valid.
config.loglevel // Will ALWAYS be valid
config.port     // Will ALWAYS be valid
config.env      // Will ALWAYS be valid


Latest: npm install recordari
Next: npm install recordari@next

Using Recordari

Using Recordari is divided into two steps, the record constructions, and the record evaluation.
In the construction you will be creating a sort of "template" for Recordari to use in the evaluation step. This "template" is what we call a record and will be denoted by the capital R preceding the variable name. Ex: ROptions or RConfig.


When constructing a record you will be using the Record function provided by Recordari.
This function takes two arguments, the first is the name of the record (this can be anything you like), and the second is the constraint object (this is the important part).

const { Record } = require('Recordari');
const RDemo = Record('Demo', {
  // This is the constraint object

In essence "the constraint object should be a modified copy of the object that you are creating a record for", let me explain.
Lets say you want to create a record for this object: { a: 42 }
And lets assume that the application expects the property a to always be a number.
We could then construct a constraint for the property a that asserts the type of the value to be a number, like this: R.Number

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number

R.Number is a constraint that tells Recordari that when it evaluates an object against the Demo record, the property a should be a number.

You can read about all the available constraints here!


After you've constructed a record you can now use it to assert the validity of objects.

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number
const demo = RDemo({ a: 42 });
console.log(demo.a); // 42

As you can see above, the Record function returns a function. This function expects a single argument, and it expects this argument to be an object that complies to the constraints of the record that you previously constructed.
If the argument does comply to the constraints, then function will act like the identity function (aka it will return the object that was passed in).
If the argument does not comply to the constraints then the function will throw a TypeError.

const { R, Record } = require('Recordari');
const RDemo = Record('Demo', {
  a: R.Number
const demo = RDemo({ a: 'hi' }); // Will throw TypeError
console.log(demo.a); // Won't be executed


See docs/

A great way to explore the available constraints is through intellisense exploration. Either by using typescript or by using a typescript enabled editor with javascript (such as vscode).




See docs/

Typescript interop

Most of Recordari is already typed out of the box.
However unfortunately typescript types needs to exists prior to compilation so we can't dynamically type an object as it goes through a Recordari record. This means that you will have to trust in Recordari to do all necessary type checks, and then override typescript by explicitly casting the resulting record to the corresponding typescript type.

  const RDemo = Record('Demo', {
    foo: R.Number.Natural,
    bar: R.String.Either(['a', 'b']),
  interface IDemo {
    foo: number;
    bar: 'a' | 'b';
  const demo = RDemo({
    foo: 1,
    bar: 'a',
  }) as IDemo;



npm i recordari

Downloadsweekly downloads









last publish


  • avatar
Report a vulnerability