For now streaming doesnβt work with neon-http.
Get Started with Waddler and Neon
Waddler has native support for Neon connections with the neon-http
and neon-websockets
drivers. These use the neon-serverless driver under the hood.
With the neon-http
and neon-websockets
drivers, you can access a Neon database from serverless environments over HTTP or WebSockets instead of TCP. Querying over HTTP is faster for single, non-interactive transactions.
If you need session or interactive transaction support, or a fully compatible drop-in replacement for the pg
driver, you can use the WebSocket-based neon-serverless
driver. You can connect to a Neon database directly using Postgres
Basic file structure
This is the basic file structure of the project.
π¦ <project root>
β π src
β β π index.ts
β π .env
β π package.json
β π tsconfig.json
Step 1 - Install @neondatabase/serverless package
npm i waddler @neondatabase/serverless dotenv
npm i -D tsx
Step 2 - Setup connection variables
Create a .env
file in the root of your project and add your database connection variable:
DATABASE_URL=
Step 3 - Connect Waddler to the database
import { waddler } from 'waddler/neon-http';
const sql = waddler(process.env.DATABASE_URL);
If you need a synchronous connection, you can use our additional connection API, where you specify a driver connection and pass it to the Waddler instance.
import { neon } from '@neondatabase/serverless';
import { waddler } from 'waddler/neon-http';
const client = neon(process.env.DATABASE_URL!);
const sql = waddler({ client });
Step 4 - Create a table
(async () => {
await sql.unsafe(`create table users (
id integer primary key generated always as identity,
name varchar(255) not null,
age integer not null,
email varchar(255) not null unique
);
`);
})()
Step 5 - Seed and Query the database
Letβs update the src/index.ts
file with queries to create, read, update, and delete users
import 'dotenv/config';
import { waddler } from 'waddler/neon-http';
const sql = waddler(process.env.DATABASE_URL!);
async function main() {
const user = [
'John',
30,
'[email protected]',
];
await sql`insert into ${sql.identifier('users')} values ${sql.values([[sql.default, ...user]])};`;
console.log('New user created!')
const users = await sql`select * from ${sql.identifier('users')};`;
console.log('Getting all users from the database: ', users)
/*
const users: {
id: number;
name: string;
age: number;
email: string;
}[]
*/
await sql`update ${sql.identifier('users')} set age = ${31} where email = ${user[2]};`;
console.log('User info updated!')
await sql`delete from ${sql.identifier('users')} where email = ${user[2]};`;
console.log('User deleted!')
}
main();
Streaming
import 'dotenv/config';
import { Client } from '@neondatabase/serverless';
import { waddler } from 'waddler/neon-serverless';
import { queryStream } from 'waddler/extensions/pg-query-stream';
async function main() {
const client = new Client(process.env.DATABASE_URL!);
await client.connect();
const sql = waddler({ client, extensions: [queryStream()] });
const stream = sql`select * from users;`.stream();
console.log('Streaming users one at a time from the database.')
for await (const user of stream) {
console.log(user)
/*
const user: {
id: number;
name: string;
age: number;
email: string;
}
*/
}
await client.end();
}
main();
Step 6 - Run index.ts file
To run any TypeScript files, you have several options, but letβs stick with one: using tsx
Youβve already installed tsx
, so we can run our queries now
Run index.ts
script
npx tsx src/index.ts
We suggest using bun
to run TypeScript files. With bun
, such scripts can be executed without issues or additional
settings, regardless of whether your project is configured with CommonJS (CJS), ECMAScript Modules (ESM), or any other module format.
To run a script with bun
, use the following command:
bun src/index.ts
If you donβt have bun installed, check the Bun installation docs