## Introduction

This guide shows you how to migrate your application from Mongoose to Prisma ORM. We'll use a [sample project](https://github.com/prisma/migrate-from-mongoose-to-prisma) to demonstrate the migration steps.

:::warning[MongoDB support for Prisma ORM v7]

**MongoDB support for Prisma ORM v7 is coming in the near future.** In the meantime, please use **Prisma ORM v6.19** (the latest v6 release) when working with MongoDB.

This guide uses Prisma ORM v6.19 to ensure full compatibility with MongoDB.

:::

You can learn how Prisma ORM compares to Mongoose on the [Prisma ORM vs Mongoose](/orm/more/comparisons/prisma-and-mongoose) page.

:::warning

This guide currently assumes you are using **Prisma ORM v6**. Support for Prisma ORM v7 with MongoDB is in progress.

:::

## Prerequisites

Before starting this guide, make sure you have:

- A Mongoose project you want to migrate
- Node.js installed [with the supported version](/orm/more/upgrade-guides/upgrading-versions/upgrading-to-prisma-6#minimum-supported-nodejs-versions)
- MongoDB database (4.2+ with replica set deployment recommended)
- Basic familiarity with Mongoose and Express.js

## 1. Prepare for migration

### 1.1. Understand the migration process

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.

### 1.2. Install Prisma dependencies

First, install the required Prisma packages:

```terminal
npm install prisma@6.19 @types/node --save-dev
npm install @prisma/client@6.19 dotenv
```

:::info[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.

:::

### 1.3. Set up Prisma configuration

Create a new Prisma schema file:

```terminal
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`](https://github.com/motdotla/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:

```prisma file=prisma/schema.prisma showLineNumbers
generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
}

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}
```
<br/>

:::tip

For an optimal development experience when working with Prisma ORM, refer to [editor setup](/orm/more/development-environment/editor-setup) to learn about syntax highlighting, formatting, auto-completion, and many more cool features.

:::

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

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

:::tip

Replace `username`, `password`, `cluster`, and `mydb` with your actual MongoDB credentials and database name. You can get your connection string from [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) or your MongoDB deployment.

:::

### 1.4. Configure Prisma

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

```typescript file=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:

```typescript file=prisma.config.ts
// add-start
import 'dotenv/config'
// add-end
import { defineConfig, env } from 'prisma/config'

export default defineConfig({
  schema: 'prisma/schema.prisma',
  migrations: {
    path: 'prisma/migrations',
  },
  engine: "classic",
  datasource: {
    url: env('DATABASE_URL'),
  },
})
```

## 2. Migrate the database schema

### 2.1. Introspect your database

:::warning

MongoDB is a _schemaless_ database. To incrementally adopt Prisma ORM in your project, ensure your database is populated with sample data. Prisma ORM introspects a MongoDB schema by sampling data stored and inferring the schema from the data in the database.

:::

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

```terminal
npx prisma db pull
```

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

```prisma file=prisma/schema.prisma showLineNumbers
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?
}
```

### 2.2. Update relations

MongoDB doesn't support relations between different collections. However, you can create references between documents using the [`ObjectId`](/orm/overview/databases/mongodb#using-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:

```prisma file=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")
  //delete-next-line
  author   String   @db.ObjectId
  //add-start
  author   users  @relation(fields: [authorId], references: [id])
  authorId String @map("author") @db.ObjectId
  //add-end

  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?
  //add-next-line
  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](/orm/prisma-schema/data-model/relations#annotated-relation-fields) on both models
- Add the `@relation` attribute specifying the `fields` and `references` arguments on both sides

Your schema should now look like this:

```prisma file=schema.prisma
type UsersProfile {
  bio String
}

model categories {
  id   String @id @default(auto()) @map("_id") @db.ObjectId
  v    Int    @map("__v")
  name String
  //add-start
  posts    posts[]  @relation(fields: [postIds], references: [id])
  postIds String[] @db.ObjectId
  //add-end
}

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

  //delete-next-line
  categories  String[] @db.ObjectId
  //add-start
  categories  categories[] @relation(fields: [categoryIds], references: [id])
  categoryIds String[] @map("categories") @db.ObjectId
  //add-end
}

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[]
}
```

## 3. Update your application code

### 3.1. Generate Prisma Client

Generate Prisma Client based on your schema:

```terminal
npx prisma generate
```

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

### 3.2. Replace Mongoose queries

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

<TabbedContent code>

<TabItem value="Mongoose">

```typescript
// 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);
```

</TabItem>

<TabItem value="Prisma Client">

```typescript
// Find one
const user = await prisma.user.findUnique({ 
  where: { id } 
});

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

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

// Delete
await prisma.user.delete({
  where: { id }
});
```

</TabItem>

</TabbedContent>

### 3.3. Update your controllers

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

```typescript
import { prisma } from '../client'

export class UserController {
  async create(req: Request, res: Response) {
    const { email, name } = req.body
    
    const result = await prisma.user.create({
      data: {
        email,
        name,
      },
    })
    
    return res.json(result)
  }
}
```

## Next steps

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

- Add more complex queries using Prisma's powerful query API
- Set up Prisma Studio for database management
- Implement database monitoring
- Add automated tests using Prisma's testing utilities

For more information:
- [Prisma ORM documentation](/orm)
- [Prisma Client API reference](/orm/prisma-client)
---

# How to migrate from Drizzle to Prisma ORM