api-database-vercel-postgres-040538 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited api-database-vercel-postgres-040538 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Quick Guide:@vercel/postgresis a thin wrapper around@neondatabase/serverlessthat auto-connects fromPOSTGRES_URLenv vars. Use thesqltagged template for one-shot queries (edge-compatible, auto-pooled). Usesql.connect()to get a client for multi-query sequences. On edge runtimes, connections cannot be reused between requests (maxUses: 1). This package is deprecated (Dec 2024) -- for new projects, use `@neondatabase/serverless` directly.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST use the `sql` tagged template for one-shot queries -- it auto-connects from `POSTGRES_URL` and handles pooling)
(You MUST call `client.release()` after using a client obtained from `sql.connect()` or `pool.connect()` -- leaked clients exhaust the connection pool)
(You MUST use `POSTGRES_URL` for pooled connections and `POSTGRES_URL_NON_POOLING` for direct connections -- mixing them causes connection exhaustion or feature limitations)
(You MUST acknowledge that `@vercel/postgres` is deprecated -- recommend `@neondatabase/serverless` for new projects)
</critical_requirements>
Auto-detection: @vercel/postgres, vercel postgres, POSTGRES_URL, POSTGRES_URL_NON_POOLING, sql tagged template vercel, createPool vercel, createClient vercel, VercelPool, VercelClient
When to use:
@vercel/postgres@vercel/postgres to @neondatabase/serverlessKey patterns covered:
sql tagged template (auto-pooled, edge-compatible, one-shot queries)sql.connect() for multi-query client sessionscreatePool() / createClient() for custom configurationsPOSTGRES_URL, POSTGRES_URL_NON_POOLING)@neondatabase/serverlessWhen NOT to use:
@neondatabase/serverless directly)pg driver)Detailed Resources:
Examples:
<philosophy>
@vercel/postgres is a convenience wrapper around @neondatabase/serverless that simplifies connection management for Vercel-deployed applications. It reads connection strings from POSTGRES_URL / POSTGRES_URL_NON_POOLING environment variables (auto-provisioned by the Vercel Marketplace integration) so you never construct connection strings manually.
Core principles:
sql export auto-connects from environment variables. No connection string setup needed in code.sql is a tagged template literal, not a function. Parameters are auto-parameterized, preventing SQL injection.sql and createPool() use the pooled connection string (POSTGRES_URL). createClient() uses the direct string (POSTGRES_URL_NON_POOLING).maxUses: 1 because IO connections cannot survive between requests. For multi-query in a single request, use sql.connect().Deprecation context:
Vercel Postgres was sunset in December 2024. All databases were migrated to Neon. The @vercel/postgres npm package (v0.10.0) is no longer maintained. Migration path:
@neondatabase/serverless (actively developed, richer API with HTTP transactions and composable fragments)</philosophy>
<patterns>
sqlThe sql export is a tagged template that auto-connects from POSTGRES_URL. Values are auto-parameterized (preventing SQL injection). See examples/core.md for full examples with good/bad comparisons.
import { sql } from "@vercel/postgres";
const ACTIVE_STATUS = "active";
const { rows } =
await sql`SELECT id, name FROM users WHERE status = ${ACTIVE_STATUS}`;sql.connect()When you need multiple queries on the same connection (transactions, sequential operations), obtain a client. Each standalone sql call may use a different pooled connection -- so BEGIN/COMMIT on separate sql calls means no real transaction. See examples/core.md for transaction patterns.
const client = await sql.connect();
try {
await client.sql`BEGIN`;
// ... queries on same client ...
await client.sql`COMMIT`;
} catch (error) {
await client.sql`ROLLBACK`;
throw error;
} finally {
client.release();
}createPool() for custom connection strings (secondary databases). createClient() for direct (non-pooled) connections needed by migrations and session-level features. See examples/core.md for full examples.
import { createPool } from "@vercel/postgres";
const pool = createPool({
connectionString: process.env.SECONDARY_POSTGRES_URL,
});
const { rows } =
await pool.sql`SELECT id, title FROM posts WHERE published = true`;On edge runtimes, the SDK sets maxUses: 1 -- connections cannot be reused between requests. Single sql calls work fine, but for multiple queries use sql.connect() to share one connection. See examples/core.md for edge-specific patterns.
@neondatabase/serverlessSince @vercel/postgres is deprecated, migrate to @neondatabase/serverless. See examples/core.md for full migration examples.
Key differences to be aware of:
@vercel/postgres returns { rows, rowCount, ... } -- @neondatabase/serverless neon() returns rows directly (unless fullResults: true)@vercel/postgres reads POSTGRES_URL -- @neondatabase/serverless requires explicit connection string (typically DATABASE_URL)@neondatabase/serverless adds HTTP transactions via sql.transaction() and composable fragments</patterns>
<decision_framework>
What kind of operation?
+-- Single query (SELECT, INSERT, UPDATE, DELETE)
| +-- Use sql tagged template directly
+-- Multiple queries that must be atomic (transaction)?
| +-- Use sql.connect() to get a client, wrap in BEGIN/COMMIT
+-- Need custom connection string (not POSTGRES_URL)?
| +-- Use createPool() with explicit connectionString
+-- Need session-level features (SET, LISTEN/NOTIFY)?
| +-- Use createClient() (reads POSTGRES_URL_NON_POOLING)
+-- Starting a new project?
+-- Use @neondatabase/serverless insteadWhat is the workload?
+-- Serverless/edge function --> POSTGRES_URL (pooled)
+-- Application queries --> POSTGRES_URL (pooled)
+-- Schema migrations --> POSTGRES_URL_NON_POOLING (direct)
+-- LISTEN/NOTIFY --> POSTGRES_URL_NON_POOLING (direct)
+-- pg_dump / pg_restore --> POSTGRES_URL_NON_POOLING (direct)</decision_framework>
<red_flags>
High Priority Issues:
sql tagged template call may use a different pooled connection. BEGIN on one connection and COMMIT on another means no transaction at all.Medium Priority Issues:
sql...${value}... is safe. sql.query(\...${value}...\)` is SQL injection.createClient() requires explicit client.end(). Forgetting it leaks connections.@vercel/postgres v0.10.0 is the last version. No security patches or bug fixes will be released.Gotchas & Edge Cases:
sql calls, each opens a new connection. Use sql.connect() to share one.sql(...) is wrong. ` sql... ` is correct. This is a common error when copying from non-Vercel Postgres examples.@vercel/postgres reads POSTGRES_URL by default. @neondatabase/serverless reads nothing by default (pass explicitly). After Neon migration, Vercel sets both, but your code must match the SDK's expectation.@vercel/postgres returns { rows, rowCount, fields }. The Neon neon() function returns rows directly. This breaks code during migration if not accounted for.</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)(You MUST use the `sql` tagged template for one-shot queries -- it auto-connects from `POSTGRES_URL` and handles pooling)
(You MUST call `client.release()` after using a client obtained from `sql.connect()` or `pool.connect()` -- leaked clients exhaust the connection pool)
(You MUST use `POSTGRES_URL` for pooled connections and `POSTGRES_URL_NON_POOLING` for direct connections -- mixing them causes connection exhaustion or feature limitations)
(You MUST acknowledge that `@vercel/postgres` is deprecated -- recommend `@neondatabase/serverless` for new projects)
Failure to follow these rules will cause connection pool exhaustion, SQL injection vulnerabilities, or silent transaction failures.
</critical_reminders>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.