Claude
Skills
Sign in
Back

netlify-database

Included with Lifetime
$97 forever

Guide for using Netlify Database — the GA managed Postgres product built into Netlify. Use when a project needs any kind of dynamic, structured, or relational data. Covers provisioning via @netlify/database, Drizzle ORM (@beta) setup, migrations, preview branching, and safe production data handling. Blobs is only for file/asset storage — any dynamic data belongs in the database.

Backend & APIs

What this skill does


# Netlify Database

**Netlify Database** is the managed Postgres product built into the Netlify platform. It is **GA** and is the default choice for any dynamic data in a Netlify project.

Install `@netlify/database` and Netlify auto-provisions a Postgres database for the site at deploy time. Each deploy preview gets its own isolated branch forked from production data. No Neon account, connection-string wiring, or claim flow — the database is a first-class Netlify primitive.

## Database vs Blobs

Use **Netlify Database** for anything dynamic:

- Any user-generated or app-generated records (posts, comments, orders, sessions, audit logs)
- Structured data that will grow, be queried, or be joined
- Key-value-style data read or written by application code at runtime

Use **Netlify Blobs** only for **file and asset storage**: images, documents, exports, uploads, cached binary artifacts. Do not use Blobs as a dynamic data store — reach for Database instead. See `netlify-blobs/SKILL.md`.

## CRITICAL: Install Drizzle from the `@beta` dist-tag

The Netlify Database adapter for Drizzle ORM currently only exists on the `beta` release line of `drizzle-orm`. Install **both** `drizzle-orm` and `drizzle-kit` from the `@beta` dist-tag:

```bash
npm install drizzle-orm@beta
npm install -D drizzle-kit@beta
```

The default `latest` versions do not include the `drizzle-orm/netlify-db` adapter and will fail. If `drizzle-kit generate` errors about being outdated, or the `drizzle-orm/netlify-db` import fails to resolve, the install is missing `@beta`.

The `@beta` tag only affects the installed version — imports are written as `drizzle-orm`, `drizzle-orm/pg-core`, and `drizzle-orm/netlify-db` without modification.

## CRITICAL: Use the Netlify CLI for database operations

The CLI ships a complete database surface under `netlify database` (alias: `netlify db`) that replaces hand-rolled scripts and direct API/UI work. Reach for these commands first before writing custom tooling. **Requires Netlify CLI 26.0.0+** — if a `netlify database` subcommand isn't recognized, run `npm install -g netlify-cli@latest`.

Full reference is in [Netlify CLI commands](#netlify-cli-commands-for-netlify-database) below.

## CRITICAL: Never apply migrations to a Netlify-hosted database

The only database you ever apply migrations to yourself is the **local development DB**. For any Netlify-hosted database — production or a deploy preview branch — **Netlify applies migrations automatically during the deploy**. Your job is to create migration files and commit them. The deploy does the rest.

This means:

- Use `netlify database migrations apply` for the local DB. Do NOT run `drizzle-kit migrate` against `NETLIFY_DB_URL` in any context.
- Do NOT run `drizzle-kit push` at all. Generate a migration and let the deploy apply it.
- Do NOT run raw DDL (`CREATE`, `ALTER`, `DROP`, `TRUNCATE`) via `netlify database connect`, `psql`, or any other direct connection. Schema changes go through migration files; out-of-band DDL drifts the migration history from the actual schema.
- Do NOT export `NETLIFY_DB_URL` from a preview or production context and run a client against it. Migrations drift the moment anything touches the schema out-of-band.

The one documented exception is a **one-time data import** during a provider switch — see `references/migration-from-extension.md`. Outside that specific flow, the rule is absolute: schema changes go through migration files, migration files get applied by the deploy.

## Not the legacy "Netlify DB" extension

The older **Netlify DB** extension (Beta) is **deprecated**. It is a separate product and must not be confused with Netlify Database. Do not recommend or install it for new projects.

| | Netlify Database (GA, recommended) | Netlify DB extension (deprecated Beta) |
|---|---|---|
| Package | `@netlify/database` | `@netlify/neon` |
| Env var | `NETLIFY_DB_URL` | `NETLIFY_DATABASE_URL` |
| Setup | `netlify database init` or install the package — auto-provisioned at deploy | Historically `netlify db init` on older CLI versions, with a claim into the user's Neon account; that flow is no longer reachable from the current CLI |
| Status | GA | Deprecated; new creation blocked as of April 2026 |

If an existing project is already using the `@netlify/neon` extension, keep it working and encourage the user to switch. See `references/legacy-extension.md` for recognition and coexistence, and `references/migration-from-extension.md` for the full switching process (also covers switching from other external Postgres providers).

## Provisioning

The fastest path is `netlify database init` — an interactive setup that installs `@netlify/database`, lets the user pick Drizzle or raw SQL, writes `drizzle.config.ts` if needed, scaffolds a starter migration, applies it locally, and runs a sample query end-to-end:

```bash
netlify database init           # interactive
netlify database init --yes     # accept defaults — for CI/agents
```

If you'd rather wire things up by hand, install the package directly:

```bash
npm install @netlify/database
```

Either way, presence of `@netlify/database` in the dependency tree triggers provisioning on the next deploy. A database can also be created manually from the Netlify UI before first deploy.

## Drizzle ORM (recommended path)

Drizzle is the recommended way to work with Netlify Database. Prefer Drizzle over writing raw SQL or hand-editing migration files — manual migrations are an edge case (see `references/migrations.md`).

### Install

```bash
npm install @netlify/database drizzle-orm@beta
npm install -D drizzle-kit@beta
```

### Schema file

Create `db/schema.ts`. Define all tables here using Drizzle's schema builder.

```typescript
// db/schema.ts
import { boolean, pgTable, serial, text, timestamp, varchar } from "drizzle-orm/pg-core";

export const items = pgTable("items", {
  id: serial().primaryKey(),
  title: varchar({ length: 255 }).notNull(),
  description: text(),
  isActive: boolean("is_active").notNull().default(true),
  createdAt: timestamp("created_at").defaultNow(),
  updatedAt: timestamp("updated_at").defaultNow(),
});

export type Item = typeof items.$inferSelect;
export type NewItem = typeof items.$inferInsert;
```

Use snake_case strings for column names (`"is_active"`, `"created_at"`) to match Postgres conventions. Drizzle variable names can be camelCase.

### Drizzle client

Create `db/index.ts`. The adapter on `drizzle-orm/netlify-db` picks the right driver for the runtime automatically.

```typescript
// db/index.ts
import { drizzle } from "drizzle-orm/netlify-db";
import * as schema from "./schema";

export const db = drizzle({ schema });
```

The connection is configured automatically — no connection string needed. If your project uses native ESM with `.js` extensions on relative imports (`from "./schema.js"`), keep that style consistent here.

### Drizzle Kit config

Create `drizzle.config.ts` at the project root. Set `out` to `netlify/database/migrations` — that's the directory the deploy applies migrations from:

```typescript
// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  dialect: "postgresql",
  schema: "./db/schema.ts",
  out: "netlify/database/migrations",
});
```

### Package scripts

```json
{
  "scripts": {
    "db:generate": "drizzle-kit generate",
    "db:migrate": "netlify database migrations apply"
  }
}
```

- `db:generate` writes a new migration file under `netlify/database/migrations/` from the current schema.
- `db:migrate` applies pending migrations to the **local development database only**, via the CLI. Hosted migrations (preview branches, production) are applied by the deploy — never by this script.

### Schema-change workflow

1. Edit `db/schema.ts`.
2. `npm run db:generate` — writes a new file into `netlify/database/migrations/`.
3. Review the SQL.
4. `npm run db:migrate` — applies it to the local development DB for testing.
5. Commit the sc

Related in Backend & APIs