npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

riv

v1.0.4

Published

RIV (Readable Interoperable Values) – A human-readable data serialization format with advanced type support.

Readme

Riv-JS

Riv (Awesome Lightweight Object Notation) is a human-readable data serialization format that extends beyond JSON's limitations, supporting advanced JavaScript types while maintaining simplicity and readability.

🚀 Features

  • Human-readable format with clean syntax
  • Advanced type support: Date, RegExp, Set, Map, BigInt, Symbol, Error, ArrayBuffer
  • Circular reference detection
  • Configurable serialization
  • Utility functions for deep cloning, merging, and validation
  • Zero dependencies
  • Lightweight (~8KB minified)

📦 Installation

npm install riv

🔧 Usage

Basic Example

const Riv = require('riv');

const data = {
  name: "John Doe",
  age: 30,
  active: true,
  tags: ["developer", "javascript"],
  profile: {
    theme: "dark",
    lang: "en"
  }
};

// Serialize to Riv format
const serialized = Riv.serialize(data, 'user');
console.log(serialized);
/*
@user
  :name => "John Doe"
  :age => 30
  :active => #yes
  :tags => <"developer" "javascript">
  :profile =>
    @
      :theme => "dark"
      :lang => "en"
*/

// Deserialize back to JavaScript object
const deserialized = Riv.deserialize(serialized);
console.log(deserialized);

Advanced Types

const complexData = {
  date: new Date('2024-01-01'),
  regex: /test\d+/gi,
  bigNumber: 9007199254740991n,
  set: new Set([1, 2, 3]),
  map: new Map([['key1', 'value1'], ['key2', 42]]),
  buffer: new ArrayBuffer(4),
  error: new Error('Something went wrong'),
  symbol: Symbol('unique'),
  special: {
    nan: NaN,
    infinity: Infinity,
    negInfinity: -Infinity,
    nil: null
  }
};

const serialized = Riv.serialize(complexData);
const restored = Riv.deserialize(serialized);

// All types are perfectly preserved!
console.log(restored.date instanceof Date); // true
console.log(restored.regex instanceof RegExp); // true
console.log(typeof restored.bigNumber === 'bigint'); // true

📚 API Reference

Core Functions

Riv.serialize(value, name?, indent?)

Converts a JavaScript value to Riv format string.

  • value: Any JavaScript value
  • name: Optional object name
  • indent: Starting indentation level
  • Returns: Riv format string

Riv.deserialize(str)

Parses an Riv format string back to JavaScript value.

  • str: Riv format string
  • Returns: JavaScript value

Utility Functions

Riv.pretty(value, name?)

Alias for serialize() with pretty formatting.

Riv.minify(value, name?)

Serializes to compact single-line format.

Riv.clone(value)

Deep clones any JavaScript value.

const original = { nested: { data: [1, 2, 3] } };
const cloned = Riv.clone(original);
// Completely independent copy

Riv.equal(a, b)

Deep equality comparison.

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
console.log(Riv.equal(obj1, obj2)); // true

Riv.merge(target, source)

Deep merge objects.

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 3 }, e: 4 };
const merged = Riv.merge(obj1, obj2);
// Result: { a: 1, b: { c: 2, d: 3 }, e: 4 }

Riv.validate(schema, data)

Simple schema validation.

const schema = {
  name: 'string',
  age: 'number',
  tags: ['string']
};

const validData = {
  name: 'John',
  age: 30,
  tags: ['dev', 'js']
};

console.log(Riv.validate(schema, validData)); // true

⚙️ Configuration

// Access configuration
const config = Riv.config;

// Modify settings
config.indent = 4;           // Indentation size (default: 2)
config.maxDepth = 50;        // Max nesting depth (default: 100)
config.dateFormat = 'timestamp'; // 'iso' or 'timestamp' (default: 'iso')

🎯 Riv Format Syntax

Primitives

#nil          // null/undefined
#yes          // true
#no           // false
"text"        // strings
42            // numbers
#nan          // NaN
#inf          // Infinity
#-inf         // -Infinity

Collections

<item1 item2>           // arrays
@                       // objects
  :key => value
@name                   // named objects
  :prop => "value"

Special Types

#date:"2024-01-01T00:00:00.000Z"    // Date
#regex:"/pattern/flags"              // RegExp
#big:123456789                       // BigInt
#symbol:"description"                // Symbol
#error:"message"                     // Error
#set:<1 2 3>                        // Set
#map:<<key1 value1> <key2 value2>>  // Map
#buffer:"1,2,3,4"                   // ArrayBuffer

🔄 JSON Compatibility

Riv can parse basic JSON syntax for easy migration:

const jsonString = '{"name": "John", "active": true}';
const parsed = Riv.deserialize(jsonString); // Works!

🚀 Performance

Riv is optimized for both speed and memory efficiency:

  • Streaming parser for large datasets
  • Circular reference detection with WeakSet
  • Minimal memory allocation during parsing
  • Fast serialization with optimized string building

🛡️ Error Handling

Riv provides detailed error messages with context:

try {
  Riv.deserialize('invalid { syntax }');
} catch (error) {
  console.log(error.message);
  // "Invalid token '{' at position 8 | Context: "invalid { syn""
}

📄 License

MIT License - see LICENSE file for details.

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📊 Comparison with JSON

| Feature | JSON | Riv | |---------|------|------| | Dates | ❌ String only | ✅ Native Date | | RegExp | ❌ No support | ✅ Full support | | BigInt | ❌ No support | ✅ Native BigInt | | Set/Map | ❌ No support | ✅ Native support | | Comments | ❌ No support | ✅ Planned | | Circular refs | ❌ Throws error | ✅ Detection | | Human readable | ⚠️ Limited | ✅ Excellent | | Size | ✅ Compact | ⚠️ Slightly larger |


Made with ❤️ for the JavaScript community