Table of Contents
- Introduction
- Why Databases Matter in Full-Stack React/Next.js
- Supported Databases: PostgreSQL, MySQL, MongoDB
- Choosing the Right ORM: Prisma vs Drizzle vs Raw Queries
- Setting Up Environment Variables for Database Connections
- Connecting PostgreSQL with Prisma
- Connecting MySQL with Prisma
- Integrating MongoDB with Mongoose
- Using Drizzle ORM with Next.js (Type-Safe SQL Alternative)
- Using Server Actions to Securely Access Databases
- Best Practices for Secure DB Access in Next.js
- Conclusion
1. Introduction
Modern full-stack applications demand seamless integration with databases. With Next.js evolving to support both server-side and client-side rendering — and now React Server Components (RSC) and Server Actions — securely connecting to and managing databases has never been more crucial.
This module covers how to connect PostgreSQL, MySQL, and MongoDB in a Next.js application using tools like Prisma, Drizzle ORM, and Mongoose while maintaining best practices for security, environment management, and performance.
2. Why Databases Matter in Full-Stack React/Next.js
React (via Next.js) has matured into a robust framework for full-stack development:
- Server components let you query databases directly during rendering.
- Server Actions allow mutations without API routes.
- API routes are still relevant in some cases but are no longer mandatory.
Next.js bridges the gap between backend and frontend, making it essential to understand how database interactions work in this hybrid environment.
3. Supported Databases: PostgreSQL, MySQL, MongoDB
You can use any database in a Next.js app, but the most common choices are:
- PostgreSQL – SQL-based, ideal for structured data.
- MySQL – Another powerful SQL database, widely supported.
- MongoDB – NoSQL, flexible document structure.
ORMs make database usage simpler, abstracting SQL or database-specific queries.
4. Choosing the Right ORM: Prisma vs Drizzle vs Raw Queries
Prisma
- Auto-generates types and queries.
- Schema-based.
- Works great with PostgreSQL, MySQL.
Drizzle ORM
- Lightweight and type-safe.
- Perfect for full type inference with SQL syntax.
- Works well with server components.
Mongoose
- Ideal for MongoDB.
- Schema-based ODM (Object Document Mapper).
Raw SQL queries are possible but not recommended unless performance is critical.
5. Setting Up Environment Variables for Database Connections
Always store your database credentials securely in a .env.local
file:
envCopyEditDATABASE_URL="postgresql://user:password@localhost:5432/mydb"
Next.js exposes server-only env vars by default in server components. Avoid using them in client components.
6. Connecting PostgreSQL with Prisma
Step 1: Install Prisma and Initialize
bashCopyEditnpm install prisma --save-dev
npx prisma init
Step 2: Configure prisma/schema.prisma
prismaCopyEditdatasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
Step 3: Define Models and Migrate
prismaCopyEditmodel User {
id Int @id @default(autoincrement())
email String @unique
name String
}
Then run:
bashCopyEditnpx prisma migrate dev --name init
Step 4: Use in Server Component or Server Action
tsCopyEditimport { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export async function getUsers() {
return await prisma.user.findMany();
}
7. Connecting MySQL with Prisma
Just change the datasource in schema.prisma
:
prismaCopyEditdatasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
Then follow the same flow as above — models, migrations, and usage.
8. Integrating MongoDB with Mongoose
Step 1: Install Mongoose
bashCopyEditnpm install mongoose
Step 2: Connect to MongoDB
tsCopyEditimport mongoose from 'mongoose';
export async function connectMongo() {
if (mongoose.connections[0].readyState) return;
await mongoose.connect(process.env.MONGODB_URI!);
}
Step 3: Create a Model
tsCopyEditimport { Schema, model, models } from 'mongoose';
const userSchema = new Schema({
name: String,
email: String
});
export const User = models.User || model('User', userSchema);
Use the User
model in server components or API routes.
9. Using Drizzle ORM with Next.js (Type-Safe SQL Alternative)
Step 1: Install Drizzle ORM for PostgreSQL
bashCopyEditnpm install drizzle-orm pg
Step 2: Define Tables and Connect
tsCopyEditimport { pgTable, serial, varchar } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 255 }),
});
Step 3: Run Queries
tsCopyEditimport { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
import { users } from './schema';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const db = drizzle(pool);
export const getUsers = async () => {
return db.select().from(users);
};
Drizzle is ideal for projects prioritizing types, performance, and minimal abstractions.
10. Using Server Actions to Securely Access Databases
Next.js 14+ lets you write server functions like this:
tsCopyEdit'use server';
import { prisma } from '@/lib/prisma';
export async function createUser(formData: FormData) {
const name = formData.get('name') as string;
const email = formData.get('email') as string;
await prisma.user.create({
data: { name, email },
});
}
These actions are server-only, removing the need for manual API routes and CSRF protection.
11. Best Practices for Secure DB Access in Next.js
- Never expose DB credentials to the client.
- Use
.env.local
for dev secrets; never commit.env
files. - Use Server Actions or React Server Components to interact with the DB.
- Consider connection pooling for production (e.g., with PgBouncer or Prisma Data Proxy).
- Use middleware and RBAC (Role-Based Access Control) for sensitive operations.
12. Conclusion
Database connectivity is at the heart of full-stack Next.js apps. With options like Prisma, Drizzle, and Mongoose, you can seamlessly integrate PostgreSQL, MySQL, or MongoDB into your stack.
Using the latest features like Server Actions, you can build secure and efficient data interactions without traditional API route overhead. And by following best practices, you’ll ensure your apps scale and remain secure in production.