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 🙏

© 2025 – Pkg Stats / Ryan Hefner

synz-db

v1.2.0

Published

A lightweight JSON-based database with Mongoose-like schema and model API

Readme

Synz-DB

A lightweight, file-based JSON database with a Mongoose-like schema and model API for Node.js applications.

Features

  • 🚀 Mongoose-like API - Familiar schema and model syntax
  • 📁 File-based storage - No external database required
  • Schema validation - Type checking, required fields, custom validators
  • 🔄 Data transformation - Automatic trimming, case conversion, type coercion
  • 🏃 Performance - Built-in caching and indexing
  • 🔒 Concurrency safe - File locking prevents data corruption
  • 📝 TypeScript ready - Full TypeScript support (coming soon)

Installation

npm install synz-db

Quick Start

const { Schema, model } = require('synz-db');

// Define a schema
const userSchema = new Schema({
  name: {
    type: String,
    required: true,
    trim: true
  },
  email: {
    type: String,
    required: true,
    unique: true,
    lowercase: true
  },
  age: {
    type: Number,
    min: 0
  }
}, {
  timestamps: true // Adds createdAt and updatedAt
});

// Create a model
const User = model('User', userSchema);

// Use the model
async function example() {
  // Create a user
  const user = await User.create({
    name: '  John Doe  ', // Will be trimmed
    email: '[email protected]', // Will be lowercased
    age: 25
  });

  // Find users
  const users = await User.find({ age: { $gte: 18 } });
  
  // Update user
  user.age = 26;
  await user.save();
}

API Reference

Schema

Create a new schema to define the structure and validation rules for your data.

const { Schema } = require('synz-db');

const schema = new Schema({
  fieldName: {
    type: String,        // String, Number, Boolean, Date, Array, Object
    required: true,      // Field is required
    default: 'value',    // Default value (can be a function)
    trim: true,          // Trim whitespace (String only)
    lowercase: true,     // Convert to lowercase (String only)
    uppercase: true,     // Convert to uppercase (String only)
    minlength: 5,        // Minimum length (String/Array)
    maxlength: 100,      // Maximum length (String/Array)
    min: 0,              // Minimum value (Number)
    max: 100,            // Maximum value (Number)
    enum: ['a', 'b'],    // Allowed values
    match: /pattern/,    // Regex pattern (String only)
    validate: function(value) {
      // Custom validator
      return value !== 'invalid';
    }
  }
}, {
  timestamps: true       // Automatically add createdAt/updatedAt
});

Schema Methods

  • virtual(name, getter) - Add virtual properties
  • pre(method, fn) - Add pre-middleware
  • post(method, fn) - Add post-middleware
// Virtual property
schema.virtual('fullName', function() {
  return `${this.firstName} ${this.lastName}`;
});

// Pre-save middleware
schema.pre('save', function() {
  this.slug = this.title.toLowerCase().replace(/\s+/g, '-');
});

// Post-save middleware
schema.post('save', function() {
  console.log('Document saved:', this.id);
});

Model

Models are created from schemas and provide the interface for interacting with your data.

const User = model('User', userSchema);

Static Methods

  • create(data) - Create and save a new document
  • find(query) - Find documents matching the query
  • findOne(query) - Find one document matching the query
  • findById(id) - Find document by ID
  • findByIdAndUpdate(id, update) - Find by ID and update
  • findByIdAndDelete(id) - Find by ID and delete
  • updateMany(query, update) - Update multiple documents
  • deleteMany(query) - Delete multiple documents
  • countDocuments(query) - Count matching documents
  • exists(query) - Check if documents exist
  • insertMany(docs) - Insert multiple documents
  • createIndex(field) - Create an index for faster queries

Instance Methods

  • save() - Save the document
  • remove() - Remove the document
  • toObject() - Convert to plain object
  • toJSON() - Convert to JSON

Database Connection

const { connect } = require('synz-db');

// Connect to a specific directory (default: './data')
connect('./my-database');

Query Examples

// Find all users
const users = await User.find();

// Find with conditions
const adults = await User.find({ age: { $gte: 18 } });

// Find one user
const user = await User.findOne({ email: '[email protected]' });

// Find by ID
const user = await User.findById('user-id-123');

// Update user
const user = await User.findById('user-id-123');
user.age = 26;
await user.save();

// Or update directly
await User.findByIdAndUpdate('user-id-123', { age: 26 });

// Delete user
await User.findByIdAndDelete('user-id-123');

// Count documents
const count = await User.countDocuments({ isActive: true });

// Check existence
const exists = await User.exists({ email: '[email protected]' });

Validation

Synz-DB provides comprehensive validation similar to Mongoose:

const userSchema = new Schema({
  email: {
    type: String,
    required: true,
    match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
    validate: {
      validator: function(email) {
        return !email.includes('spam');
      },
      message: 'Email cannot contain spam'
    }
  },
  age: {
    type: Number,
    min: [0, 'Age cannot be negative'],
    max: [120, 'Age seems unrealistic']
  },
  role: {
    type: String,
    enum: {
      values: ['user', 'admin', 'moderator'],
      message: '{VALUE} is not a valid role'
    }
  }
});

Performance

Indexing

Create indexes on frequently queried fields for better performance:

// Create an index
await User.createIndex('email');

// The index will speed up queries like:
const user = await User.findOne({ email: '[email protected]' });

Caching

Synz-DB automatically caches collections in memory with a default timeout of 30 seconds. You can clear the cache manually:

const { JsonDB } = require('synz-db');
const db = new JsonDB();

// Clear cache for specific collection
db.clearCache('users');

// Clear all cache
db.clearCache();

// Get cache statistics
const stats = db.getCacheStats();
console.log(stats); // { size: 2, collections: ['users', 'posts'], memory: 1024 }

File Structure

By default, Synz-DB stores data in JSON files:

./data/
├── users.json
├── posts.json
└── comments.json

Each collection is stored as a separate JSON file with automatic atomic writes to prevent corruption.

Error Handling

try {
  await User.create({ name: 'John' }); // Missing required email
} catch (error) {
  console.error('Validation failed:', error.message);
  // "Validation failed: Field 'email' is required"
}

TypeScript Support

Full TypeScript definitions are coming soon! For now, you can use basic typing:

interface IUser {
  name: string;
  email: string;
  age?: number;
}

const User = model<IUser>('User', userSchema);

Migration from Mongoose

Synz-DB uses a similar API to Mongoose, making migration straightforward:

// Before (Mongoose)
const mongoose = require('mongoose');
const User = mongoose.model('User', userSchema);

// After (Synz-DB)
const { model } = require('synz-db');
const User = model('User', userSchema);

// Most operations remain the same!

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see the LICENSE file for details.

Changelog

v1.0.0

  • Initial release
  • Mongoose-like schema and model API
  • File-based JSON storage
  • Validation and transformation
  • Caching and indexing
  • Concurrency safety