mongoose
Elegant MongoDB object modeling for Node.js — schemas, validation, middleware, and type-safe queries.
MongoDB is schemaless, but your application needs structure — consistent field types, required fields, default values, and relationships. Writing raw MongoDB driver code for every query is repetitive and error-prone.
Mongoose adds a schema layer on top of MongoDB. Define a Schema (field types, validation, defaults), create a Model from it, and query with Model.find(), Model.create(). Middleware (pre/post hooks) run before/after operations. Virtuals compute fields without storing them.
Define a schema and model
import mongoose, { Schema, Document } from 'mongoose';
interface IUser extends Document {
name: string;
email: string;
createdAt: Date;
}
const UserSchema = new Schema<IUser>({
name: { type: String, required: true, trim: true },
email: { type: String, required: true, unique: true, lowercase: true },
}, { timestamps: true });
export const User = mongoose.model<IUser>('User', UserSchema);
await mongoose.connect(process.env.MONGODB_URI!);
// Create
const alice = await User.create({ name: 'Alice', email: 'alice@example.com' });
// Query
const users = await User.find({ name: /alice/i }).sort('-createdAt').limit(10);
// Update
await User.updateOne({ _id: alice._id }, { $set: { name: 'Alice B.' } });
// Delete
await User.deleteOne({ _id: alice._id });Use it when
Node.js apps using MongoDB that need schema validation, relationships (populate), timestamps, virtuals, or reusable query helpers.
Skip it when
Schema-free documents where flexibility is intentional, TypeScript-first projects (consider Prisma + MongoDB or Typegoose), high-performance scenarios where the ODM overhead matters.
Ready to explore the full API?
See every class, function, and relationship in an interactive graph.