# Add Prisma ORM to an existing MongoDB database (/docs/prisma-orm/add-to-existing-project/mongodb) > For the complete Prisma documentation index, see [llms.txt](https://www.prisma.io/docs/llms.txt). A markdown version of any docs page is available by appending `.md` to its URL. Add Prisma ORM to an app whose MongoDB database already has collections. Location: Prisma ORM > Add To Existing Project > Add Prisma ORM to an existing MongoDB database This page uses MongoDB. [Use PostgreSQL instead](https://www.prisma.io/docs/prisma-orm/add-to-existing-project/postgresql). On this page you add Prisma ORM to an app whose MongoDB database already has collections. You run `orm init`, write a contract that describes your collections, and run two queries. The contract is the file that holds your models. In earlier Prisma ORM versions, it was `schema.prisma`. Your app must reach its MongoDB database and run on Node.js 22.18 or newer. A single `mongod` server is enough. You need a replica set only for transactions and change streams, and MongoDB Atlas already runs one. If your database has no collections yet, follow [Add Prisma ORM and MongoDB to an existing app](https://www.prisma.io/docs/prisma-orm/quickstart/existing-app/mongodb) instead, which creates the collections for you. If you want Prisma ORM to create a new app for you, follow [Create a new app with MongoDB](https://www.prisma.io/docs/prisma-orm/quickstart/mongodb). > [!NOTE] > Using Prisma ORM 7? > > Prisma ORM 8 is the current release, as a release candidate. Prisma ORM 7 remains fully supported; its docs live at [/orm/v7](https://www.prisma.io/docs/orm/v7) and its setup paths at [/v7/getting-started](https://www.prisma.io/docs/v7/getting-started). > > For what release candidate means, when the final release is expected, and how to stay on version 7, see [Release status](https://www.prisma.io/docs/orm/release-status). ## 1. Install `tsx` [#1-install-tsx] The scripts on this page run with `tsx`. If your project does not have it, install it: #### bun ```bash bun add --dev tsx typescript ``` #### pnpm ```bash pnpm add --save-dev tsx typescript ``` #### yarn ```bash yarn add --dev tsx typescript ``` #### npm ```bash npm install --save-dev tsx typescript ``` ## 2. Initialize Prisma ORM [#2-initialize-prisma-orm] The `orm init` command below changes your `tsconfig.json` and your `package.json`. In `tsconfig.json`, it sets `module` to `preserve` and `moduleResolution` to `bundler`. If your `package.json` has no `"type"` field, it adds `"type": "module"`. If it has `"type": "commonjs"`, the command keeps it and prints a warning. If your app runs as CommonJS, for example because it loads files with `require` or because `tsc` compiles it to `require` calls, follow [In a CommonJS project](https://www.prisma.io/docs/cli/orm-init#in-a-commonjs-project) before you start your app again. `tsx` runs the scripts on this page in both kinds of app, so you can finish this page first. From the root of your project, run: #### bun ```bash bunx prisma@latest orm init --yes --target mongodb --authoring psl --write-env ``` #### pnpm ```bash pnpm dlx prisma@latest orm init --yes --target mongodb --authoring psl --write-env ``` #### yarn ```bash yarn dlx prisma@latest orm init --yes --target mongodb --authoring psl --write-env ``` #### npm ```bash npx prisma@latest orm init --yes --target mongodb --authoring psl --write-env ``` `prisma@latest` runs Prisma ORM 8, and `--target mongodb` picks MongoDB. `--authoring psl` picks PSL, the Prisma Schema Language, which is the `.prisma` file format you know from earlier Prisma ORM versions. `--write-env` writes a `.env` file, unless you already have one. `--yes` accepts the default answer to every question, so the command asks nothing. The command installs the Prisma ORM packages and writes its files. You use three of them on this page: * `src/prisma/contract.prisma`, an example contract. In step 4 you change it to describe your collections. * `src/prisma/db.ts`, the file your code imports to run queries. * `.env`, which holds the connection string. The command also writes `prisma-8.md`, a short reference for writing queries. You do not need it for this page. From now on, every `prisma` command ends with the line `Prisma agent skills are out of date`. You can ignore it, because it does not change what the command does. Agent skills are instruction files that AI coding tools read, and the line appears because your project has none yet. To add them and stop the line, run [`npx prisma@latest init`](https://www.prisma.io/docs/cli/init). In Prisma ORM 8, `init` adds the skills and a `postinstall` script that keeps them up to date, and it leaves your contract and your `.env` alone. `orm init` is the command that sets up Prisma ORM. ## 3. Set your database connection string [#3-set-your-database-connection-string] If you had no `.env`, `orm init` wrote one with a placeholder, `DATABASE_URL="mongodb://user:password@localhost:27017/mydb"`. Set `DATABASE_URL` in `.env` to the connection string of the database your app already uses: ```text title=".env" DATABASE_URL="mongodb://username:password@host:27017/database" ``` The part after the last `/`, and before any `?`, is the name of the database. `orm init` wrote `src/prisma/db.ts`, and you do not need to change it: ```typescript 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({ contractJson, url: process.env['DATABASE_URL']!, }); ``` The first line loads `.env`, so every file that imports `db` reads `DATABASE_URL` from there. The two `contract` files it imports are written by `contract emit` in step 5. ## 4. Describe your collections in the contract [#4-describe-your-collections-in-the-contract] Prisma ORM cannot read a MongoDB database to write the contract for you, so you write it yourself. Describe only the collections that your code reads and writes through Prisma ORM. The other collections stay as they are. The example contract in `src/prisma/contract.prisma` describes a `users` collection and a `posts` collection: ```prisma title="src/prisma/contract.prisma" // use prisma-8 model User { id ObjectId @id @map("_id") email String @unique username String? 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") } ``` Keep the first line, because `contract emit` reads only `.prisma` files that start with it. `@@map("users")` names the collection that stores the model. MongoDB stores the identifier of every document in `_id`. On MongoDB, `contract emit` names each field in `contract.json` by the name in its `@map`, so in queries and in results you use `_id`, not `id`. The same goes for any other field with `@map`. Change the models to match your documents: one model for each collection, with one field for each field of its documents. [Data modeling](https://www.prisma.io/docs/orm/data-modeling) lists the field types. ## 5. Generate the files your code imports [#5-generate-the-files-your-code-imports] `contract emit` takes the place of `prisma generate`, and you run it after every change to the contract: #### bun ```bash bunx prisma contract emit ``` #### pnpm ```bash pnpm prisma contract emit ``` #### yarn ```bash yarn prisma contract emit ``` #### npm ```bash npx prisma contract emit ``` The command writes `src/prisma/contract.json` and `src/prisma/contract.d.ts`, and `db.ts` imports both of them. Commit them, because your app cannot run without them. ## 6. Query a collection with `db.orm` [#6-query-a-collection-with-dborm] `db.orm` queries your models, the way Prisma Client did in earlier Prisma ORM versions. On MongoDB you reach a model by the name of its collection, which is the name in `@@map`. So the `User` model is `db.orm.users`. Create `script.ts` with the code below, and put your own names in it: replace `users` with the name of one of your collections, and replace `email` and `existing@example.com` with a field and a value from its documents. ```typescript 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: #### bun ```bash bunx tsx script.ts ``` #### pnpm ```bash pnpm dlx tsx script.ts ``` #### yarn ```bash yarn dlx tsx script.ts ``` #### npm ```bash npx tsx script.ts ``` ```text no-copy { username: null, _id: '6abca6a1e7a9bb8d8c716f65', email: 'existing@example.com', name: 'Existing User' } ``` The document has no `username` field, and `username` is optional in the contract, so the result shows it as `null`. If no document matches, the script prints `null`. ## 7. Query a collection with a pipeline [#7-query-a-collection-with-a-pipeline] `db.query` builds a MongoDB aggregation pipeline on a collection, which it names as it is stored in MongoDB. `.build()` returns the pipeline, and `runtime.query()` runs it, where `runtime` is the object that `await db.runtime()` returns. Replace `users`, `email`, and the value with your own again. Replace `script.ts` with this version: ```typescript title="script.ts" import { db } from "./src/prisma/db"; async function main() { const runtime = await db.runtime(); const query = db.query .from("users") .match((fields) => fields.email.eq("existing@example.com")) .project("email", "name") .build(); const rows = await runtime.query(query); console.log(rows); await db.close(); } main().catch((error) => { console.error(error); process.exit(1); }); ``` Run it again: #### bun ```bash bunx tsx script.ts ``` #### pnpm ```bash pnpm dlx tsx script.ts ``` #### yarn ```bash yarn dlx tsx script.ts ``` #### npm ```bash npx tsx script.ts ``` ```text no-copy [ { email: 'existing@example.com', name: 'Existing User', _id: '6abca6a1e7a9bb8d8c716f65' } ] ``` ## 8. Next steps [#8-next-steps] When you change `src/prisma/contract.prisma`, run `npx prisma contract emit` again. You can read and write documents in collections that already exist without a migration. Use [`migration plan`](https://www.prisma.io/docs/cli/migration-plan) when you want Prisma ORM to create or change collections and indexes. ## Related pages - [`Add Prisma ORM to an existing PostgreSQL database`](https://www.prisma.io/docs/prisma-orm/add-to-existing-project/postgresql): Add Prisma ORM to an app whose PostgreSQL database already has tables.