Private Preview
This feature is in private preview: it's not ready for production use, and it may be briefly unavailable as we deploy updates. To get access, sign up here.
A function takes a request and returns a web response, running on long-lived Node.js compute next to your database. This guide builds one by hand: define it in neon.ts, run it locally, deploy it, and call it over HTTP.
Prerequisites
- A Neon account with Functions preview access. See Preview access.
- The latest
neon, installed and authenticated. Functions commands are new and change often during the preview, so upgrade before you start (npm install -g neon@latest). - Node.js 20 or later. Deployed functions run on Node.js 24, so use 24 locally for the closest match.
Functions are available on new projects in AWS us-east-2 only, created on or after June 15, 2026.
neon init --previewis designed to be run by your AI coding assistant. It outputs structured instructions that guide the agent through setup. To install the Neon Platform (neon) and Neon Functions skills separately:npx skills add neondatabase/agent-skills -s neon -s neon-functionsSet up your project
Create your project directory:
mkdir my-function && cd my-functionThen link the directory to your Neon project. There are two ways:
With an AI coding assistant. Ask it to run
neon init --preview. The command returns structured JSON instructions for the full setup: MCP server and agent skills, optional template scaffolding, project linking, and env var pull. Sign-in opens a browser window, and the agent pauses while you complete the OAuth step.By hand. Run
neon linkand select your project and branch when prompted (or pass--project-id). This writes a.neonfile and pulls the branch's environment variables into a local.env.neon linkTo start from a working example instead, run
neon bootstrap. It scaffolds a starter template and links it. Available templates: Hono API, AI SDK agent, Mastra agent, MCP server, Realtime chat (Next.js + WebSockets), and Realtime counter (TanStack Router + SSE), all on Neon Functions. This guide builds the function by hand.Define your function
Create
neon.tsat your project root. It declares your functions and is whatneon devandneon deployread:neon.tsimport { defineConfig } from "@neon/config/v1"; export default defineConfig({ // preview groups features still in beta: functions, AI Gateway, and object-storage buckets. preview: { functions: { // The key is the function's slug: // a permanent ID used in CLI commands and the URL. hello: { name: "My first function", // display label only source: "./functions/hello.ts", // path to the handler file }, }, }, });The slug is permanent: it can't be renamed after the first deploy. See the neon.ts reference for all options.
Install dependencies:
npm install @neon/config hono pg npm install --save-dev @types/pgA function is any module whose default export has a
fetch(request)method that returns aResponse. That can be an object with afetchmethod:export default { fetch: (request: Request) => new Response('Hello world'), };Or a bare async function:
export default async function handler(request: Request) { return new Response('Hello world'); }A Hono app exports the object shape, so
export default appworks directly. For this guide, write a handler that queries Postgres.DATABASE_URLis injected automatically from the linked branch's Postgres database:functions/hello.tsimport { Hono } from 'hono'; import { Pool } from 'pg'; // Create the pool once at module scope so it's reused across requests. const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 5 }); const app = new Hono(); app.get('/', async (c) => { const { rows } = await pool.query('SELECT version()'); return c.json(rows[0]); }); export default app; // Optional: drain the pool on shutdown (the platform sends SIGINT). process.on('SIGINT', () => { pool.end().then(() => process.exit(0)); });Use a connection pool, not the serverless driver
A function keeps running across requests, so connect to Postgres with a long-lived
pgPoolcreated once at module scope. Don't use@neondatabase/serverlesshere: it's built for short-lived, edge-style invocations that open a connection per request, which wastes the persistent runtime a function gives you. Use the pooledDATABASE_URLfor queries; useDATABASE_URL_UNPOOLEDonly where you need a dedicated connection (such asLISTEN/NOTIFY).Develop locally
neon devserves all functions declared inneon.tswith hot reload. It injectsDATABASE_URLand other Neon env vars from the linked branch. See Environment variables for the full list and how to pull them into a local.envfile.neon devThe terminal prints the URL for each running function:
Neon Functions dev server hello http://localhost:8787Deploy
neon deployreadsneon.tsand applies it to the linked branch, deploying every function it declares:neon deployThe CLI bundles each function with esbuild, uploads it, and waits for the deployment to complete.
To deploy a single file without a
neon.ts, deploy it by slug instead:neon functions deploy hello --src functions/hello.tsFor all deploy options, including the Neon API, see Deploy and manage functions.
Invoke
Once the deployment reaches
completed, retrieve the invocation URL:neon functions get helloThe
invocation_urlfield contains the public URL for your function:https://<branch_id>-<slug>.compute.<cell>.us-east-2.aws.neon.techCall it with curl:
curl https://<branch_id>-hello.compute.<cell>.us-east-2.aws.neon.techThe response is a JSON object with your branch's Postgres version:
{ "version": "PostgreSQL 17.x on ..., compiled by gcc ..." }
Need help?
Join our Discord Server to ask questions or see what others are doing with Neon. For paid plan support options, see Support.








