jdb-lite
v1.0.1
Published
A lightweight schema-based JSON database library with validation
Maintainers
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 collectionEach 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 hereTypeScript
// 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
- Use indexes for frequently queried fields (planned feature)
- Limit results with
.limit()to avoid loading large datasets - Use
.countDocuments()instead of.find().lengthfor counting - 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.
