
Security News
Crates.io Users Targeted by Phishing Emails
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
@neondatabase/serverless
Advanced tools
@neondatabase/serverless is an npm package designed to facilitate serverless interactions with Neon, a serverless PostgreSQL database. It provides a set of tools and utilities to connect, query, and manage PostgreSQL databases in a serverless environment, making it easier to build scalable and efficient applications.
Connecting to a Neon Database
This feature allows you to establish a connection to a Neon database using the provided connection string. The code sample demonstrates how to create a new client instance and connect to the database.
const { Client } = require('@neondatabase/serverless');
const client = new Client({
connectionString: process.env.NEON_DATABASE_URL,
});
async function connect() {
await client.connect();
console.log('Connected to Neon Database');
}
connect();
Executing SQL Queries
This feature allows you to execute SQL queries against the connected Neon database. The code sample demonstrates how to connect to the database, execute a SELECT query, and log the results.
const { Client } = require('@neondatabase/serverless');
const client = new Client({
connectionString: process.env.NEON_DATABASE_URL,
});
async function executeQuery() {
await client.connect();
const res = await client.query('SELECT * FROM users');
console.log(res.rows);
await client.end();
}
executeQuery();
Handling Transactions
This feature allows you to handle transactions in the Neon database. The code sample demonstrates how to begin a transaction, execute an insert query, commit the transaction, and handle errors by rolling back the transaction if necessary.
const { Client } = require('@neondatabase/serverless');
const client = new Client({
connectionString: process.env.NEON_DATABASE_URL,
});
async function handleTransaction() {
await client.connect();
try {
await client.query('BEGIN');
await client.query('INSERT INTO users(name) VALUES($1)', ['John Doe']);
await client.query('COMMIT');
console.log('Transaction committed');
} catch (e) {
await client.query('ROLLBACK');
console.error('Transaction rolled back', e);
} finally {
await client.end();
}
}
handleTransaction();
The 'pg' package is a popular PostgreSQL client for Node.js. It provides a comprehensive set of features for connecting to and interacting with PostgreSQL databases. Compared to @neondatabase/serverless, 'pg' is more general-purpose and widely used, but it may require additional configuration for serverless environments.
The 'knex' package is a SQL query builder for Node.js, supporting multiple database types including PostgreSQL. It provides a flexible and powerful API for building and executing SQL queries. While 'knex' offers more advanced query building capabilities, it is not specifically tailored for serverless environments like @neondatabase/serverless.
The 'sequelize' package is a promise-based Node.js ORM for various SQL databases, including PostgreSQL. It provides a higher-level abstraction for database interactions, including model definitions and associations. Compared to @neondatabase/serverless, 'sequelize' offers more features for complex data modeling but may introduce additional overhead for simple use cases.
@neondatabase/serverless
is Neon's PostgreSQL driver for JavaScript and TypeScript. It's:
pg
(on which it's based)Install it with your preferred JavaScript package manager. It's named @neondatabase/serverless
on npm and @neon/serverless
on JSR. So, for example:
npm install @neondatabase/serverless
or
bunx jsr add @neon/serverless
Using TypeScript? No worries: types are included either way.
Note: to install with npm for use by another package that declares a dependency on pg
(node-postgres), use an alias plus an override, which will look something like this in your package.json
:
...
"dependencies": {
"pg": "npm:@neondatabase/serverless@^1.0.0"
},
"overrides": {
"pg": "npm:@neondatabase/serverless@^1.0.0"
}
...
Get your connection string from the Neon console and set it as an environment variable. Something like:
DATABASE_URL="postgres://username:password@host.neon.tech/neondb"
For one-shot queries, use the neon(...)
function. For instance:
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`;
// `post` is now { id: 12, title: 'My post', ... } (or undefined)
Note: interpolating ${postId}
here is safe from SQL injection.
There are more details and options for neon()
function.
Turn this example into a complete API endpoint deployed on Vercel Edge Functions at https://myapp.vercel.dev/api/post?postId=123
by following two simple steps:
api/post.ts
:import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
export default async (req: Request, ctx: any) => {
// get and validate the `postId` query parameter
const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);
if (isNaN(postId)) return new Response('Bad request', { status: 400 });
// query and validate the post
const [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`;
if (!post) return new Response('Not found', { status: 404 });
// return the post as JSON
return new Response(JSON.stringify(post), {
headers: { 'content-type': 'application/json' }
});
}
export const config = {
runtime: 'edge',
regions: ['iad1'], // specify the region nearest your Neon DB
};
npm install -g vercel # install vercel CLI
npx vercel env add DATABASE_URL # paste Neon connection string, select all environments
npx vercel dev # check working locally, then ...
npx vercel deploy
A query using the neon
function, as shown above, is carried by an https fetch request.
This should work — and work fast — from any modern JavaScript environment. But you can only send one query at a time this way: sessions and transactions are not supported.
transaction()
Multiple queries can be issued via fetch request within a single, non-interactive transaction by using the transaction()
function. This is exposed as a property on the query function.
For example:
import { neon } from '@neondatabase/serverless';
const sql = neon(process.env.DATABASE_URL);
const showLatestN = 10;
const [posts, tags] = await sql.transaction([
sql`SELECT * FROM posts ORDER BY posted_at DESC LIMIT ${showLatestN}`,
sql`SELECT * FROM tags`,
]);
There are some additional options when using transaction()
.
Pool
and Client
Use the Pool
or Client
constructors, instead of the functions described above, when you need:
session or interactive transaction support, and/or
compatibility with node-postgres, which supports query libraries like Kysely or Zapatos.
Queries using Pool
and Client
are carried by WebSockets. There are two key things to know about this:
In Node.js v21 and earlier and some other environments, there's no built-in WebSocket support. In these cases, supply a WebSocket constructor function.
In serverless environments such as Vercel Edge Functions or Cloudflare Workers, WebSocket connections can't outlive a single request.
That means Pool
or Client
objects must be connected, used and closed within a single request handler. Don't create them outside a request handler; don't create them in one handler and try to reuse them in another; and to avoid exhausting available connections, don't forget to close them.
Note: on Cloudflare Workers, consider using Cloudflare Hyperdrive instead of this driver.
These points are demonstrated in the examples below.
The full API guide to Pool
and Client
can be found in the node-postgres docs.
There are a few additional configuration options that apply to Pool
and Client
here.
Pool.connect()
In Node.js, it takes two lines to configure WebSocket support. For example:
import { Pool, neonConfig } from '@neondatabase/serverless';
// only do this in Node v21 and below
import ws from 'ws';
neonConfig.webSocketConstructor = ws;
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
pool.on('error', (err) => console.error(err)); // deal with e.g. re-connect
// ...
const client = await pool.connect();
try {
await client.query('BEGIN');
const {
rows: [{ id: postId }],
} = await client.query('INSERT INTO posts (title) VALUES ($1) RETURNING id', [
'Welcome',
]);
await client.query('INSERT INTO photos (post_id, url) VALUES ($1, $2)', [
postId,
's3.bucket/photo/url',
]);
await client.query('COMMIT');
} catch (err) {
await client.query('ROLLBACK');
throw err;
} finally {
client.release();
}
// ...
await pool.end();
Other WebSocket libraries are available. For example, you could replace ws
in the above example with undici
:
import { WebSocket } from 'undici';
neonConfig.webSocketConstructor = WebSocket;
Pool.query()
We can rewrite the Vercel Edge Function shown above (under the heading 'Deploy it') to use Pool
, as follows:
import { Pool } from '@neondatabase/serverless';
// *don't* create a `Pool` or `Client` here, outside the request handler
export default async (req: Request, ctx: any) => {
// create a `Pool` inside the request handler
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
try {
// get and validate the `postId` query parameter
const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);
if (isNaN(postId)) return new Response('Bad request', { status: 400 });
// query and validate the post
const { rows: [post] } = await pool.query('SELECT * FROM posts WHERE id = $1', [postId]);
if (!post) return new Response('Not found', { status: 404 });
// return the post as JSON
return new Response(JSON.stringify(post), {
headers: { 'content-type': 'application/json' }
});
} finally {
// end the `Pool` inside the same request handler
// (unlike `await`, `ctx.waitUntil` won't hold up the response)
ctx.waitUntil(pool.end());
}
}
export const config = {
runtime: 'edge',
regions: ['iad1'], // specify the region nearest your Neon DB
};
Note: we don't actually use the pooling capabilities of Pool
in this example. But it's slightly briefer than using Client
and, because Pool.query
is designed for one-shot queries, we may in future automatically route these queries over https for lower latency.
Client
Using Client
instead, the example looks like this:
import { Client } from '@neondatabase/serverless';
// don't create a `Pool` or `Client` here, outside the request handler
export default async (req: Request, ctx: any) => {
// create a `Client` inside the request handler
const client = new Client(process.env.DATABASE_URL);
await client.connect();
try {
// get and validate the `postId` query parameter
const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);
if (isNaN(postId)) return new Response('Bad request', { status: 400 });
// query and validate the post
const { rows: [post] } = await client.query('SELECT * FROM posts WHERE id = $1', [postId]);
if (!post) return new Response('Not found', { status: 404 });
// return the post as JSON
return new Response(JSON.stringify(post), {
headers: { 'content-type': 'application/json' }
});
} finally {
// end the `Client` inside the same request handler
// (unlike `await`, `ctx.waitUntil` won't hold up the response)
ctx.waitUntil(client.end());
}
}
export const config = {
runtime: 'edge',
regions: ['iad1'], // specify the region nearest your Neon DB
};
These repos show how to use @neondatabase/serverless
with a variety of environments and tools:
This package comes configured to connect to a Neon database. But you can also use it to connect to your own Postgres instances if you run your own WebSocket proxy.
This code is released under the MIT license.
Please visit Neon Community or Support.
1.0.1 (2025-06-06)
The package now prints a security warning to the console when a connection is made in a web browser. This behaviour can be suppressed with a new configuration option: disableWarningInBrowsers
. There are a few other very minor fixes.
FAQs
node-postgres for serverless environments from neon.tech
The npm package @neondatabase/serverless receives a total of 583,139 weekly downloads. As such, @neondatabase/serverless popularity was classified as popular.
We found that @neondatabase/serverless demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 9 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The Rust Security Response WG is warning of phishing emails from rustfoundation.dev targeting crates.io users.
Product
Socket now lets you customize pull request alert headers, helping security teams share clear guidance right in PRs to speed reviews and reduce back-and-forth.
Product
Socket's Rust support is moving to Beta: all users can scan Cargo projects and generate SBOMs, including Cargo.toml-only crates, with Rust-aware supply chain checks.