Skip to main content
Prisma Documentation Docs

Search documentation

Type to search this documentation.

On this pageOverview

Mongoose

This guide shows you how to migrate your application from Mongoose to Prisma ORM. The examples use a sample project.

You can learn how Prisma ORM compares to Mongoose on the Prisma ORM vs Mongoose page.

Before starting this guide, make sure you have:

  • A Mongoose project you want to migrate
  • Node.js installed with the supported version
  • MongoDB database (4.2+ with replica set deployment recommended)
  • Basic familiarity with Mongoose and Express.js

The steps for migrating from Mongoose to Prisma ORM are always the same, no matter what kind of application or API layer you're building:

  1. Install the Prisma CLI
  2. Introspect your database
  3. Install and generate Prisma Client
  4. Gradually replace your Mongoose queries with Prisma Client

These steps apply whether you're building a REST API (e.g., with Express, Koa, or NestJS), a GraphQL API (e.g., with Apollo Server, TypeGraphQL, or Nexus), or any other kind of application that uses Mongoose for database access.

First, install the required Prisma packages:

title="bun"
bun add prisma@6.19.3 @types/node --dev
pnpm
pnpm add prisma@6.19.3 @types/node --save-dev
yarn
yarn add prisma@6.19.3 @types/node --dev
npm
npm install prisma@6.19.3 @types/node --save-dev
bun add @prisma/client@6.19.3 dotenv
Bash
pnpm add @prisma/client@6.19.3 dotenv
Bash
yarn add @prisma/client@6.19.3 dotenv
Bash
npm install @prisma/client@6.19.3 dotenv

[!NOTE] Why Prisma v6.19?

This is the latest stable version of Prisma ORM v6 that fully supports MongoDB. MongoDB support for Prisma ORM v7 is coming soon.

You can also install prisma@6 and @prisma/client@6 to automatically get the latest v6 release.

Create a new Prisma schema file:

title="bun"
bunx --bun prisma init --datasource-provider mongodb --output ../generated/prisma
pnpm
pnpm prisma init --datasource-provider mongodb --output ../generated/prisma
yarn
yarn prisma init --datasource-provider mongodb --output ../generated/prisma
npm
npx prisma init --datasource-provider mongodb --output ../generated/prisma

This command creates:

  • A new directory called prisma that contains a schema.prisma file; your Prisma schema specifies your database connection and models
  • .env: A dotenv file at the root of your project (if it doesn't already exist), used to configure your database connection URL as an environment variable
  • prisma.config.ts: Configuration file for Prisma

The Prisma schema uses the ESM-first prisma-client generator:

title="prisma/schema.prisma"
generator client {

  provider = "prisma-client"

  output   = "../generated/prisma"

}

datasource db {

  provider = "mongodb"

  url      = env("DATABASE_URL")

}

Update the DATABASE_URL in the .env file with your MongoDB connection string:

DATABASE_URL="mongodb+srv://username:password@cluster.mongodb.net/mydb"

The generated prisma.config.ts file should look like this:

title="prisma.config.ts"
import { defineConfig, env } from "prisma/config";

export default defineConfig({

  schema: "prisma/schema.prisma",

  migrations: {

    path: "prisma/migrations",

  },

  engine: "classic",

  datasource: {

    url: env("DATABASE_URL"),

  },

});

Add dotenv to load environment variables from your .env file:

title="prisma.config.ts"
import "dotenv/config"; 

import { defineConfig, env } from "prisma/config";

export default defineConfig({

  schema: "prisma/schema.prisma",

  migrations: {

    path: "prisma/migrations",

  },

  engine: "classic",

  datasource: {

    url: env("DATABASE_URL"),

  },

});

Run Prisma's introspection to create the Prisma schema from your existing database:

title="bun"
bunx prisma db pull
pnpm
pnpm prisma db pull
yarn
yarn prisma db pull
npm
npx prisma db pull

This will create a schema.prisma file with your database schema.

title="prisma/schema.prisma"
type UsersProfile {

  bio String

}

model categories {

  id   String @id @default(auto()) @map("_id") @db.ObjectId

  v    Int    @map("__v")

  name String

}

model posts {

  id         String   @id @default(auto()) @map("_id") @db.ObjectId

  v          Int      @map("__v")

  author     String   @db.ObjectId

  categories String[] @db.ObjectId

  content    String

  published  Boolean

  title      String

}

model users {

  id      String        @id @default(auto()) @map("_id") @db.ObjectId

  v       Int           @map("__v")

  email   String        @unique(map: "email_1")

  name    String

  profile UsersProfile?

}

MongoDB doesn't support relations between different collections. However, you can create references between documents using the ObjectId field type or from one document to many using an array of ObjectIds in the collection. The reference will store id(s) of the related document(s). You can use the populate() method that Mongoose provides to populate the reference with the data of the related document.

Update the 1-n relationship between posts <-> users as follows:

  • Rename the existing author reference in the posts model to authorId and add the @map("author") attribute
  • Add the author relation field in the posts model and it's @relation attribute specifying the fields and references
  • Add the posts relation in the users model

Your schema should now look like this:

title="schema.prisma"
type UsersProfile {

  bio String

}

model categories {

  id   String @id @default(auto()) @map("_id") @db.ObjectId

  v    Int    @map("__v")

  name String

}

model posts {

  id        String  @id @default(auto()) @map("_id") @db.ObjectId

  title     String

  content   String

  published Boolean

  v         Int     @map("__v")

  author   String   @db.ObjectId

  author   users  @relation(fields: [authorId], references: [id]) 

  authorId String @map("author") @db.ObjectId

  categories String[] @db.ObjectId

}

model users {

  id      String        @id @default(auto()) @map("_id") @db.ObjectId

  v       Int           @map("__v")

  email   String        @unique(map: "email_1")

  name    String

  profile UsersProfile?

  posts   posts[]

}

Then, update the m-n between posts <-> categories references as follows:

  • Rename the categories field to categoryIds and map it using @map("categories") in the posts model
  • Add a new categories relation field in the posts model
  • Add the postIds scalar list field in the categories model
  • Add the posts relation in the categories model
  • Add a relation scalar on both models
  • Add the @relation attribute specifying the fields and references arguments on both sides

Your schema should now look like this:

title="schema.prisma"
type UsersProfile {

  bio String

}

model categories {

  id   String @id @default(auto()) @map("_id") @db.ObjectId

  v    Int    @map("__v")

  name String

  posts    posts[]  @relation(fields: [postIds], references: [id]) 

  postIds String[] @db.ObjectId

}

model posts {

  id        String  @id @default(auto()) @map("_id") @db.ObjectId

  title     String

  content   String

  published Boolean

  v         Int     @map("__v")

  author   users  @relation(fields: [authorId], references: [id])

  authorId String @map("author") @db.ObjectId

  categories  String[] @db.ObjectId

  categories  categories[] @relation(fields: [categoryIds], references: [id]) 

  categoryIds String[] @map("categories") @db.ObjectId

}

model users {

  id      String        @id @default(auto()) @map("_id") @db.ObjectId

  v       Int           @map("__v")

  email   String        @unique(map: "email_1")

  name    String

  profile UsersProfile?

  posts   posts[]

}

Generate Prisma Client based on your schema:

title="bun"
bunx prisma generate
pnpm
pnpm prisma generate
yarn
yarn prisma generate
npm
npx prisma generate

This creates a type-safe Prisma Client in the generated/prisma directory.

Create a module that instantiates the client once, so your controllers can import it:

title="src/client.ts"
import { PrismaClient } from "../generated/prisma/client";

export const prisma = new PrismaClient();

Start replacing your Mongoose queries with Prisma Client. Here's an example of how to convert some common queries:

title="Mongoose"
// Find one

const user = await User.findById(id);

// Create

const user = await User.create({

  email: "alice@prisma.io",

  name: "Alice",

});

// Update

await User.findByIdAndUpdate(id, {

  name: "New name",

});

// Delete

await User.findByIdAndDelete(id);
Prisma Client
// Find one
const user = await prisma.users.findUnique({
  where: { id },
});

// Create
const user = await prisma.users.create({
  data: {
    email: "alice@prisma.io",
    name: "Alice",
  },
});

// Update
await prisma.users.update({
  where: { id },
  data: { name: "New name" },
});

// Delete
await prisma.users.delete({
  where: { id },
});

Update your Express controllers to use Prisma Client. For example, here's how to update a user controller:

import { prisma } from "../client";

export class UserController {

  async create(req: Request, res: Response) {

    const { email, name } = req.body;

    const result = await prisma.users.create({

      data: {

        email,

        name,

      },

    });

    return res.json(result);

  }

}

Now that you've migrated to Prisma ORM, you can:

  • Add more complex queries, such as filters, relations, and aggregations
  • Set up Prisma Studio for database management
  • Implement database monitoring
  • Add automated tests using Prisma's testing utilities

For more information:

Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu