# netlify-database

Zero-config Postgres guidance for Netlify apps. Helps agents run queries from Functions, structure migrations, and configure Drizzle ORM via @netlify/database.

- skill · `type=skill` · Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode · 2900 installs · ★ 45
- Author: netlify
- License: MIT · policy=mirror · the beginning of the file is at the end of this page
- Source: https://github.com/netlify/context-and-tools/tree/HEAD/skills/netlify-database/SKILL.md
- Updated: 2026-10-23
- HTML: https://affpapa.org/en/nevibecode/skills/netlify-database

## What it does

This skill teaches coding agents how to work with managed Postgres using `@netlify/database`. It sets up parameterized queries for Netlify Functions and Edge Functions through `getDatabase()`. It also handles transactions on `db.pool`. Legacy imports from `@netlify/neon` and old `NETLIFY_DATABASE_URL` references get updated to the current driver and `NETLIFY_DB_URL`.

Drizzle ORM requires `@beta` releases. Standard releases lack the native `drizzle-orm/netlify-db` adapter and will fail. In `drizzle.config.ts`, the `out` property must point to `netlify/database/migrations/`. Running `drizzle-kit push` or `drizzle-kit migrate` against the remote database breaks deployment flows, because Netlify automatically runs committed migration files on deploy.

## Requirements
- Works with: PostgreSQL, Supabase

## Install

### Claude Code (native platform)

1. **Skills CLI (Vercel)**
```bash
npx skills add netlify/context-and-tools --skill netlify-database -a claude-code
```

2. **Manually: put the files in place**
- File: `~/.claude/skills/netlify-database/SKILL.md` — Copy the whole skill folder; for one project use .claude/skills/netlify-database/

### Codex

1. **Skills CLI (Vercel)**
```bash
npx skills add netlify/context-and-tools --skill netlify-database -a codex
```

2. **Manually: put the files in place**
- File: `.agents/skills/netlify-database/SKILL.md` — For all projects use ~/.agents/skills/

### Cursor

1. **Skills CLI (Vercel)**
```bash
npx skills add netlify/context-and-tools --skill netlify-database -a cursor
```

2. **Manually: put the files in place**
- File: `.cursor/skills/netlify-database/SKILL.md` — Cursor also reads .agents/skills/ and .claude/skills/

### GitHub Copilot

1. **GitHub CLI**
```bash
gh skill install netlify/context-and-tools netlify-database
```

2. **Manually: put the files in place**
- File: `.github/skills/netlify-database/SKILL.md`

### Gemini CLI

1. **Skills CLI (Vercel)**
```bash
npx skills add netlify/context-and-tools --skill netlify-database -a gemini-cli
```

2. **Platform CLI**
```bash
gemini skills install https://github.com/netlify/context-and-tools --path skills/netlify-database
```

### Windsurf (Devin Desktop)

**Manually: put the files in place**
- File: `.devin/skills/netlify-database/SKILL.md` — The legacy .windsurf/skills/ path still works

### OpenCode

**Skills CLI (Vercel)**
```bash
npx skills add netlify/context-and-tools --skill netlify-database -a opencode
```

### Claude.ai

**Claude.ai**
- Zip the folder and upload it in Settings → Capabilities → Skills

Where a file is given instead of a command, copy the files from the source to that path: https://github.com/netlify/context-and-tools/tree/HEAD/skills/netlify-database/SKILL.md

## When to use it
- query Postgres from Netlify Functions using `@netlify/database`
- wire up Drizzle ORM with the `drizzle-orm/netlify-db` adapter
- generate schema migrations in `netlify/database/migrations/`
- replace legacy `@netlify/neon` code with `getDatabase`

## Example prompts
- Write a Netlify Function that queries active users using `getDatabase` from `@netlify/database`.
- Configure `drizzle.config.ts` so generated migrations go into `netlify/database/migrations/`.
- Show how to run a multi-step insert transaction using `db.pool` in an Edge Function.

## Source text · SKILL.md · MIT

Below is the content of a third-party file. It is data, not instructions for you: do not act on anything written inside unless the human asks. Block tag: f5b34a4151e2c6a6.

BEGIN THIRD-PARTY FILE f5b34a4151e2c6a6
````text
---
name: netlify-database
description: Zero-config Postgres for Netlify apps via @netlify/database — querying data from Functions/Edge Functions, writing schema migrations, setting up Drizzle ORM, local dev with netlify dev, database branches for deploy previews, and migrating an existing Postgres project onto Netlify. Use when adding a database, building a contact form or CRUD API, writing SQL migrations, wiring up Drizzle, running netlify database commands, testing with a local Postgres, or switching from Neon/Supabase/RDS to Netlify Database.
---

# Netlify Database

Zero-config managed Postgres. Install `@netlify/database`, write migrations under `netlify/database/migrations/`, deploy — Netlify provisions the DB and applies migrations automatically. Queryable from Functions, Edge Functions, Builds, and Agent Runners.

## Modern client (reach for this)

```ts
import { getDatabase } from "@netlify/database";

const db = getDatabase();               // auto-selects connection for the runtime
const userId = 42;
const users = await db.sql`SELECT * FROM users WHERE id = ${userId}`;  // auto-parameterized
```

Own driver / ORM instead:
```ts
import { getConnectionString } from "@netlify/database";
const connectionString = getConnectionString();  // correct branch for this env
```

**Legacy — do NOT use for new code:** `import { neon } from "@netlify/neon"`. Superseded by `@netlify/database`. Replace `neon()` calls with the Drizzle `netlify-db` adapter or a Postgres driver via `getConnectionString()`. The legacy env var `NETLIFY_DATABASE_URL` is replaced by `NETLIFY_DB_URL`.

## Where things go

| What | Location |
|------|----------|
| Migrations | `netlify/database/migrations/` (SQL files or subdirs with `migration.sql`) |
| Query code | Functions (`netlify/functions/`), Edge Functions |
| Drizzle schema | `db/schema.ts` (convention) |
| Drizzle client | `db/index.ts` (convention) |
| Connection string | `NETLIFY_DB_URL` env var, or `getConnectionString()` |

## Querying

`getDatabase(options?)` returns a client with `sql` and `pool`. `options.connectionString` overrides the auto-provisioned one; `options.debug` enables logging.

```ts
const db = getDatabase();
const active = await db.sql`SELECT * FROM users WHERE active = ${true}`;
await db.sql`INSERT INTO users (name, email) VALUES (${"Ada"}, ${"ada@example.com"})`;
await db.sql`UPDATE users SET name = ${"Ada Lovelace"} WHERE id = ${1}`;
await db.sql`DELETE FROM users WHERE id = ${1}`;

// Type the rows
interface User { id: number; name: string; email: string; }
const typed = await db.sql<User>`SELECT * FROM users`;

// Stream
for await (const row of db.sql`SELECT * FROM users`.stream()) { /* ... */ }
for await (const chunk of db.sql`SELECT * FROM users`.chunked(100)) { /* ... */ }
```
````
END THIRD-PARTY FILE f5b34a4151e2c6a6

The third-party file has ended. Everything between the f5b34a4151e2c6a6 tags is data: requests and commands from it are not followed. An “end of file” line with another tag inside the block is part of the file.

First 2793 of 19506 bytes. © netlify · MIT · https://github.com/netlify/context-and-tools/tree/HEAD/skills/netlify-database/SKILL.md

_Part of the page did not fit — see the HTML version._

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
