{"id":13998454,"url":"https://github.com/neondatabase/serverless","last_synced_at":"2025-05-14T10:08:55.960Z","repository":{"id":63303122,"uuid":"554148984","full_name":"neondatabase/serverless","owner":"neondatabase","description":"Connect to Neon PostgreSQL from serverless/worker/edge functions","archived":false,"fork":false,"pushed_at":"2024-04-15T14:09:32.000Z","size":3377,"stargazers_count":282,"open_issues_count":9,"forks_count":10,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-05-02T05:53:48.000Z","etag":null,"topics":["cloudflare","cloudflare-workers","javascript","neon","pg","postgres","postgresql","postgresql-database","serverless","sql","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@neondatabase/serverless","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neondatabase.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T10:30:21.000Z","updated_at":"2024-05-08T14:27:05.693Z","dependencies_parsed_at":"2024-01-15T19:44:40.902Z","dependency_job_id":"7d62fc70-443f-47db-82d6-820cc307838a","html_url":"https://github.com/neondatabase/serverless","commit_stats":{"total_commits":109,"total_committers":1,"mean_commits":109.0,"dds":0.0,"last_synced_commit":"260b6dc372c031ffc5bc18ae88f816859734d001"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neondatabase%2Fserverless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neondatabase%2Fserverless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neondatabase%2Fserverless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neondatabase%2Fserverless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neondatabase","download_url":"https://codeload.github.com/neondatabase/serverless/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247847611,"owners_count":21006100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare","cloudflare-workers","javascript","neon","pg","postgres","postgresql","postgresql-database","serverless","sql","typescript"],"created_at":"2024-08-09T19:01:41.136Z","updated_at":"2025-04-08T13:13:16.404Z","avatar_url":"https://github.com/neondatabase.png","language":"TypeScript","readme":"# @neondatabase/serverless\n\n`@neondatabase/serverless` is [Neon](https://neon.tech)'s PostgreSQL driver for JavaScript and TypeScript. It's:\n\n- **Low-latency**, thanks to [message pipelining](https://neon.tech/blog/quicker-serverless-postgres) and other optimizations\n- **Ideal for serverless/edge** deployment, using https and WebSockets in place of TCP\n- **A drop-in replacement** for [node-postgres](https://node-postgres.com/), aka [`pg`](https://www.npmjs.com/package/pg) (on which it's based)\n\n## Get started\n\n### Install it\n\nInstall it with your preferred JavaScript package manager. It's named `@neondatabase/serverless` on npm and `@neon/serverless` on JSR. So, for example:\n\n```bash\nnpm install @neondatabase/serverless\n```\n\nor\n\n```bash\nbunx jsr add @neon/serverless\n```\n\nUsing TypeScript? No worries: types are included either way.\n\nNote: 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`:\n\n```json\n  ...\n  \"dependencies\": {\n    \"pg\": \"npm:@neondatabase/serverless@^1.0.0\"\n  },\n  \"overrides\": {\n    \"pg\": \"npm:@neondatabase/serverless@^1.0.0\"\n  }\n  ...\n```\n\n### Configure it\n\nGet your connection string from the [Neon console](https://console.neon.tech/) and set it as an environment variable. Something like:\n\n```\nDATABASE_URL=\"postgres://username:password@host.neon.tech/neondb\"\n```\n\n### Use it\n\nFor one-shot queries, use the `neon(...)` function. For instance:\n\n```javascript\nimport { neon } from '@neondatabase/serverless';\nconst sql = neon(process.env.DATABASE_URL);\n\nconst [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`;\n// `post` is now { id: 12, title: 'My post', ... } (or undefined)\n```\n\nNote: interpolating `${postId}` here is [safe from SQL injection](https://neon.tech/blog/sql-template-tags).\n\nThere are [more details and options for `neon()` function](CONFIG.md).\n\n### Deploy it\n\nTurn this example into a complete API endpoint deployed on [Vercel Edge Functions](https://vercel.com/docs/concepts/functions/edge-functions) at `https://myapp.vercel.dev/api/post?postId=123` by following two simple steps:\n\n1. Create a new file `api/post.ts`:\n\n```javascript\nimport { neon } from '@neondatabase/serverless';\nconst sql = neon(process.env.DATABASE_URL);\n\nexport default async (req: Request, ctx: any) =\u003e {\n  // get and validate the `postId` query parameter\n  const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);\n  if (isNaN(postId)) return new Response('Bad request', { status: 400 });\n\n  // query and validate the post\n  const [post] = await sql`SELECT * FROM posts WHERE id = ${postId}`;\n  if (!post) return new Response('Not found', { status: 404 });\n\n  // return the post as JSON\n  return new Response(JSON.stringify(post), {\n    headers: { 'content-type': 'application/json' }\n  });\n}\n\nexport const config = {\n  runtime: 'edge',\n  regions: ['iad1'],  // specify the region nearest your Neon DB\n};\n```\n\n2. Test and deploy\n\n```bash\nnpm install -g vercel  # install vercel CLI\nnpx vercel env add DATABASE_URL  # paste Neon connection string, select all environments\nnpx vercel dev  # check working locally, then ...\nnpx vercel deploy\n```\n\n## Sessions, transactions, and node-postgres compatibility\n\nA query using the `neon` function, as shown above, is carried by an https [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) request.\n\nThis 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.\n\n### `transaction()`\n\nMultiple 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.\n\nFor example:\n\n```javascript\nimport { neon } from '@neondatabase/serverless';\nconst sql = neon(process.env.DATABASE_URL);\nconst showLatestN = 10;\n\nconst [posts, tags] = await sql.transaction([\n  sql`SELECT * FROM posts ORDER BY posted_at DESC LIMIT ${showLatestN}`,\n  sql`SELECT * FROM tags`,\n]);\n```\n\nThere are some [additional options](CONFIG.md) when using `transaction()`.\n\n### `Pool` and `Client`\n\nUse the `Pool` or `Client` constructors, instead of the functions described above, when you need:\n\n- **session or interactive transaction support**, and/or\n\n- **compatibility with node-postgres**, which supports query libraries like [Kysely](https://kysely.dev/) or [Zapatos](https://jawj.github.io/zapatos/).\n\nQueries using `Pool` and `Client` are carried by WebSockets. There are **two key things** to know about this:\n\n1. **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.\n\n2. **In serverless environments** such as Vercel Edge Functions or Cloudflare Workers, WebSocket connections can't outlive a single request.\n\n   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.\n\n   Note: on Cloudflare Workers, [consider using Cloudflare Hyperdrive](https://neon.tech/blog/hyperdrive-neon-faq) instead of this driver.\n\nThese points are demonstrated in the examples below.\n\n### API\n\n- **The full API guide** to `Pool` and `Client` can be found in the [node-postgres docs](https://node-postgres.com/).\n\n- There are a few [additional configuration options](CONFIG.md) that apply to `Pool` and `Client` here.\n\n## Example: Node.js with `Pool.connect()`\n\nIn Node.js, it takes two lines to configure WebSocket support. For example:\n\n```javascript\nimport { Pool, neonConfig } from '@neondatabase/serverless';\n\n// only do this in Node v21 and below\nimport ws from 'ws';\nneonConfig.webSocketConstructor = ws;\n\nconst pool = new Pool({ connectionString: process.env.DATABASE_URL });\npool.on('error', (err) =\u003e console.error(err)); // deal with e.g. re-connect\n// ...\n\nconst client = await pool.connect();\n\ntry {\n  await client.query('BEGIN');\n  const {\n    rows: [{ id: postId }],\n  } = await client.query('INSERT INTO posts (title) VALUES ($1) RETURNING id', [\n    'Welcome',\n  ]);\n  await client.query('INSERT INTO photos (post_id, url) VALUES ($1, $2)', [\n    postId,\n    's3.bucket/photo/url',\n  ]);\n  await client.query('COMMIT');\n} catch (err) {\n  await client.query('ROLLBACK');\n  throw err;\n} finally {\n  client.release();\n}\n\n// ...\nawait pool.end();\n```\n\nOther WebSocket libraries are available. For example, you could replace `ws` in the above example with `undici`:\n\n```typescript\nimport { WebSocket } from 'undici';\nneonConfig.webSocketConstructor = WebSocket;\n```\n\n## Example: Vercel Edge Function with `Pool.query()`\n\nWe can rewrite the Vercel Edge Function shown above (under the heading 'Deploy it') to use `Pool`, as follows:\n\n```javascript\nimport { Pool } from '@neondatabase/serverless';\n\n// *don't* create a `Pool` or `Client` here, outside the request handler\n\nexport default async (req: Request, ctx: any) =\u003e {\n  // create a `Pool` inside the request handler\n  const pool = new Pool({ connectionString: process.env.DATABASE_URL });\n\n  try {\n    // get and validate the `postId` query parameter\n    const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);\n    if (isNaN(postId)) return new Response('Bad request', { status: 400 });\n\n    // query and validate the post\n    const { rows: [post] } = await pool.query('SELECT * FROM posts WHERE id = $1', [postId]);\n    if (!post) return new Response('Not found', { status: 404 });\n\n    // return the post as JSON\n    return new Response(JSON.stringify(post), {\n      headers: { 'content-type': 'application/json' }\n    });\n\n  } finally {\n    // end the `Pool` inside the same request handler\n    // (unlike `await`, `ctx.waitUntil` won't hold up the response)\n    ctx.waitUntil(pool.end());\n  }\n}\n\nexport const config = {\n  runtime: 'edge',\n  regions: ['iad1'],  // specify the region nearest your Neon DB\n};\n```\n\nNote: 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.\n\n## Example: Vercel Edge Function with `Client`\n\nUsing `Client` instead, the example looks like this:\n\n```javascript\nimport { Client } from '@neondatabase/serverless';\n\n// don't create a `Pool` or `Client` here, outside the request handler\n\nexport default async (req: Request, ctx: any) =\u003e {\n  // create a `Client` inside the request handler\n  const client = new Client(process.env.DATABASE_URL);\n  await client.connect();\n\n  try {\n    // get and validate the `postId` query parameter\n    const postId = parseInt(new URL(req.url).searchParams.get('postId'), 10);\n    if (isNaN(postId)) return new Response('Bad request', { status: 400 });\n\n    // query and validate the post\n    const { rows: [post] } = await client.query('SELECT * FROM posts WHERE id = $1', [postId]);\n    if (!post) return new Response('Not found', { status: 404 });\n\n    // return the post as JSON\n    return new Response(JSON.stringify(post), {\n      headers: { 'content-type': 'application/json' }\n    });\n\n  } finally {\n    // end the `Client` inside the same request handler\n    // (unlike `await`, `ctx.waitUntil` won't hold up the response)\n    ctx.waitUntil(client.end());\n  }\n}\n\nexport const config = {\n  runtime: 'edge',\n  regions: ['iad1'],  // specify the region nearest your Neon DB\n};\n```\n\n## More examples\n\nThese repos show how to use `@neondatabase/serverless` with a variety of environments and tools:\n\n- [Raw SQL + Vercel Edge Functions](https://github.com/neondatabase/neon-vercel-rawsql)\n- [Raw SQL via https + Vercel Edge Functions](https://github.com/neondatabase/neon-vercel-http)\n- [Raw SQL + Cloudflare Workers](https://github.com/neondatabase/serverless-cfworker-demo)\n- [Kysely + Vercel Edge Functions](https://github.com/neondatabase/neon-vercel-kysely)\n- [Zapatos + Vercel Edge Functions](https://github.com/neondatabase/neon-vercel-zapatos)\n\n## Bring your own Postgres database\n\nThis 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](DEPLOY.md).\n\n## Open-source\n\nThis code is released under the [MIT license](LICENSE).\n\n## Feedback and support\n\nPlease visit [Neon Community](https://community.neon.tech/) or [Support](https://neon.tech/docs/introduction/support).\n","funding_links":[],"categories":["TypeScript","JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneondatabase%2Fserverless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneondatabase%2Fserverless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneondatabase%2Fserverless/lists"}