Skip to main content
Prisma Documentation Docs

Search documentation

Type to search this documentation.

On this pageOverview

MongoDB

To add Prisma ORM to a project that already uses MongoDB, you will run orm init, describe the collections you want to work with, emit the generated artifacts, and run a couple of queries.

Use this path when you already have an application and database. Make sure the app can already reach its MongoDB deployment and runs on Node.js 22.18 or newer (on the 24 line, 24.11 or newer; Node.js 24 is recommended). If you want Prisma ORM to create a new app for you, use the MongoDB quickstart.

A standalone mongod is enough for the steps below. A replica set is only needed for transactions and change streams; MongoDB Atlas already gives you one.

If your project already runs TypeScript scripts, you can skip this step.

Otherwise, install the script tooling:

title="bun"
bun add --dev tsx typescript
pnpm
pnpm add --save-dev tsx typescript
yarn
yarn add --dev tsx typescript
npm
npm install --save-dev tsx typescript

From the root of your existing project, run:

bunx prisma@latest orm init --target mongodb
Bash
pnpm dlx prisma@latest orm init --target mongodb
Bash
yarn dlx prisma@latest orm init --target mongodb
Bash
npx prisma@latest orm init --target mongodb

This command is for a project that already exists: it preselects MongoDB, adds Prisma ORM files and package scripts to the app you already have, and does not scaffold a new framework project.

orm init also changes the module settings in tsconfig.json, and adds "type": "module" to package.json when the file has no "type" field. If your app is CommonJS, follow In a CommonJS project before you run the app again.

It also adds prisma-8.md, a short project-level reference your coding agent can read. It does not install agent skills; the Prisma ORM skill ships inside the @prisma/orm-mongo package your project installs. If you later run prisma init or prisma skills sync, Prisma writes skill files for coding agents into your repo. To stop that, pass --skills=none to init or set the skills.agents config field to []; the next skills sync removes any copies already written.

When Prisma ORM asks the remaining setup questions:

  • choose PSL
  • keep the default schema path, src/prisma/contract.prisma. Pass --schema-path if you want the contract somewhere else; the rest of this page assumes the default.
  • answer the last question, Also write a .env file from .env.example? (gitignored), with Yes. It defaults to No, and --write-env skips the prompt and writes the file.

This command is for a project that already exists: it preselects MongoDB, adds Prisma ORM files and package scripts to the app you already have, and does not scaffold a new framework project.

orm init also changes the module settings in tsconfig.json, and adds "type": "module" to package.json when the file has no "type" field. If your app is CommonJS, follow In a CommonJS project before you run the app again.

It also adds prisma-8.md, a short project-level reference your coding agent can read. It does not install agent skills; the Prisma ORM skill ships inside the @prisma/orm-mongo package your project installs. If you later run prisma init or prisma skills sync, Prisma writes skill files for coding agents into your repo. To stop that, pass --skills=none to init or set the skills.agents config field to []; the next skills sync removes any copies already written.

When Prisma ORM asks the remaining setup questions:

  • choose PSL
  • keep the default schema path, src/prisma/contract.prisma. Pass --schema-path if you want the contract somewhere else; the rest of this page assumes the default.
  • answer the last question, Also write a .env file from .env.example? (gitignored), with Yes. It defaults to No, and --write-env skips the prompt and writes the file.

orm init always writes .env.example, and writes .env only if you asked it to. Put the connection string for the MongoDB deployment your app already uses into .env:

title=".env"
DATABASE_URL="mongodb://127.0.0.1:27017/app?replicaSet=rs0"

orm init also writes src/prisma/db.ts, the file your application imports. It builds the Prisma ORM client from the emitted contract and reads the connection string from the environment:

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

import mongo from "@prisma/orm-mongo/runtime";

import type { Contract } from "./contract.d";

import contractJson from "./contract.json" with { type: "json" };

export const db = mongo<Contract>({

  contractJson,

  url: process.env["DATABASE_URL"]!,

});

The first line is import "dotenv/config", so any script that imports db loads .env for itself. You do not need to pass the URL again at the call site.

This is the key adoption step for MongoDB, because you decide which part of the existing database Prisma ORM should model first.

PostgreSQL has contract infer, but MongoDB does not, so this step is manual.

Open src/prisma/contract.prisma and make it match the collections you want Prisma ORM to query first. If your existing database already has users and posts collections with email, name, title, and authorId, the starter contract is already a useful first draft:

title="src/prisma/contract.prisma"
// use prisma-8

model User {

  id    ObjectId @id @map("_id")

  email String   @unique

  name  String?

  posts Post[]

  @@map("users")

}

model Post {

  id       ObjectId @id @map("_id")

  title    String

  content  String?

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

  authorId ObjectId

  @@map("posts")

}

You do not need to model every collection on day one. Start with the part of the database you want to read and write first.

Once the contract looks right, this step turns it into the generated files the runtime and query APIs use.

Run:

bunx prisma contract emit
Bash
pnpm prisma contract emit
Bash
yarn prisma contract emit
Bash
npx prisma contract emit

This refreshes src/prisma/contract.json and src/prisma/contract.d.ts so the runtime and query APIs match the contract you just reviewed.

This refreshes src/prisma/contract.json and src/prisma/contract.d.ts so the runtime and query APIs match the contract you just reviewed.

With the emitted artifacts in place, you can test the higher-level API first and confirm Prisma ORM can read the existing collections.

Create a script.ts file:

title="script.ts"
import { db } from "./src/prisma/db";

async function main() {

  const user = await db.orm.users.where({ email: "existing@example.com" }).first();

  console.log(user);

  await db.close();

}

main().catch((error) => {

  console.error(error);

  process.exit(1);

});

Run it:

title="bun"
bunx tsx script.ts
pnpm
pnpm dlx tsx script.ts
yarn
yarn dlx tsx script.ts
npm
npx tsx script.ts

After the ORM example, this step shows the lower-level MongoDB pipeline builder against the same existing collections.

Pipeline plans run through the runtime. On MongoDB db.runtime() returns a promise, so it has to be awaited; on PostgreSQL the same call is synchronous.

Replace script.ts with this version:

title="script.ts"
import { db } from "./src/prisma/db";

async function main() {

  const runtime = await db.runtime();

  const plan = db.query

    .from("users")

    .match((fields) => fields.email.eq("existing@example.com"))

    .project("email", "name")

    .build();

  const rows = await runtime.query(plan);

  console.log(rows);

  await db.close();

}

main().catch((error) => {

  console.error(error);

  process.exit(1);

});

Run it again:

title="bun"
bunx tsx script.ts
pnpm
pnpm dlx tsx script.ts
yarn
yarn dlx tsx script.ts
npm
npx tsx script.ts

When you change src/prisma/contract.prisma, emit the contract again:

bunx prisma contract emit
Bash
pnpm prisma contract emit
Bash
yarn prisma contract emit
Bash
npx prisma contract emit

You do not need a migration just to read collections that already exist. Use migration plan when you want Prisma ORM to own a schema change.

You do not need a migration just to read collections that already exist. Use migration plan when you want Prisma ORM to own a schema change.

Suggest an edit

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

Export
Documentation menu