# Add Prisma ORM and MongoDB to an existing app (/docs/prisma-orm/quickstart/existing-app/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 you already have, create the collections in an empty MongoDB database, run a first query, and apply a first migration. Location: Prisma ORM > Quickstart > Existing App > Add Prisma ORM and MongoDB to an existing app This page uses MongoDB. [Use PostgreSQL instead](https://www.prisma.io/docs/prisma-orm/quickstart/existing-app/postgresql). Use this page when you already have an app and its database has no collections yet. By the end, your app has one model, the database has a collection for it, and a script writes and reads a document. You also change the model once and apply the change to the database with a migration. If your database already has collections, follow [Add Prisma ORM to an existing MongoDB database](https://www.prisma.io/docs/prisma-orm/add-to-existing-project/mongodb) instead. > [!NOTE] > Using Prisma ORM 7? > > Prisma ORM 8 is 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). ## Prerequisites [#prerequisites] * A project directory with a `package.json`, on Node.js 22.18 or newer on the 22 line, 24.11 or newer on the 24 line, or 26 or newer (24 recommended). [Supported versions](https://www.prisma.io/docs/orm/supported-versions) has every floor. * A way to run a TypeScript file. This page uses `tsx`. If your project does not have it, run `npm install --save-dev tsx typescript`. * An empty MongoDB database, version 8.0 or newer. A single `mongod` server is enough. You need a replica set only for transactions and change streams. ## 1. Add Prisma ORM to the project [#1-add-prisma-orm-to-the-project] 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 packages, writes the files, and ends with the summary below. In `package.json`, it adds the packages with their current version numbers, and a `contract:emit` script that runs `prisma contract emit`. If your project already has a `tsconfig.json` or a `.gitignore`, the command edits that file and keeps the rest of it. ```text no-copy │ target: mongodb │ authoring: psl │ schema: src/prisma/contract.prisma written ├─ src/prisma/contract.prisma ├─ prisma.config.ts ├─ src/prisma/db.ts ├─ prisma-8.md ├─ .env.example ├─ .env ├─ tsconfig.json ├─ .gitignore ├─ .gitattributes └─ package.json installed ├─ @prisma/orm-mongo ├─ dotenv ├─ prisma@latest (dev) ├─ @types/node (dev) └─ @prisma/cli-engine@0.9.0 (dev) ✔ Done. Open prisma-8.md to get started. ``` You work with three of these files: * `src/prisma/contract.prisma` holds your models. It is what `schema.prisma` was in earlier Prisma ORM versions, and Prisma ORM 8 calls it the contract. The summary lists it as `schema`. * `prisma.config.ts` tells the `prisma` commands where the contract is and which database to connect to. * `src/prisma/db.ts` is the file your app imports to run queries. You do not need `prisma-8.md` for this page. It is a short reference for writing queries. `.gitattributes` marks the files that Prisma ORM generates, so that GitHub collapses them in pull request diffs. `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 { contractFromJson } from '@prisma/orm-mongo/static'; import type { Contract } from './contract.d'; import contractJson from './contract.json' with { type: 'json' }; export const contract = contractFromJson(contractJson); export const db = mongo({ contract, 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 4. 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. ## 2. Set the connection string [#2-set-the-connection-string] If you had no `.env`, `orm init` wrote one with a placeholder, `DATABASE_URL="mongodb://user:password@localhost:27017/mydb"`. Open `.env` and set `DATABASE_URL` to the connection string of your database: ```bash title=".env" DATABASE_URL="mongodb://username:password@host:27017/database" ``` The part after the last `/`, and before any `?`, is the name of the database. If you have no MongoDB server yet, [A database on your machine](https://www.prisma.io/docs/prisma-orm/local-database#mongodb) shows how to run one in Docker. `orm init` added `.env` to `.gitignore`, so the password stays out of version control. ## 3. Write one model [#3-write-one-model] `orm init` wrote a starter contract with a `User` and a `Post` model. Replace the contents of `src/prisma/contract.prisma` with one model: ```prisma title="src/prisma/contract.prisma" // use prisma-8 model User { id ObjectId @id @map("_id") email String @unique name String? @@map("users") } ``` 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`, and `@map("_id")` stores the `id` field there. In queries and in their results you use the field name, `id`, and Prisma ORM reads and writes `_id` for you. The same goes for any other field with `@map`. The file has no `datasource` or `generator` block. The connection string comes from `.env`, and `contract emit` in the next step takes the place of the generator. [Data modeling](https://www.prisma.io/docs/orm/data-modeling) covers field types and relations. ## 4. Generate the files your code imports [#4-generate-the-files-your-code-imports] Run `contract emit` after every change to the contract. It takes the place of `prisma generate`. From here on, commands start with `npx prisma`, without `@latest`. That runs the version of Prisma ORM that `orm init` installed in your project: #### bun ```bash bunx prisma contract emit ``` #### pnpm ```bash pnpm prisma contract emit ``` #### yarn ```bash yarn prisma contract emit ``` #### npm ```bash npx prisma contract emit ``` ```text no-copy ✔ Resolving contract source... ✔ Emitting contract... │ contract: src/prisma/contract.json │ types: src/prisma/contract.d.ts ✔ Emitted contract.json and contract.d.ts ``` The command writes `contract.json` and `contract.d.ts` next to the contract. Commit both files, because `db.ts` imports them. ## 5. Create the collection [#5-create-the-collection] #### bun ```bash bunx prisma db init ``` #### pnpm ```bash pnpm prisma db init ``` #### yarn ```bash yarn prisma db init ``` #### npm ```bash npx prisma db init ``` ```text no-copy ✔ Introspecting database schema ✔ Planning migration ✔ Initialising database across spaces │ contract: src/prisma/contract.json │ database: mongodb://127.0.0.1:27029/app1 ✔ Applied 2 operation(s) across 1 contract space App space ├─ Create collection users ├─ Create index on users (email:1) └─ marker 778f20d8e17f0107ce8a9f84577123728a700cb38e1b2b2689949ae658d3776e ✔ Advanced ref "db" → 778f20d8e17f0107ce8a9f84577123728a700cb38e1b2b2689949ae658d3776e ``` `db init` creates the collections and indexes your contract declares. It also gives each collection a validator, which is the MongoDB rule that lists the fields a document may have. MongoDB then rejects a document with a field that the contract does not declare. The output names two more things it wrote: * The `marker` is a record in the database. It holds the hash of your contract, which is the long text in the output, so that later commands can tell which version of the contract the database has. * The `db` ref is the file `migrations/app/refs/db.json` in your project. It holds the same hash. The line `Advanced ref "db"` means that the command wrote this file. `migration plan` in step 7 reads it to find out which contract your development database has. You can ignore the word `space` in the output, because all your migrations are in `migrations/app/`. Commit the `migrations/` directory together with your code, because `migration plan` reads it on every later change. If the command fails with `DRIVER.CONNECTION_FAILED`, the value of `DATABASE_URL` in `.env` is wrong or the database is not reachable. ## 6. Write and read a document [#6-write-and-read-a-document] Create `script.ts` in the root of your project: ```typescript title="script.ts" import { db } from "./src/prisma/db"; async function main() { const created = await db.orm.users.create({ email: "alice@example.com", name: "Alice", }); console.log("Created:", created); const users = await db.orm.users.all(); console.log("All users:", users); await db.close(); } main().catch((error) => { console.error(error); process.exit(1); }); ``` `db.orm` queries your models, the way Prisma Client did in earlier Prisma ORM versions. You reach this model as `db.orm.users`, because on MongoDB you address a model by the name of its collection, which is the name in `@@map`. `await db.close()` closes the database connections, and without it the script keeps running after the last query. `create` takes the fields directly, with no `data` wrapper, and `.all()` does what `findMany()` did. 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 Created: { id: '6abc2ce7b04f66be2c85564d', email: 'alice@example.com', name: 'Alice' } All users: [ { id: '6abc2ce7b04f66be2c85564d', email: 'alice@example.com', name: 'Alice' } ] ``` The script passes no identifier, and the new document gets one, returned as a string in `id`. To find a document by it, filter on `id`, as in `db.orm.users.where({ id: created.id }).first()`. In your app, import `db` from `src/prisma/db.ts` the same way. [Reading data](https://www.prisma.io/docs/orm/fundamentals/reading-data) and [Writing data](https://www.prisma.io/docs/orm/fundamentals/writing-data) show the other queries. ## 7. Change the model and apply the change [#7-change-the-model-and-apply-the-change] Add a field to the model: ```prisma title="src/prisma/contract.prisma" // use prisma-8 model User { id ObjectId @id @map("_id") email String @unique name String? phone String? // [!code ++] @@map("users") } ``` Generate the files again, then plan a migration. `migration plan` compares the new contract with the last one you applied to your development database, and writes the difference into a new directory under `migrations/app/`. `--name` sets the end of the directory's name, after the date and time. #### bun ```bash bunx prisma contract emit bunx prisma migration plan --name add_user_phone ``` #### pnpm ```bash pnpm prisma contract emit pnpm prisma migration plan --name add_user_phone ``` #### yarn ```bash yarn prisma contract emit yarn prisma migration plan --name add_user_phone ``` #### npm ```bash npx prisma contract emit npx prisma migration plan --name add_user_phone ``` ```text no-copy │ contract: src/prisma/contract.json │ migrations: migrations/app │ name: add_user_phone ✔ Planned baseline (2 operation(s)) + 1 operation(s) migrations/app/20260929T2126_baseline ├─ Create collection users └─ Create index on users (email:1) migrations/app/20260929T2127_add_user_phone └─ Update validator on users from: 778f20d8e17f0107ce8a9f84577123728a700cb38e1b2b2689949ae658d3776e to: f0035d1963f127dc8ee91e154d51810755ee91b090659127881d1ab31e03e3cf baseline: migrations/app/20260929T2126_baseline app space: migrations/app/20260929T2127_add_user_phone ``` The output continues with a preview of the MongoDB commands. The first plan in a project writes two directories. The baseline holds the steps that create the collection and the index, which `db init` already ran on your development database. The second directory is your change. Your change updates the validator, so that a document may have the `phone` field. Apply the migration: #### bun ```bash bunx prisma db migrate --advance-ref db ``` #### pnpm ```bash pnpm prisma db migrate --advance-ref db ``` #### yarn ```bash yarn prisma db migrate --advance-ref db ``` #### npm ```bash npx prisma db migrate --advance-ref db ``` ```text no-copy ✔ Running migration plan across spaces │ migrations: migrations │ database: mongodb://127.0.0.1:27029/app1 ✔ Applied 1 migration(s) (1 operation(s)) across 1 contract space(s) App space ├─ Update validator on users └─ marker f0035d1963f127dc8ee91e154d51810755ee91b090659127881d1ab31e03e3cf ✔ Advanced ref "db" → f0035d1963f127dc8ee91e154d51810755ee91b090659127881d1ab31e03e3cf ``` `db migrate` runs only the migrations that the database does not have yet, so here it runs only your change. `--advance-ref db` writes the new hash to the `db` ref, so that the next `migration plan` contains only your next change. Pass it every time you apply a migration to your development database. Commit the `migrations/` directory again. To apply the migrations to any other database, such as production, pass its connection string. Leave out `--advance-ref`, because the `db` ref describes your development database: #### bun ```bash bunx prisma db migrate --db "$PRODUCTION_DATABASE_URL" ``` #### pnpm ```bash pnpm prisma db migrate --db "$PRODUCTION_DATABASE_URL" ``` #### yarn ```bash yarn prisma db migrate --db "$PRODUCTION_DATABASE_URL" ``` #### npm ```bash npx prisma db migrate --db "$PRODUCTION_DATABASE_URL" ``` `db migrate` runs the migrations that this database does not have yet. An empty database has no marker, so there `db migrate` runs the baseline and then your change. Every later change follows the same four steps, which take the place of `prisma migrate dev`: edit `src/prisma/contract.prisma`, run `npx prisma contract emit`, run `npx prisma migration plan --name `, and run `npx prisma db migrate --advance-ref db`. ## Next steps [#next-steps] * [Data modeling](https://www.prisma.io/docs/orm/data-modeling) for relations, more field types, and indexes. * [Generating a migration](https://www.prisma.io/docs/orm/migrations/generating-a-migration) for what a migration directory contains and how to edit it. * [`db update`](https://www.prisma.io/docs/cli/db-update) to apply a contract change to a development database without writing migration files. ## Related pages - [`Add Prisma ORM and PostgreSQL to an existing app`](https://www.prisma.io/docs/prisma-orm/quickstart/existing-app/postgresql): Add Prisma ORM to an app you already have, create the tables in an empty PostgreSQL database, run a first query, and apply a first migration.