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

@flickerstop/jrmongo

v2.0.0

Published

A lightweight MongoDB wrapper for Node.js with simplified operations and connection management

Readme

JrMongo

A lightweight MongoDB wrapper for Node.js that simplifies database operations with an intuitive API and automatic connection management.

Features

  • Simple API — Easy-to-use methods for all common MongoDB operations
  • Auto Connection — Connects on first use, reuses connections automatically
  • Silent by Default — No console output unless you enable verbose mode
  • Environment Variables — Built-in .env support via dotenv
  • Connection Options — Pass-through options to MongoClient (pool size, TLS, timeouts)
  • TypeScript Ready — Includes comprehensive type definitions
  • Dual Format — Works with both ESM (import) and CommonJS (require)
  • ObjectId Export — Re-exports MongoDB's ObjectId for convenience

Installation

npm install @flickerstop/jrmongo

Quick Start

  1. Create a .env file in your project root:
MONGODB_URL=mongodb://localhost:27017
  1. Use JrMongo in your application:
import { JrMongo } from '@flickerstop/jrmongo';

const db = JrMongo.db('myapp');

// Insert
await db.add('users', { name: 'Alice', email: '[email protected]' });

// Find
const users = await db.find('users', { name: 'Alice' });

// Update
await db.update('users', { name: 'Alice' }, { email: '[email protected]' });

// Delete
await db.deleteOne('users', { name: 'Alice' });

// Close when done
await db.close();

API Reference

JrMongo.db(dbName, dbURL?, options?)

Creates a new database connection instance.

| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | dbName | string | — | Name of the database | | dbURL | string | process.env.MONGODB_URL | MongoDB connection URL | | options | object | {} | Options passed through to MongoClient |

// Basic
const db = JrMongo.db('myapp');

// With custom URL
const db = JrMongo.db('myapp', 'mongodb://localhost:27017');

// With connection options
const db = JrMongo.db('myapp', 'mongodb://localhost:27017', {
  maxPoolSize: 20,
  connectTimeoutMS: 5000
});

JrMongo.configure(options)

Configures global settings.

JrMongo.configure({ verbose: true }); // Enable connection logging

JrMongo.isReady(dbName?)

Check if a database connection is established.

JrMongo.isReady('myapp'); // Check specific DB
JrMongo.isReady();        // Check if any connection exists

JrMongo.close(dbName?)

Close a specific connection or all connections.

await JrMongo.close('myapp'); // Close one
await JrMongo.close();       // Close all

Find Operations

find(tableName, searchFor?, options?)

Find documents matching criteria with optional sort, skip, limit, and projection.

const users = await db.find('users', { age: { $gte: 18 } });

// With pagination and sorting
const page = await db.find('users', {}, {
  sort: { createdAt: -1 },
  skip: 20,
  limit: 10,
  projection: { name: 1, email: 1 }
});

findOne(tableName, searchFor?, projection?)

Find a single document. Returns null if not found.

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

findFirst(tableName, searchFor?, projection?)

Alias for findOne().

findAll(tableName, projection?)

Find all documents in a collection.

const allUsers = await db.findAll('users', { name: 1, email: 1 });

findLimit(tableName, searchFor, limit)

Find documents with a limit.

const top10 = await db.findLimit('users', {}, 10);

findLimitEnd(tableName, searchFor, limit)

Find the last N documents (sorted by natural insertion order, newest first).

const latest = await db.findLimitEnd('logs', {}, 5);

findText(tableName, textToSearchFor)

Perform text search (requires a text index on the collection).

const match = await db.findText('articles', 'mongodb tutorial');

Insert Operations

add(tableName, newObject)

Insert a single document.

const result = await db.add('users', { name: 'Alice', age: 30 });
console.log(result.insertedId);

addMany(tableName, arrayOfNewObjects)

Insert multiple documents.

const result = await db.addMany('users', [
  { name: 'Bob', age: 25 },
  { name: 'Carol', age: 35 }
]);
console.log(result.insertedCount); // 2

Update Operations

update(tableName, searchFor, updateTo, upsert?)

Update a single document using $set.

await db.update('users', { name: 'Alice' }, { age: 31 });

// With upsert (create if not found)
await db.update('users', { name: 'Eve' }, { name: 'Eve', age: 22 }, true);

updateMany(tableName, searchFor, updateTo)

Update multiple documents using $set.

await db.updateMany('users', { role: 'guest' }, { active: false });

updateParts(tableName, searchFor, updateTo, upsert?)

Update nested fields without overwriting sibling fields. Uses dot-notation flattening internally.

// Only updates address.city, leaves address.state and address.zip intact
await db.updateParts('users', { name: 'Alice' }, {
  address: { city: 'New York' }
});

findOneAndUpdate(tableName, searchFor, updateTo, options?)

Atomically find and update a document, returning the document.

| Option | Type | Default | Description | |--------|------|---------|-------------| | upsert | boolean | false | Create if not found | | returnNew | boolean | true | Return updated doc (true) or original (false) | | projection | object | — | Fields to include/exclude |

const user = await db.findOneAndUpdate('users',
  { name: 'Alice' },
  { loginCount: 5 },
  { returnNew: true }
);

push(tableName, searchFor, valueToPush, upsert?)

Push a value onto an array field using $push.

await db.push('users', { name: 'Alice' }, { tags: 'admin' });

bulkWrite(tableName, data)

Perform bulk write operations.

await db.bulkWrite('users', [
  { insertOne: { document: { name: 'David', age: 28 } } },
  { updateOne: { filter: { name: 'Alice' }, update: { $set: { age: 32 } } } },
  { deleteOne: { filter: { name: 'Bob' } } }
]);

Delete Operations

deleteOne(tableName, searchFor)

Delete a single document.

await db.deleteOne('users', { name: 'Bob' });

deleteMany(tableName, searchFor?)

Delete multiple documents. Pass empty or no filter to delete all.

await db.deleteMany('users', { active: false });
await db.deleteMany('temp_data'); // delete all

findOneAndDelete(tableName, searchFor, options?)

Atomically find and delete a document, returning the deleted document.

| Option | Type | Description | |--------|------|-------------| | projection | object | Fields to include/exclude | | sort | object | Sort to determine which document to delete |

const deleted = await db.findOneAndDelete('queue', { status: 'pending' });

Aggregation

aggregate(tableName, pipeline)

Run an aggregation pipeline.

const stats = await db.aggregate('orders', [
  { $match: { status: 'completed' } },
  { $group: { _id: '$product', total: { $sum: '$amount' } } },
  { $sort: { total: -1 } }
]);

Count & Utility

count(tableName, searchFor?)

Count documents matching the filter.

const total = await db.count('users');
const admins = await db.count('users', { role: 'admin' });

getTableNames()

Get all collection names in the database.

const collections = await db.getTableNames();

close()

Close this database connection.

await db.close();

Index Management

createIndex(tableName, indexSpec, options?)

Create an index on a collection.

await db.createIndex('users', { email: 1 }, { unique: true });
await db.createIndex('articles', { title: 'text', body: 'text' });

createIndexes(tableName, indexSpecs)

Create multiple indexes at once.

await db.createIndexes('users', [
  { key: { email: 1 }, unique: true },
  { key: { createdAt: -1 } }
]);

dropIndex(tableName, indexName)

Drop a specific index.

await db.dropIndex('users', 'email_1');

dropIndexes(tableName)

Drop all indexes (except _id).

listIndexes(tableName)

List all indexes on a collection.

const indexes = await db.listIndexes('users');

Collection Management

createCollection(collectionName, options?)

Create a new collection.

await db.createCollection('logs', { capped: true, size: 1048576 });

dropCollection(collectionName)

Drop a collection.

await db.dropCollection('old_logs');

ObjectId

JrMongo re-exports MongoDB's ObjectId for convenience, so you don't need to install or import mongodb separately:

import { JrMongo, ObjectId } from '@flickerstop/jrmongo';

const user = await db.findOne('users', { _id: new ObjectId('507f1f77bcf86cd799439011') });

Environment Variables

| Variable | Required | Description | |----------|----------|-------------| | MONGODB_URL | Yes (unless passed to db()) | MongoDB connection string |

Example .env file:

MONGODB_URL=mongodb://localhost:27017
# or for MongoDB Atlas:
MONGODB_URL=mongodb+srv://username:[email protected]

Error Handling

All methods return promises. Use try/catch for error handling:

try {
  await db.add('users', { name: 'Alice' });
} catch (error) {
  console.error('Database operation failed:', error);
}

Input validation throws immediately for invalid arguments:

try {
  await db.find('');  // Empty collection name
} catch (error) {
  // "JrMongo: tableName must be a non-empty string"
}

Connection Management

  • Connections are established lazily on first operation
  • Connections are reused across all operations on the same database
  • Multiple database connections can coexist simultaneously
  • Call db.close() or JrMongo.close() to clean up

TypeScript Support

JrMongo includes comprehensive TypeScript definitions:

import { JrMongo, ObjectId } from '@flickerstop/jrmongo';

interface User {
  _id?: ObjectId;
  name: string;
  email: string;
  age: number;
}

const db = JrMongo.db('myapp');
const user = await db.findOne<User>('users', { name: 'Alice' });
const users = await db.find<User>('users', {}, { sort: { name: 1 }, limit: 10 });

Contributing

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

License

MIT License - see LICENSE file for details.