Files
turbostarter/.context/turbostarter-framework-context/sections/web/database/client.md
Alejandro Gutiérrez 3527e732d4 feat: turbostarter boilerplate
Production-ready Next.js boilerplate with:
- Runtime env validation (fail-fast on missing vars)
- Feature-gated config (S3, Stripe, email, OAuth)
- Docker + Coolify deployment pipeline
- PostgreSQL + pgvector, MinIO S3, Better Auth
- TypeScript strict mode (no ignoreBuildErrors)
- i18n (en/es), AI modules, billing, monitoring

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:01:55 +01:00

2.6 KiB

title, description, url
title description url
Database client Use database client to interact with the database. /docs/web/database/client

Database client

The database client is an export of the Drizzle client. It is automatically typed by Drizzle based on the schema and is exposed as the db object from the database package (@turbostarter/db) in the monorepo.

This guide covers how to initialize the client and also basic operations, such as querying, creating, updating, and deleting records. To learn more about the Drizzle client, check out the official documentation.

Initializing the client

Pass the validated DATABASE_URL to the client to initialize it.

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";

import { env } from "../env";

const client = postgres(env.DATABASE_URL);
export const db = drizzle(client);

Now it's exported from the @turbostarter/db package and can be used across the codebase (server-side).

Querying data

To query data, you can use the db object and its methods:

import { eq } from "@turbostarter/db";
import { db } from "@turbostarter/db/server";
import { customer } from "@turbostarter/db/schema";

export const getCustomerByUserId = async (userId: string) => {
  const [data] = await db
    .select()
    .from(customer)
    .where(eq(customer.userId, userId));

  return data ?? null;
};

Mutating data

You can use the exported utilities to mutate data. Insert, update or delete records in fast and fully type-safe way:

import { eq } from "@turbostarter/db";
import { db } from "@turbostarter/db/server";
import { customer } from "@turbostarter/db/schema";

export const upsertCustomer = (data: InsertCustomer) => {
  return db.insert(customer).values(data).onConflictDoUpdate({
    target: customer.userId,
    set: data,
  });
};