--- title: Schema migration with Neon Postgres and Prisma ORM subtitle: Set up Neon Postgres and run migrations for your Javascript project using Prisma ORM enableTableOfContents: true updatedOn: '2025-06-30T11:30:21.910Z' --- [Prisma](https://www.prisma.io/) is an open-source ORM for Node.js and Typescript, known for its ease of use and focus on type safety. It supports many databases, including Postgres, and provides a robust system for managing database schemas and migrations. This guide walks you through using `Prisma` ORM with a `Neon` Postgres database in a Javascript project. We'll create a Node.js application, set up Prisma, and show how to run migrations using Prisma. ## Prerequisites To follow along with this guide, you will need: - A Neon account. If you do not have one, sign up at [Neon](https://neon.tech). Your Neon project comes with a ready-to-use Postgres database named `neondb`. We'll use this database in the following examples. - [Node.js](https://nodejs.org/) and [npm](https://www.npmjs.com/) installed on your local machine. We'll use Node.js to build and test the application locally. ## Setting up your Neon database ### Initialize a new project 1. Log in to the Neon Console and navigate to the [Projects](https://console.neon.tech/app/projects) section. 2. Select an existing project or click the `New Project` button to create a new one. ### Retrieve your Neon database connection string You can find your Neon database connection string by clicking the **Connect** button on your **Project Dashboard**. It should look similar to this: ```bash postgresql://alex:AbC123dEf@ep-cool-darkness-123456.us-east-2.aws.neon.tech/dbname?sslmode=require&channel_binding=require ``` Keep your connection string handy for later use. ## Setting Up the Node application ### Create a new Node project We'll create a simple catalog, with API endpoints that query the database for authors and a list of their books. Run the following command in your terminal to set up a new project using `Express.js`: ```bash mkdir neon-prisma-guide && cd neon-prisma-guide npm init -y && touch .env index.js npm pkg set type="module" && npm pkg set scripts.start="node index.js" npm install express ``` To use the Prisma ORM for making queries, install the `@prisma/client` package and the Prisma CLI. The CLI is only needed as a development dependency to generate the Prisma Client for the given schema. ```bash npm install @prisma/client && npm install prisma --save-dev npx prisma init ``` These commands create a new `prisma` folder in your project with a `schema.prisma` file, where we will define the database schema for our application. ### Configure Prisma to Use Neon Database Open the `prisma/schema.prisma` file and update the `datasource db` block with your Neon database connection details: ```prisma datasource db { provider = "postgresql" url = env("DATABASE_URL") } ``` Add the `DATABASE_URL` environment variable to your `.env` file, which you'll use to connect to your Neon database. Use the connection string that you obtained from the Neon Console earlier: ```bash # .env DATABASE_URL=NEON_DATABASE_CONNECTION_STRING ``` ### Define the Database schema In the `prisma/schema.prisma` file, add the following model definitions: ```prisma model Author { @@map("authors") id Int @id @default(autoincrement()) name String bio String? createdAt DateTime @default(now()) @map("created_at") books Book[] } model Book { @@map("books") id Int @id @default(autoincrement()) title String authorId Int @map("author_id") createdAt DateTime @default(now()) @map("created_at") author Author @relation(fields: [authorId], references: [id]) } ``` Two models are defined above: `Author`, which contains information about authors, and `Book`, for details about published books. The `Book` model includes a foreign key that references the `Author` model. ### Generate Prisma client and run migrations To create and apply migrations based on your schema, run the following command in the terminal: ```bash npx prisma migrate dev --name init ``` This command generates migration files written in SQL corresponding to our schema definitions and applies them to create the tables in your Neon database. We used the `--name` flag to name the migration. The command also generates a Prisma Client that is aware of our schemas: ```javascript import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); ``` We'll use this client later to interact with the database. ### Seed the Database To test that the application works, we need to add some example data to our tables. Create a `seed.js` file in your project and add the following code to it: ```javascript // seed.js import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); const seed = async () => { const authors = [ { name: 'J.R.R. Tolkien', bio: 'The creator of Middle-earth and author of The Lord of the Rings.', books: { create: [ { title: 'The Hobbit' }, { title: 'The Fellowship of the Ring' }, { title: 'The Two Towers' }, { title: 'The Return of the King' }, ], }, }, { name: 'George R.R. Martin', bio: 'The author of the epic fantasy series A Song of Ice and Fire.', books: { create: [{ title: 'A Game of Thrones' }, { title: 'A Clash of Kings' }], }, }, { name: 'J.K. Rowling', bio: 'The creator of the Harry Potter series.', books: { create: [ { title: "Harry Potter and the Philosopher's Stone" }, { title: 'Harry Potter and the Chamber of Secrets' }, ], }, }, ]; for (const author of authors) { await prisma.author.create({ data: author, }); } }; async function main() { try { await seed(); console.log('Seeding completed'); } catch (error) { console.error('Error during seeding:', error); process.exit(1); } finally { await prisma.$disconnect(); } } main(); ``` Run the seed script to populate the database with the initial data: ```bash node seed.js ``` You should see the `Seeding completed` message in the terminal, indicating that the seed data was inserted into the database. ### Implementing the API Endpoints Now that the database is set up and populated with data, we can implement the API to query the authors and their books. We'll use [Express](https://expressjs.com/), which is a minimal web application framework for Node.js. Create an `index.ts` file at the project root, and add the following code to set up your Express server: ```javascript import express from 'express'; import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); const app = express(); const port = process.env.PORT || 3000; app.get('/', async (req, res) => { res.send('Hello World! This is a book catalog.'); }); app.get('/authors', async (req, res) => { const authors = await prisma.author.findMany(); res.json(authors); }); app.get('/books/:author_id', async (req, res) => { const authorId = parseInt(req.params.author_id); const books = await prisma.book.findMany({ where: { authorId: authorId, }, }); res.json(books); }); // Start the server app.listen(port, () => { console.log(`Server running on http://localhost:${port}`); }); ``` This code sets up a simple API with two endpoints: `/authors` and `/books/:authorId`. The `/authors` endpoint returns a list of all the authors, and the `/books/:authorId` endpoint returns a list of books written by the specific author with the given `authorId`. Run the application using the following command: ```bash npm run start ``` This will start the server at `http://localhost:3000`. Navigate to `http://localhost:3000/authors` and `http://localhost:3000/books/1` in your browser to check that the API works as expected. ## Migration after a schema change To demonstrate how to execute a schema change, we'll add a new column to the `authors` table, listing the country of origin for each author. ### Update the Prisma model Modify the `Author` model in the `prisma/schema.prisma` file to add the new `country` field: ```prisma model Author { @@map("authors") id Int @id @default(autoincrement()) name String bio String? country String? createdAt DateTime @default(now()) @map("created_at") books Book[] } ``` ### Generate and apply the migration Run the following command to generate a new migration and apply it to the database: ```bash npx prisma migrate dev --name add-country ``` This command generates a new migration file to add the new field and applies it to the database. It also updates the Prisma client to reflect the change in the schema. ### Verify the migration To verify the migration, run the application again: ```bash npm run start ``` You can navigate to `http://localhost:3000/authors` in your browser to check that each author entry has a `country` field, currently set to `null`. ## Conclusion In this guide, we set up a new Javascript project using `Express.js` and `Prisma` ORM and connected it to a `Neon` Postgres database. We created a schema for the database, generated and ran migrations, and implemented API endpoints to query the database. ## Source code You can find the source code for the application described in this guide on GitHub. Migrations with Neon and Prisma ## Resources For more information on the tools used in this guide, refer to the following resources: - [Prisma ORM](https://www.prisma.io/) - [Express.js](https://expressjs.com/)