Easy database access in Express servers
Build high-performance and type-safe Express servers with Prisma's developer-friendly database tools: The world's most popular TypeScript ORM and the first serverless database without cold starts.
Why Express and Prisma?
Built for high-performance web apps
Built on unikernels, Prisma Postgres runs on bare metal servers for peak performance and infinite scalability.
Middleware-friendly
Prisma integrates seamlessly with Express's middleware pattern, making it easy to add database operations to your request processing pipeline.
Serverless, without cold starts
The first serverless database with pay-as-you-go pricing, no infrastructure management, and zero cold starts.
Built-in global caching
Add a cache strategy to any database query and its results will be cached close to your users for peak performance and UX.
Helpful communities
Both Express and Prisma have vibrant communities where you find support, fun events and amazing developers.
Lightweight & flexible architecture
Express's minimalist approach pairs perfectly with Prisma's focused database toolkit, giving you a lean stack that's powerful without unnecessary bloat.
How Prisma and Express fit together
Basic CRUD Routes
Prisma simplifies building REST APIs in Express by providing an intuitive and type-safe way of sending queries. Instead of writing raw SQL, you can create, read, update, and delete records with JavaScript methods that map directly to your schema.
This approach reduces boilerplate while giving you full type safety and autocompletion in your editor.
// src/routes/users.ts
import express from 'express';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '../generated/client';
const router = express.Router();
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({ adapter });
router.get('/', async (req, res) => {
const users = await prisma.user.findMany();
res.json(users);
});
router.post('/', async (req, res) => {
const { name, email } = req.body;
const newUser = await prisma.user.create({ data: { name, email } });
res.status(201).json(newUser);
});
export default router;Authentication Middleware
Authentication is a common requirement for most Express applications. Prisma integrates seamlessly with JWT-based auth flows by providing type-safe database access for user verification.
This middleware pattern demonstrates how to decode tokens, fetch user data from your database, and attach it to the request object for use in downstream route handlers while maintaining clean separation of concerns.
// src/middleware/auth.ts
import jwt from 'jsonwebtoken';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '../generated/client';
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({ adapter });
export const authenticate = async (req, res, next) => {
const token = req.headers.authorization?.split(' ')[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);
const user = await prisma.user.findUnique({
where: { id: decoded.userId },
select: { id: true, email: true, role: true }
});
req.user = user;
next();
};
import express from 'express';
const router = express.Router();
router.use(authenticate);Transactions
Database transactions are essential when multiple operations need to succeed or fail as a single unit. Prisma's transaction API makes this complex pattern accessible in Express apps by wrapping related operations in a single atomic function.
This ensures data integrity when creating orders with line items, managing inventory, or handling any scenario where partial updates would leave your database in an inconsistent state.
// src/routes/orders.ts
import express from 'express';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '../generated/client';
const router = express.Router();
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({ adapter });
router.post('/', async (req, res) => {
const { userId, items } = req.body;
const result = await prisma.$transaction(async (tx) => {
const order = await tx.order.create({ data: { userId, status: 'PENDING' } });
const orderItems = await Promise.all(
items.map(item => tx.orderItem.create({
data: { orderId: order.id, productId: item.productId, quantity: item.quantity }
}))
);
return { order, orderItems };
});
res.status(201).json(result);
});
export default router;Data model & migrations
When using Prisma, you can use the Prisma schema to model your data in a declarative way and auto-generate migration files to make changes to your database schema.
Using Prisma Migrate, you can generate a customizable SQL migration file that will execute the required changes against the database.
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}Featured Prisma & Express community examples
Express & Prisma ORM Starter Kit
A ready-to-run example project for a REST API with Prisma ORM.
Master Prisma ORM in Express: Step by Step Video Tutorial
Learn how to integrate Prisma ORM in an Express app in this step-by-step video tutorial.
How to Build a REST API with Prisma and PostgreSQL
A comprehensive tutorial for building REST APIs with Express, Prisma and PostgreSQL.