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

jdb-lite

v1.0.1

Published

A lightweight schema-based JSON database library with validation

Readme

jdb-lite

A lightweight, zero-dependency JSON database for Node.js with a familiar API. Perfect for small projects, prototyping, or when you need a simple file-based database without the complexity of traditional databases.

✨ Features

  • 🔄 Familiar API - Mongoose-like interface that feels natural
  • 📁 JSON File Storage - Data stored in simple JSON files
  • 🔧 Schema Validation - Define and validate your data structure
  • 📦 Multi-format Support - Works with CommonJS, ES Modules, TypeScript, and JavaScript
  • 🔍 Full CRUD Operations - Create, Read, Update, Delete with filtering and sorting
  • 🎯 TypeScript Support - Full type safety and IntelliSense
  • Zero Dependencies - Lightweight with no external dependencies
  • 🚀 Easy Setup - Get started in minutes

📦 Installation

npm install jdb-lite

🚀 Quick Start

JavaScript (CommonJS)

const JsonDB = require('jdb-lite');
const { Schema } = require('jdb-lite');

// Define a schema
const userSchema = new Schema({
  name: { type: 'String', required: true },
  email: { type: 'String', required: true },
  age: { type: 'Number', required: true },
  isActive: { type: 'Boolean', default: true }
});

// Connect and create model
async function main() {
  await JsonDB.connect('./my-database');
  const User = JsonDB.model('User', userSchema);

  // Create a user
  const user = new User({
    name: 'John Doe',
    email: '[email protected]',
    age: 30
  });

  await user.save();
  console.log('User saved!', user);
}

main();

JavaScript (ES Modules)

import JsonDB, { Schema } from 'jdb-lite';

const userSchema = new Schema({
  name: { type: 'String', required: true },
  email: { type: 'String', required: true },
  age: { type: 'Number', required: true }
});

await JsonDB.connect('./my-database');
const User = JsonDB.model('User', userSchema);

const user = await User.create({
  name: 'Jane Doe',
  email: '[email protected]',
  age: 25
});

console.log('User created!', user);

TypeScript

import JsonDB, { Schema, Document } from 'jdb-lite';

// Define interface
interface IUser extends Document {
  name: string;
  email: string;
  age: number;
  isActive?: boolean;
}

// Create schema with type safety
const userSchema = new Schema<IUser>({
  name: { type: 'String', required: true },
  email: { type: 'String', required: true },
  age: { type: 'Number', required: true },
  isActive: { type: 'Boolean', default: true }
});

await JsonDB.connect('./my-database');
const User = JsonDB.model<IUser>('User', userSchema);

// Type-safe operations
const user: IUser = await User.create({
  name: 'Alice Smith',
  email: '[email protected]',
  age: 28
});

📖 Complete Usage Guide

1. Connection

// Connect to database (creates folder if doesn't exist)
await JsonDB.connect('./my-database');

// Or specify a different path
await JsonDB.connect('/path/to/database');

// Disconnect when done
await JsonDB.disconnect();

2. Schema Definition

const userSchema = new Schema({
  // String field
  name: { 
    type: 'String', 
    required: true,
    default: 'Anonymous'
  },
  
  // Number field
  age: { 
    type: 'Number', 
    required: true,
    validate: (value) => value >= 0 // Custom validation
  },
  
  // Boolean field
  isActive: { 
    type: 'Boolean', 
    default: true 
  },
  
  // Date field
  createdAt: { 
    type: 'Date', 
    default: Date.now 
  },
  
  // Array field
  tags: { 
    type: 'Array', 
    default: [] 
  },
  
  // Object field
  settings: { 
    type: 'Object', 
    default: {} 
  }
}, {
  timestamps: true, // Adds createdAt and updatedAt automatically
  collection: 'users' // Custom collection name (optional)
});

3. Creating Documents

// Method 1: Constructor + save
const user = new User({
  name: 'John Doe',
  email: '[email protected]',
  age: 30
});
await user.save();

// Method 2: Direct creation
const user = await User.create({
  name: 'Jane Doe',
  email: '[email protected]',
  age: 25
});

// Method 3: Create multiple
const users = await User.insertMany([
  { name: 'User 1', email: '[email protected]', age: 20 },
  { name: 'User 2', email: '[email protected]', age: 30 }
]);

4. Reading Documents

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

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

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

// Find by ID
const user = await User.findById('507f1f77bcf86cd799439011');

// Advanced querying
const users = await User.find({ age: { $gte: 25 } })
  .sort({ age: -1 })        // Sort by age descending
  .limit(10)                // Limit to 10 results
  .skip(5);                 // Skip first 5 results

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

5. Updating Documents

// Update one document
await User.updateOne(
  { email: '[email protected]' }, // Filter
  { age: 31 }                    // Update
);

// Update multiple documents
await User.updateMany(
  { isActive: false },  // Filter
  { isActive: true }    // Update
);

// Find and update (returns updated document)
const updatedUser = await User.findOneAndUpdate(
  { email: '[email protected]' },
  { age: 32 },
  { new: true } // Return updated document
);

// Find by ID and update
const user = await User.findByIdAndUpdate(
  '507f1f77bcf86cd799439011',
  { name: 'John Smith' },
  { new: true }
);

6. Deleting Documents

// Delete one document
await User.deleteOne({ email: '[email protected]' });

// Delete multiple documents
await User.deleteMany({ isActive: false });

// Find and delete (returns deleted document)
const deletedUser = await User.findOneAndDelete({ email: '[email protected]' });

// Find by ID and delete
const user = await User.findByIdAndDelete('507f1f77bcf86cd799439011');

7. Instance Methods

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

// Check if document is new (not saved yet)
console.log(user.isNew); // false

// Check if field was modified
user.age = 32;
console.log(user.isModified('age')); // true

// Convert to plain object
const plainObject = user.toObject();

// Convert to JSON
const jsonString = JSON.stringify(user.toJSON());

// Validate document
await user.validate();

// Save changes
await user.save();

// Remove document
await user.remove();

🏗️ Data Storage

Your data is stored in JSON files within the specified database folder:

my-database/
├── users.json      # User collection
├── posts.json      # Post collection
└── comments.json   # Comment collection

Each collection is a JSON array of documents:

[
  {
    "_id": "507f1f77bcf86cd799439011",
    "name": "John Doe",
    "email": "[email protected]",
    "age": 30,
    "isActive": true,
    "createdAt": "2023-01-01T00:00:00.000Z",
    "updatedAt": "2023-01-01T00:00:00.000Z"
  }
]

🔧 Advanced Features

Custom Methods and Statics

// Add instance methods
userSchema.methods.getDisplayName = function() {
  return this.name.toUpperCase();
};

// Add static methods
userSchema.statics.findByEmail = function(email) {
  return this.findOne({ email });
};

// Usage
const user = await User.findOne({ name: 'John' });
console.log(user.getDisplayName()); // "JOHN"

const user = await User.findByEmail('[email protected]');

Schema Validation

const userSchema = new Schema({
  email: {
    type: 'String',
    required: true,
    validate: (email) => {
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        throw new Error('Invalid email format');
      }
      return true;
    }
  },
  age: {
    type: 'Number',
    required: true,
    validate: (age) => {
      if (age < 0 || age > 150) {
        throw new Error('Age must be between 0 and 150');
      }
      return true;
    }
  }
});

📱 Module System Examples

Node.js (CommonJS)

// index.js
const JsonDB = require('jdb-lite');

async function main() {
  await JsonDB.connect('./database');
  // Your code here
}

Node.js (ES Modules)

// index.mjs or with "type": "module" in package.json
import JsonDB from 'jdb-lite';

await JsonDB.connect('./database');
// Your code here

TypeScript

// index.ts
import JsonDB, { Schema, Document } from 'jdb-lite';

interface User extends Document {
  name: string;
  email: string;
}

const userSchema = new Schema<User>({
  name: { type: 'String', required: true },
  email: { type: 'String', required: true }
});

await JsonDB.connect('./database');
const UserModel = JsonDB.model<User>('User', userSchema);

🔍 Query Examples

// Basic queries
const users = await User.find({ age: 25 });
const user = await User.findOne({ email: '[email protected]' });

// Comparison operators
const adults = await User.find({ age: { $gte: 18 } });
const seniors = await User.find({ age: { $gt: 65 } });
const young = await User.find({ age: { $lt: 30 } });

// Sorting and limiting
const newest = await User.find().sort({ createdAt: -1 }).limit(5);
const oldest = await User.find().sort({ createdAt: 1 }).limit(5);

// Pagination
const page2 = await User.find().skip(10).limit(10);

// Counting
const totalUsers = await User.countDocuments();
const activeUsers = await User.countDocuments({ isActive: true });

🛠️ Error Handling

try {
  const user = new User({
    name: 'John',
    // Missing required email field
    age: 30
  });
  
  await user.save();
} catch (error) {
  console.error('Validation error:', error.message);
  // "Field 'email' is required"
}

🚀 Performance Tips

  1. Use indexes for frequently queried fields (planned feature)
  2. Limit results with .limit() to avoid loading large datasets
  3. Use .countDocuments() instead of .find().length for counting
  4. Close connections with JsonDB.disconnect() when done

📚 Migration from Other Libraries

From Mongoose

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

// jdb-lite
const JsonDB = require('jdb-lite');
const User = JsonDB.model('User', userSchema);

From Lowdb

// Lowdb
const low = require('lowdb');
const db = low('db.json');

// jdb-lite
const JsonDB = require('jdb-lite');
await JsonDB.connect('./database');

🤝 Contributing

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

📄 License

MIT License - see LICENSE file for details.


Made with ❤️ for developers who need a simple, reliable JSON database solution.