Skip to content

Migrate from Mongoose

Mondel is intentionally not a Mongoose-compatible layer. Plan for API and mental-model changes.

What maps cleanly

MongooseMondel
Schema pathsdefineSchema + s.*
required, enum, min, max.required(), .enum(), .min(), .max()
unique: true.unique() / index options
timestamps: truetimestamps: true
Model.findfindMany
Model.findOnefindOne
Model.createcreate / createMany
findByIdAndUpdatefindOneAndUpdate / updateById
countDocumentscount
Transactions via sessionsdb.startSession() + { session }

What does not map 1:1

Mongoose featureMondel approach
Middleware (pre/post)Explicit functions in your app layer
VirtualsCompute in application code
Populate$lookup aggregation or manual second query
DiscriminatorsSeparate schemas / collections
PluginsCompose your own helpers
Lean vs hydrated docsAlways plain objects
save() on documentsupdateById / updateOne
Cast + coerce everywhereZod validation on writes; strict types

Schema example

typescript
// Mongoose-ish idea
// email: { type: String, required: true, unique: true }
// role: { type: String, enum: ["ADMIN", "USER"], default: "USER" }

import { defineSchema, s } from "mondel";

export const userSchema = defineSchema("users", {
  timestamps: true,
  fields: {
    email: s.string().required().email().unique(),
    role: s.enum(["ADMIN", "USER"]).default("USER"),
  },
});

Connection

Replace mongoose.connect + models with createClient (Client guide).

Indexes

Replace syncIndexes() on startup with:

bash
npx mondel push --uri "$MONGODB_URI" --schema ./dist/schemas.js

Validation

Mongoose casts aggressively. Mondel’s strict mode throws on invalid shapes — closer to “fail fast” than silent cast. Use loose while porting dirty data.

Populate → lookup

typescript
const usersWithPosts = await db.users.aggregate([
  {
    $lookup: {
      from: "posts",
      localField: "_id",
      foreignField: "authorId",
      as: "posts",
    },
  },
]);

Suggested migration order

  1. Read-only paths → findMany / findOne
  2. Simple writes → create / updateOne
  3. Remove document instance methods (user.save())
  4. Replace middleware with service functions
  5. Move indexes to CLI
  6. Enable validation: "strict"

Released under the MIT License. · llms.txt