Mongster

Getting Started

Why Mongster ?

Motivation behind a type-safe MongoDB ODM

Mongster was built from the frustration felt over years of using the current MongoDB ecosystem for TypeScript. Existing ODM/ORM(s) do provide a lot of functionality but MongoDB being "Schemaless" and "Document-oriented", the ecosystem never grasped the power of TypeScript. Some projects do try to bring TypeScript but with a lot of tradeoffs and rituals.

Mongster tries to keep the best of both worlds; type-safety w/o the bloats.

Many MongoDB libraries grew up around JavaScript first that shows up in a few common patterns:

  • the runtime API is dynamic, and the TypeScript support is a second class citizen,
  • the schema lives in a second language, decorators, or a plugin ecosystem,
  • driver behavior gets hidden behind document classes, magic fields, or generated wrappers.

Mongster takes a narrower path

It keeps the official MongoDB driver model, then adds the pieces that matter for day-to-day TypeScript work: one schema for runtime validation, type inference, index metadata, typed populate, hooks, and a typed aggregation builder.

TypeScript should describe the real shape

In Mongster, the schema is not documentation sitting next to your code. It IS the code.

import { ,  } from "mongster";

const  = .({
  : .().(1),
  : .().(/.+@.+/).(),
  : .().(["admin", "member"]).("member"),
}).();

const  = ("users", );

type  = M.<typeof >;
type  = M.<typeof >;

That keeps the create input, stored document shape, and database indexes aligned without writing the same intent in multiple places.

Stay close to MongoDB

Mongster DOES NOT try to turn MongoDB into a relational ORM.

Queries still look like MongoDB queries. Updates still use MongoDB update operators. Transactions still use MongoDB sessions under the hood. If you already understand the driver and the database, Mongster should feel familiar rather than like a second database API.

Keep the useful parts, skip the extra abstraction

Mongster is opinionated about where abstraction is worth it:

  • keep schema validation,
  • keep type inference,
  • keep index definitions close to fields,
  • keep typed populate for declared refs,
  • keep transactions and hooks.

It deliberately avoids building a large document runtime around your collections. There are no document classes to learn before you can read a query. There is no separate schema DSL to compile. There is no plugin-driven object graph to debug.

Why not just use something else?

That depends on the tradeoff you want.

  • Mongoose is feature-rich, but that feature set grew around a very JavaScript-shaped model: documents with behavior, virtuals, middlewares, and a large API surface.
  • Typegoose inherits Mongoose's model through decorators and classes.
  • Prisma gives you generated client types, but with MongoDB it also brings a separate schema language and a workflow that is not centered on native MongoDB semantics.
  • Papr stays closer to the driver and brings a lot of the functionalities. But still lacks a lot of necessary APIs needed for day-to-day work.

Mongster goes further on typed populate, hooks, and aggregation ergonomics.

Mongster is for the case where you want MongoDB to stay MongoDB, while TypeScript becomes the main source of truth instead of a thin layer on top.

On this page