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

@mantlejs/mongodb

v0.1.0-experimental

Published

MongoDB adapter for Mantle JS — MongoRepository with full QueryParams support and Atlas Vector Search

Readme

@mantlejs/mongodb

MongoDB adapter for Mantle JS. Provides MongoRepository<T> — an abstract Repository<T> base class over the official MongoDB Node.js driver (no Mongoose) — and MongoVectorRepository<T>, a VectorRepository<T> implementation on top of MongoDB Atlas Vector Search. Primary deployment target is MongoDB Atlas; works unchanged against any MongoDB 6+ server.


Installation

npm install @mantlejs/mongodb mongodb

Concepts

Document storage

MongoDB stores records as BSON documents in named collections. Mongo's native _id is an ObjectId; MongoRepository accepts and returns id as a string (24-char hex) at the Repository<T> boundary, converting to/from ObjectId internally — services and hooks never see a raw ObjectId. Malformed ids are rejected with BadRequest.

Collections

Subclasses declare readonly collectionName: string. Collections are created lazily by MongoDB on first write — no manual setup required for development or testing.

Query translation

Mantle QueryParams.where operators map almost directly onto MongoDB query operators — $lt/$lte/$gt/$gte/$ne/$in/$nin/$or/$and are native MongoDB syntax already, and dot-path keys ("metadata.owner.name") are native too. $contains is translated to jsonb-@>-equivalent MongoDB conditions. $like/$ilike/$notlike are not supported by this adapter and throw BadRequest — use the raw collection escape hatch with $regex for pattern matching. Unsupported operators are rejected loudly via assertOperators.

Vector search (Atlas)

MongoVectorRepository implements Mantle's VectorRepository<T> (findSimilar / upsertVector / deleteVector) via the $vectorSearch aggregation stage. This is an Atlas feature, not core MongoDB — it requires an Atlas cluster (the free M0 tier works) and an Atlas Vector Search index on the collection. Fields you want to filter on in findSimilar must be declared as type: "filter" in that index. Register it with VectorRepositoryService from @mantlejs/mantle to expose POST /<path>/similar, exactly like the Pinecone/Qdrant adapters.

Transactions

withTransaction() runs a block of repository calls inside one MongoDB session/transaction via client.startSession().withTransaction(). This requires the deployment to be a replica set — true for every Atlas cluster including free-tier M0. Standalone self-hosted MongoDB without a replica set throws the driver's native error; this is a deployment requirement, not something Mantle works around.


Quick start

import { mantle } from "@mantlejs/mantle";
import { mongodb, MongoRepository } from "@mantlejs/mongodb";

const app = mantle().configure(mongodb({ uri: process.env.MONGODB_URI!, dbName: "app" }));

interface User extends Record<string, unknown> {
  id: string;
  name: string;
  email: string;
}

class UserRepository extends MongoRepository<User> {
  readonly collectionName = "users";

  // Escape hatch — driver-native queries via this.collection
  async findByEmailDomain(domain: string): Promise<User[]> {
    const docs = await this.collection.find({ email: { $regex: `@${domain}$` } }).toArray();
    return docs.map((doc) => this.fromDocument(doc));
  }
}

const repo = new UserRepository(app);

const user = await repo.save({ name: "Alice", email: "[email protected]" });
const admins = await repo.findAll({ where: { role: "admin" }, sort: { name: "asc" }, limit: 10 });

// Transaction (requires a replica set / Atlas)
await repo.withTransaction(async (txRepo) => {
  const alice = await txRepo.save({ name: "Alice", email: "[email protected]" });
  await txRepo.patchById(alice.id, { name: "Alice A." });
});

Vector search quick start

import { VectorRepositoryService } from "@mantlejs/mantle";
import { MongoVectorRepository } from "@mantlejs/mongodb";

interface Doc extends Record<string, unknown> {
  id: string;
  text: string;
  category: string;
}

class DocRepository extends MongoVectorRepository<Doc> {
  readonly collectionName = "docs";
  override readonly vectorIndexName = "docs_vector_index"; // Atlas Vector Search index name
  override readonly vectorField = "embedding"; // field the index covers
}

const docs = new DocRepository(app);

await docs.upsertVector(id, embedding, { text: "MongoDB is a document database", category: "db" });

// Top-5 nearest neighbours, optionally pre-filtered ("category" must be a filter field in the index)
const hits = await docs.findSimilar(queryEmbedding, 5, { where: { category: "db" } });
// → [{ id, text, category, _score: 0.97 }, …]  — HIGHER _score is more similar

// Or expose it as a service: POST /docs/similar { "vector": [...], "topK": 5 }
app.use("docs", new VectorRepositoryService(docs), {
  methods: ["find", "get", "create", "update", "patch", "remove", "similar"],
});

API

mongodb(config)

Returns a MantlePlugin. Call via app.configure(mongodb(config)).

app.configure(mongodb({ uri: "mongodb+srv://…", dbName: "app" }));

Side effects:

  • Creates one MongoClient (connects lazily on first operation) and stores it at app.get("mongoClient")
  • Stores the target Db at app.get("mongoDb")
  • Wraps app.teardown() to close the client

MongoConfig

| Field | Type | Default | Description | | --------------- | -------------------- | ------- | ---------------------------------------------------- | | uri | string | — | Atlas or self-hosted connection string (required) | | dbName | string | — | Database to open collections against (required) | | clientOptions | MongoClientOptions | {} | Full driver options (TLS, pool sizing) — passthrough |


MongoRepository<T, D> (abstract class)

Implements Repository<T, D> for MongoDB. Subclasses must declare collectionName.

| Method | Description | | ---------------------- | ----------------------------------------------------------------------- | | findAll(params?) | Query documents with filtering, sorting, offset pagination, projection | | findById(id) | Fetch a single record by id; returns null if not found | | save(data) | Insert a document (_id auto-generated unless data.id is given) | | saveAll(data[]) | Batch insert (single insertMany call) | | updateById(id, data) | Replace the full document (findOneAndReplace) | | patchById(id, data) | Merge partial fields ($set); undefined values are dropped | | deleteById(id) | Delete a record and return it; throws NotFound if absent | | count(params?) | Count documents matching optional QueryParams | | withTransaction(fn) | Run repository calls in one MongoDB transaction (replica set required) | | describe() | RepositoryCapabilities — adapter name, operator set, pagination style |

Instance properties

| Property | Type | Default | Description | | ---------------- | ------------ | ------- | --------------------------------------------------------------- | | collectionName | string | — | Collection to target (abstract — must be declared) | | timestamps | boolean | true | Maintain createdAt/updatedAt as BSON Date fields | | collection | Collection | — | Protected escape hatch — the driver collection ($regex, agg…) |

QueryParams.where operators

Equality, null, $lt, $lte, $gt, $gte, $ne, $in, $nin, $or, $and, $contains, and dot-path keys. $contains follows the shared jsonb-@> conformance semantics (NESTED_QUERY_CASES in @mantlejs/mantle): scalar operand → array-element match, array operand → $all, object operand → recursive dot-path superset. $like/$ilike/$notlike throw BadRequest.

Error mapping

Driver errors are translated to typed MantleError subclasses:

| Condition | Error thrown | | ---------------------------------------------------------- | ------------- | | Duplicate key (code 11000 or 11001) | Conflict | | MongoNetworkError, MongoServerSelectionError | Unavailable | | anything else | GeneralError |


MongoVectorRepository<T, D> (abstract class)

Extends MongoRepository<T, D> and implements VectorRepository<T, D> via Atlas Vector Search.

VectorRepository<T> methods

| Method | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | | findSimilar(vector, topK, params?) | $vectorSearch top-K nearest neighbours; results carry _score (higher = more similar) and exclude the embedding field | | upsertVector(id, vector, data) | Upsert a record with its embedding (findOneAndUpdate + upsert) | | deleteVector(id) | Delete the record (and its embedding) — same as deleteById |

Additional instance properties

| Property | Type | Default | Description | | --------------------- | -------- | ---------------- | ----------------------------------------------------------------------- | | vectorIndexName | string | "vector_index" | Name of the Atlas Vector Search index on this collection | | vectorField | string | "embedding" | Document field storing the embedding | | candidateMultiplier | number | 10 | ANN pool: numCandidates = topK × multiplier (capped at Atlas's 10000) |


Types

import type { MongoConfig, WhereClause } from "@mantlejs/mongodb";
import { MONGO_OPERATORS, toMongoFilter, toMongoSort, toMongoProjection } from "@mantlejs/mongodb";

| Export | Description | | ------------------- | ---------------------------------------------------------------- | | MongoConfig | Options passed to the mongodb() plugin | | MONGO_OPERATORS | Exactly the $-operators the where-clause translator accepts | | toMongoFilter | QueryParams.where → MongoDB filter document translator | | toMongoSort | QueryParams.sort → MongoDB sort document (asc/desc → 1/-1) | | toMongoProjection | QueryParams.select → MongoDB inclusion projection |


Development

npx nx build mongodb    # compile
npx nx test mongodb     # run tests
npx nx lint mongodb     # lint

Publishing

Build before publishing:

npx nx build mongodb

First publish (scoped packages require --access public):

cd packages/mongodb
npm publish --access public

Subsequent releases — bump version in packages/mongodb/package.json, then:

cd packages/mongodb
npm publish