Gathering detailed insights and metrics for @neondatabase/serverless
Gathering detailed insights and metrics for @neondatabase/serverless
Gathering detailed insights and metrics for @neondatabase/serverless
Gathering detailed insights and metrics for @neondatabase/serverless
@prisma/adapter-neon
Prisma's driver adapter for "@neondatabase/serverless"
@neondatabase/toolkit
This is a toolkit that Bundles Neon's [API Client](https://www.npmjs.com/package/@neondatabase/api-client) as well as Neon's [Serverless Driver](https://github.com/neondatabase/serverless).
@jkomyno/prisma-neon-js-connector
Prisma's JS Connector for "@neondatabase/serverless"
@jkomyno/prisma-neon-driver-adapter
Prisma's Driver Adapter for "@neondatabase/serverless"
Connect to Neon PostgreSQL from serverless/worker/edge functions
npm install @neondatabase/serverless
Typescript
Module System
Min. Node Version
Node Version
NPM Version
98.8
Supply Chain
100
Quality
92.8
Maintenance
100
Vulnerability
100
License
JavaScript (62.51%)
TypeScript (36.88%)
Shell (0.6%)
Total Downloads
17,635,096
Last Day
55,747
Last Week
564,948
Last Month
2,376,170
Last Year
14,174,364
MIT License
441 Stars
331 Commits
27 Forks
5 Watchers
52 Branches
34 Contributors
Updated on Jun 06, 2025
Minified
Minified + Gzipped
Latest Version
1.0.1
Package Id
@neondatabase/serverless@1.0.1
Unpacked Size
400.57 kB
Size
125.23 kB
File Count
10
NPM Version
10.9.0
Node Version
22.11.0
Published on
Jun 06, 2025
Cumulative downloads
Total Downloads
2
42
@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:
1npm install @neondatabase/serverless
or
1bunx 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
:
1 ... 2 "dependencies": { 3 "pg": "npm:@neondatabase/serverless@^1.0.0" 4 }, 5 "overrides": { 6 "pg": "npm:@neondatabase/serverless@^1.0.0" 7 } 8 ...
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:
1import { neon } from '@neondatabase/serverless'; 2const sql = neon(process.env.DATABASE_URL); 3 4const [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`; 5// `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
:1import { neon } from '@neondatabase/serverless'; 2const sql = neon(process.env.DATABASE_URL); 3 4export default async (req: Request, ctx: any) => { 5 // get and validate the `postId` query parameter 6 const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10); 7 if (isNaN(postId)) return new Response('Bad request', { status: 400 }); 8 9 // query and validate the post 10 const [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`; 11 if (!post) return new Response('Not found', { status: 404 }); 12 13 // return the post as JSON 14 return new Response(JSON.stringify(post), { 15 headers: { 'content-type': 'application/json' } 16 }); 17} 18 19export const config = { 20 runtime: 'edge', 21 regions: ['iad1'], // specify the region nearest your Neon DB 22};
1npm install -g vercel # install vercel CLI 2npx vercel env add DATABASE_URL # paste Neon connection string, select all environments 3npx vercel dev # check working locally, then ... 4npx 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:
1import { neon } from '@neondatabase/serverless'; 2const sql = neon(process.env.DATABASE_URL); 3const showLatestN = 10; 4 5const [posts, tags] = await sql.transaction([ 6 sql`SELECT * FROM posts ORDER BY posted_at DESC LIMIT ${showLatestN}`, 7 sql`SELECT * FROM tags`, 8]);
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:
1import { Pool, neonConfig } from '@neondatabase/serverless'; 2 3// only do this in Node v21 and below 4import ws from 'ws'; 5neonConfig.webSocketConstructor = ws; 6 7const pool = new Pool({ connectionString: process.env.DATABASE_URL }); 8pool.on('error', (err) => console.error(err)); // deal with e.g. re-connect 9// ... 10 11const client = await pool.connect(); 12 13try { 14 await client.query('BEGIN'); 15 const { 16 rows: [{ id: postId }], 17 } = await client.query('INSERT INTO posts (title) VALUES ($1) RETURNING id', [ 18 'Welcome', 19 ]); 20 await client.query('INSERT INTO photos (post_id, url) VALUES ($1, $2)', [ 21 postId, 22 's3.bucket/photo/url', 23 ]); 24 await client.query('COMMIT'); 25} catch (err) { 26 await client.query('ROLLBACK'); 27 throw err; 28} finally { 29 client.release(); 30} 31 32// ... 33await pool.end();
Other WebSocket libraries are available. For example, you could replace ws
in the above example with undici
:
1import { WebSocket } from 'undici'; 2neonConfig.webSocketConstructor = WebSocket;
Pool.query()
We can rewrite the Vercel Edge Function shown above (under the heading 'Deploy it') to use Pool
, as follows:
1import { Pool } from '@neondatabase/serverless'; 2 3// *don't* create a `Pool` or `Client` here, outside the request handler 4 5export default async (req: Request, ctx: any) => { 6 // create a `Pool` inside the request handler 7 const pool = new Pool({ connectionString: process.env.DATABASE_URL }); 8 9 try { 10 // get and validate the `postId` query parameter 11 const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10); 12 if (isNaN(postId)) return new Response('Bad request', { status: 400 }); 13 14 // query and validate the post 15 const { rows: [post] } = await pool.query('SELECT * FROM posts WHERE id = $1', [postId]); 16 if (!post) return new Response('Not found', { status: 404 }); 17 18 // return the post as JSON 19 return new Response(JSON.stringify(post), { 20 headers: { 'content-type': 'application/json' } 21 }); 22 23 } finally { 24 // end the `Pool` inside the same request handler 25 // (unlike `await`, `ctx.waitUntil` won't hold up the response) 26 ctx.waitUntil(pool.end()); 27 } 28} 29 30export const config = { 31 runtime: 'edge', 32 regions: ['iad1'], // specify the region nearest your Neon DB 33};
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:
1import { Client } from '@neondatabase/serverless'; 2 3// don't create a `Pool` or `Client` here, outside the request handler 4 5export default async (req: Request, ctx: any) => { 6 // create a `Client` inside the request handler 7 const client = new Client(process.env.DATABASE_URL); 8 await client.connect(); 9 10 try { 11 // get and validate the `postId` query parameter 12 const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10); 13 if (isNaN(postId)) return new Response('Bad request', { status: 400 }); 14 15 // query and validate the post 16 const { rows: [post] } = await client.query('SELECT * FROM posts WHERE id = $1', [postId]); 17 if (!post) return new Response('Not found', { status: 404 }); 18 19 // return the post as JSON 20 return new Response(JSON.stringify(post), { 21 headers: { 'content-type': 'application/json' } 22 }); 23 24 } finally { 25 // end the `Client` inside the same request handler 26 // (unlike `await`, `ctx.waitUntil` won't hold up the response) 27 ctx.waitUntil(client.end()); 28 } 29} 30 31export const config = { 32 runtime: 'edge', 33 regions: ['iad1'], // specify the region nearest your Neon DB 34};
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.
No vulnerabilities found.
No security vulnerabilities found.
Last Day
-8.3%
55,747
Compared to previous day
Last Week
-5.4%
564,948
Compared to previous week
Last Month
11.8%
2,376,170
Compared to previous month
Last Year
316.2%
14,174,364
Compared to previous year