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

ormyx

v0.1.0

Published

A ORM-Based program for making JSON a relational-like database

Readme

Ormyx (JSON-based Relational Database)

MPOP Reverse II [Ryann Kim M. Sesgundo]

wakatime npm version

Ormyx is a TypeScript-based ORM-like library designed to manage JSON data as a relational-like database with built-in encryption. It simplifies data persistence by providing a structured way to handle tables, rows, and automatic ID generation while keeping your data secure.

Note

I don't recommend using this for large-scale projects; it's best suited for small projects, prototypes, or hobbies. This was created for fun and as a way to expand my ideas and knowledge.

Table of Contents

Features

  • Relational Structure: Organize your JSON data into tables and records.
  • Built-in Encryption: Uses json-enc-dec to keep your database files secure.
  • Data Filtering & Type Safety: Automatically sanitizes input and enforces column types to prevent unwanted data injection.
  • Auto ID Generation: Support for both random 12-character strings and incremental numeric IDs.
  • Flexible Data Insertion: Support for both JSON objects and easy-to-use string formats.
  • TypeScript Support: Fully typed for an enhanced developer experience.

Installation

npm install ormyx

How To

1. Initialization

ormyx(key: string, filename?: string)

To get started, you need to initialize Ormyx with a secret encryption key. If the database file does not exist, it will be created automatically.

Option A: Providing a Custom Filename You can specify a name for your database. Filenames are automatically sanitized (only the base name is kept) and the .dat extension is added if missing.

import { ormyx } from 'ormyx';

// This creates/loads 'my-database.dat'
const db = ormyx('your-secret-key', 'my-database');

// 'my.db.json' will be sanitized to 'my.dat'
const db2 = ormyx('your-secret-key', 'my.db.json');

Option B: Using the Default Filename (Optional) If you omit the second parameter, the database will default to data.dat.

import { ormyx } from 'ormyx';

// This creates/loads 'data.dat'
const db = ormyx('your-secret-key');

Warning: The encryption key is the only way to access your data. If you lose the key or use a different one later, you will not be able to read the existing database. Always store your keys in environment variables!

2. Creating Tables (Required)

db.create(tableName: string, columns: object | string, autoincrement?: boolean)

You must create a table before you can insert any data. This defines the structure, column types, and ID generation strategy.

Option A: Using an Object (Recommended) Define columns and their types using a JSON object.

// Example: db.create('users', { username: 'string', email: 'string', active: 'boolean' })
db.create('users', {
    username: 'string',
    email: 'string',
    role: 'string',
    active: 'boolean'
});

Option B: Using a String Format A convenient shorthand for defining columns and types.

// Example: db.create('users', "username = string, email = string, age = int")
db.create('users', "username = string, email = string, role = string, active = boolean");

Column Type Rules:

  • Supported Types: string, (number or int), boolean.
  • ID Column: By default, an id column is added as a number or int (incremental). To use a random string ID, define id: 'string'.
  • Autoincrement: The third parameter (default: true) controls if numeric IDs should automatically increment.

3. Inserting Data

db.insert(tableName: string, data: object | string, options?: insertOptions)

You can insert data into your tables by providing either a JSON object or a formatted string.

Using JSON Object (Recommended)

This method is recommended for structured data and better type safety.

// Example: db.insert('users', { username: 'ryannkim', active: true })
try {
    const result = db.insert('users', {
        username: 'ryannkim',
        role: 'developer',
        active: true
    });
    console.log('Inserted record:', result);
} catch (error) {
    console.error('Failed to insert:', error.message);
}

Using String Format

A convenient shorthand for simple data entry.

// Example: db.insert('users', "username = mpop, role = admin")
db.insert('users', "username = mpop, role = admin, active = true");

String Format Rules:

  • Pairs: Use key = value format.
  • Types: Numbers and booleans (true/false) are automatically parsed.
  • Quotes: Wrap values in ' or " if they contain commas or special characters.
  • Separators: Separate fields with a comma (,).

ID Generation Strategies

Control how IDs are generated via the options parameter or table structure.

// Incremental ID: 1, 2, 3... (Default if 'id' type is 'number')
db.insert('logs', { event: 'startup' });

// Random 12-character alphanumeric ID (Default if 'id' type is 'string')
db.insert('sessions', { token: 'xyz123' });

// Custom ID length for string-based IDs
db.insert('tokens', { value: 'abc' }, { idLength: 16 });

4. Reading Data

db.read(tableName: string, id: string | number)

Retrieve a specific record by its ID.

// Example: db.read('users', 1)
const user = db.read('users', 1);

if (user) {
    console.log('User data:', user);
} else {
    console.error('Record not found');
}

5. Filtering Data

db.filter(tableName: string, options: filterOptions)

Search for data within a table that matches specific criteria using a where clause.

// Example: Basic filtering
const results = db.filter('users', { 
    where: "age > 20 AND active = true" 
});

// Using logical aliases (&, |, &&, ||)
const admins = db.filter('users', { 
    where: "role = admin & active = true" 
});

// Pagination support
const pagedResults = db.filter('users', {
    where: "active = true",
    start: 0,
    limit: 10
});

Supported Operators:

  • Comparison: =, !=, >, <, >=, <=, in
  • Logical: AND, OR, &&, ||, &, |

Rules:

  • Logical Operators: & and && act as AND. | and || act as OR.
  • Case Sensitivity: Operator aliases like AND/OR are case-insensitive.
  • Values: Strings with spaces should be wrapped in quotes (e.g., name = 'John Doe').

6. Updating Data

db.update(tableName: string, id: string | number, data: object | string)

Modify an existing record. New data is merged with the existing record.

// Example: db.update('users', 1, { active: false })
db.update('users', 1, { active: false });

// Using string format
db.update('users', 1, "role = administrator, active = true");

7. Deleting Data

db.remove(tableName: string, id: string | number)

Remove a specific record from a table.

// Example: db.remove('users', 1)
const status = db.remove('users', 1);
console.log(status.message); // "Deleted successfully"

8. Altering Tables

db.alter(tableName: string, newColumns?: object | string, deleteColumns?: string[])

Modify the structure of an existing table. You can add new columns with types or remove existing ones.

// Add new columns to the 'users' table
db.alter('users', { age: 'number', gender: 'string' });

// Using string format
db.alter('users', "address = string");

// Remove columns from the 'users' table
db.alter('users', undefined, ['role']);

9. Renaming Tables

db.rename(oldTableName: string, newTableName: string)

Rename an existing table. This will preserve both the table structure and its data.

// Example: db.rename('users', 'members')
const result = db.rename('users', 'members');
console.log(result.message); // "Table users is now renamed to members"

Data Structure

The internal structure of the database follows a hierarchical JSON format:

{
  "table_struct": {
    "users": {
        "username": "string",
        "email": "string",
        "role": "string",
        "active": "boolean",
        "id": "number"
    }
  },
  "users": {
    "1": {
      "username": "ryannkim",
      "email": "[email protected]",
      "role": "developer",
      "active": true,
      "id": 1
    }
  }
}

TypeScript Interfaces

type data_structure = Record<string, string | number | boolean | undefined | null>
type json_data = Record<string | number, data_structure>
type main_structure = Record<string, json_data>

interface insertOptions {
    increment?: boolean
    idLength?: number
}

How it Works

  1. Initialization: ormyx() checks for the database file. If missing, it initializes a new encrypted file.
  2. Operations: Every write operation (insert, update, remove) synchronizes with the encrypted file, performs the operation in-memory, and then flushes the re-encrypted data back to disk.
  3. Encryption: Powered by json-enc-dec, ensuring data at rest is secure.

Contributing

Contributions are welcome! To maintain a clean and manageable history, please use Semantic Commit Messages:

  • feat: for new features

  • fix: for bug fixes

  • rebrand: for rebranding changes

  • docs: or doc: for documentation changes

  • style: for formatting, missing semi colons, etc.

  • refactor: for refactoring production code

  • test: for adding missing tests

  • chore: for updating build tasks, package manager configs, etc.

Example: feat: add support for custom primary keys

Security Best Practices

  • Environment Variables: Never hardcode your encryption key. Use .env files or secrets managers.
  • Key Consistency: Using a different key on an existing database will result in decryption failure and potential data corruption if forced.
  • Backups: Regularly backup your .dat files. Encryption protects data privacy, not data loss.

License

This project is licensed under the MIT License.


View Changelog