Skip to main content
If you want the thinnest path from a Next.js app to PostgreSQL, use pg. You keep direct SQL, avoid ORM abstractions, and still get DBHost for pooling, backups, and day-to-day database management. This quickstart keeps to the shortest useful path: one DBHost database, one shared pool, and one server-side query. Best fit: Teams that want plain SQL, minimal dependencies, and full control over query text. Not for: Teams that want ORM models, generated clients, or schema tooling baked into the database layer. If you want to compare this path with Prisma or Drizzle, start with the Next.js + PostgreSQL guide.

What you need

  • A DBHost account and one active database
  • A Next.js app
  • Node.js 18 or later
  • The pg package installed in the app
Next.js Server Components run on the server, so your database credentials and SQL stay out of the client bundle when you query from server-only code.

1. Create a database in DBHost

Create a database from the dashboard, then copy the connection string from the database detail page.

2. Install pg

From your Next.js project:
npm install pg
npm install -D @types/pg

3. Point the app at DBHost

Add the DBHost connection string to .env.local or the environment file your app already uses:
DATABASE_URL="postgresql://uabc123_my_project:PASSWORD@db.dbhost.app:6432/uabc123_my_project?sslmode=verify-full"
Use the exact connection details from DBHost.

4. Create a simple table

With plain pg, you own the schema workflow. For a quickstart, the easiest path is to create one table from the DBHost SQL Explorer or any migration tool your team already uses:
CREATE TABLE IF NOT EXISTS projects (
  id bigserial PRIMARY KEY,
  name text NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now()
);
That gives the app something simple to query immediately.

5. Create one shared pool

Keep the pool in one reusable server-only file:
// app/lib/db.ts
import { Pool } from "pg";

const globalForPg = globalThis as unknown as {
  pool?: Pool;
};

export const pool =
  globalForPg.pool ??
  new Pool({
    connectionString: process.env.DATABASE_URL,
  });

if (process.env.NODE_ENV !== "production") {
  globalForPg.pool = pool;
}
That keeps development reloads from creating a new pool every time the file changes.

6. Query from a server component

// app/page.tsx
import { pool } from "./lib/db";

export default async function HomePage() {
  const result = await pool.query(
    `
      SELECT id, name, created_at
      FROM projects
      ORDER BY created_at DESC
      LIMIT 5
    `,
  );

  return (
    <main>
      <h1>Projects</h1>
      <ul>
        {result.rows.map((project) => (
          <li key={project.id}>{project.name}</li>
        ))}
      </ul>
    </main>
  );
}
That is enough to verify the database connection, pooled query path, and Next.js render path in one pass.

When DBHost helps most

  • You want a plain PostgreSQL client without running your own pooler
  • You want backups and password resets from the dashboard later
  • You want the option to automate database actions through the published CLI or REST API
  • You want PostgreSQL without turning database operations into a platform project

Next steps

Start for Free

Create a DBHost account and provision your first database.

Compare Next.js Paths

See when plain pg, Drizzle, or Prisma is the better fit for your app.
  • See the DBHost quickstart for the shortest path to your first database.
  • See the Next.js + PostgreSQL guide if you want to compare plain pg with Drizzle or Prisma.
  • See the CLI if you want to script database actions from your terminal.
  • See the API reference if your deployment pipeline already speaks HTTP.