Docs/Guides/Next.js

Connect with Next.js

Build full-stack applications with Next.js and PhoenixDB.

Choose Your Approach

Raw SQL (pg)

Direct PostgreSQL queries with node-postgres

Prisma ORM

Type-safe database access with Prisma

Option 1: Raw SQL with pg

Install

npm install pg

Create Database Helper

lib/db.ts
import { Pool } from 'pg';

const pool = new Pool({
  connectionString: process.env.DATABASE_URL,
  ssl: { rejectUnauthorized: false },
  max: 10,
});

export async function query<T = any>(
  text: string,
  params?: any[]
): Promise<T[]> {
  const client = await pool.connect();
  try {
    const result = await client.query(text, params);
    return result.rows;
  } finally {
    client.release();
  }
}

export default pool;

Server Component Example

app/users/page.tsx
import { query } from '@/lib/db';

interface User {
  id: number;
  name: string;
  email: string;
}

export default async function UsersPage() {
  const users = await query<User>('SELECT * FROM users ORDER BY id');

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name} - {user.email}</li>
        ))}
      </ul>
    </div>
  );
}

API Route Example

app/api/users/route.ts
import { NextResponse } from 'next/server';
import { query } from '@/lib/db';

export async function GET() {
  const users = await query('SELECT * FROM users');
  return NextResponse.json(users);
}

export async function POST(request: Request) {
  const { name, email } = await request.json();
  
  const result = await query(
    'INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *',
    [name, email]
  );
  
  return NextResponse.json(result[0], { status: 201 });
}

Option 2: Prisma ORM

Install Prisma

npm install prisma @prisma/client
npx prisma init

Configure schema.prisma

prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        Int      @id @default(autoincrement())
  name      String
  email     String   @unique
  createdAt DateTime @default(now())
}

Create Prisma Client

lib/prisma.ts
import { PrismaClient } from '@prisma/client';

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined;
};

export const prisma = globalForPrisma.prisma ?? new PrismaClient();

if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;

Usage in Server Components

app/users/page.tsx
import { prisma } from '@/lib/prisma';

export default async function UsersPage() {
  const users = await prisma.user.findMany({
    orderBy: { id: 'asc' }
  });

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name} - {user.email}</li>
        ))}
      </ul>
    </div>
  );
}

Environment Variable

Add to your .env.local:

DATABASE_URL="postgresql://postgres:YOUR_PASSWORD@abc123.server1.phoenixdb.space:5432/mydb?sslmode=require"

Important: Never commit .env.local to version control. Add it to your .gitignore.