Neon-compatible client for postgres.do - drop-in replacement for @neondatabase/serverless
npm install @dotdo/neon> Drop-in replacement for @neondatabase/serverless. Same API, edge-native performance.
Already using Neon? Just change this line:
``typescript
// Before
import { neon } from '@neondatabase/serverless'
// After
import { neon } from '@dotdo/neon'
`
That's it. Your code just works, now running on Cloudflare's edge.
---
You chose Neon for its serverless PostgreSQL promise. The API was clean, cold starts were acceptable, and your team shipped fast.
Then came the trade-offs:
- External: Migration to anything else means rewriting queries
- Internal: You don't want to refactor a working codebase
- Philosophical: You shouldn't have to choose between great DX and great performance
Your database sits in one region. Your users are everywhere. Every query travels hundreds of milliseconds. Your bills keep climbing.
---
@dotdo/neon is a drop-in compatibility layer that routes your existing Neon code to postgres.do - PostgreSQL running in Cloudflare Durable Objects at the edge.
No API changes. No query rewrites. Just swap the import.
---
`bash`
npm install @dotdo/neon
Find and replace across your codebase:
`typescript
// Before
import { neon, neonConfig, Pool, Client } from '@neondatabase/serverless'
// After
import { neon, neonConfig, Pool, Client } from '@dotdo/neon'
`
`typescript
// Before (Neon)
const sql = neon('postgres://user:pass@ep-xyz.us-east-2.aws.neon.tech/neondb')
// After (postgres.do)
const sql = neon('postgres://db.postgres.do/mydb')
`
Done. Every query you've written works unchanged.
---
| Before (Neon) | After (@dotdo/neon) |
|---------------|---------------------|
| Regional database | Edge database in 300+ locations |
| Pay per query | FREE reads via Cloudflare Cache |
| 50-200ms latency | Sub-10ms from the edge |
| Vendor lock-in | Standard PostgreSQL |
---
Without action:
- Monthly bills keep climbing with every query
- Users experience latency you can't optimize away
- Migration gets harder as your codebase grows
- You remain locked into a single vendor's pricing decisions
---
`typescript
import { neon } from '@dotdo/neon'
const sql = neon('postgres://db.postgres.do/mydb')
// Tagged template queries - works exactly like Neon
const users = await sqlSELECT * FROM users
// Parameters are SQL injection safe
const user = await sqlSELECT * FROM users WHERE id = ${userId}
// Full results with column metadata
const sqlFull = neon('postgres://...', { fullResults: true })
const result = await sqlFullSELECT * FROM users`
console.log(result.fields) // Column metadata
console.log(result.rows) // Data rows
`typescript
const sql = neon('postgres://db.postgres.do/mydb')
// Transaction callback syntax
const result = await sql.transaction([
sqlINSERT INTO users (name) VALUES ('Alice'),INSERT INTO audit_log (action) VALUES ('user_created')
sql,
])
// With isolation level
const result = await sql.transaction(
[
sqlUPDATE accounts SET balance = balance - 100 WHERE id = 1,UPDATE accounts SET balance = balance + 100 WHERE id = 2
sql,`
],
{ isolationLevel: 'Serializable' }
)
`typescript
import { Pool } from '@dotdo/neon'
const pool = new Pool({
connectionString: 'postgres://db.postgres.do/mydb'
})
const client = await pool.connect()
try {
const result = await client.query('SELECT * FROM users')
console.log(result.rows)
} finally {
client.release()
}
`
`typescript
import { Client } from '@dotdo/neon'
const client = new Client({
connectionString: 'postgres://db.postgres.do/mydb'
})
await client.connect()
const result = await client.query('SELECT * FROM users WHERE id = $1', [userId])
await client.end()
`
`typescript
import { neonConfig } from '@dotdo/neon'
// WebSocket constructor for Node.js environments
import ws from 'ws'
neonConfig.webSocketConstructor = ws
// Custom fetch implementation
neonConfig.fetchFunction = customFetch
// Custom endpoint transformation
neonConfig.fetchEndpoint = (host, port) => https://custom.postgres.do/sql`
---
| Feature | @neondatabase/serverless | @dotdo/neon |
|---------|--------------------------|-------------|
| neon() tagged templates | Yes | Yes |neon().transaction()
| | Yes | Yes |fullResults
| option | Yes | Yes |arrayMode
| option | Yes | Yes |authToken
| option | Yes | Yes |Pool
| class | Yes | Yes |Client
| class | Yes | Yes |neonConfig
| settings | Yes | Yes |NeonDbError
| | Yes | Yes |
| TypeScript types | Yes | Yes |
---
Full type definitions included:
`typescript
import type {
NeonQueryFunction,
FullQueryResults,
Field,
HTTPQueryOptions,
HTTPTransactionOptions,
PoolConfig,
ClientConfig,
QueryResult,
QueryConfig,
CustomTypesConfig,
NeonConfigType,
} from '@dotdo/neon'
// NeonDbError for error handling
import { NeonDbError } from '@dotdo/neon'
`
---
Create an HTTP query function.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| fullResults | boolean | false | Return fields metadata with rows |arrayMode
| | boolean | false | Return rows as arrays |fetchOptions
| | RequestInit | - | Custom fetch options |authToken
| | string \| () => string \| Promise | - | JWT for authorization |
Create a connection pool.
| Option | Type | Description |
|--------|------|-------------|
| connectionString | string | Database URL |max
| | number | Maximum pool size |
Create a single connection.
| Option | Type | Description |
|--------|------|-------------|
| connectionString | string | Database URL |
Global configuration object.
| Property | Type | Description |
|----------|------|-------------|
| webSocketConstructor | typeof WebSocket | WebSocket implementation |fetchFunction
| | typeof fetch | Custom fetch implementation |fetchEndpoint
| | (host, port, options?) => string | Endpoint transformation |wsProxy
| | string \| ((host, port) => string) | WebSocket proxy |poolQueryViaFetch
| | boolean | Route Pool queries via HTTP |
---
@dotdo/neon is part of the postgres.do ecosystem - PostgreSQL at the edge.
| Package | Description |
|---------|-------------|
| postgres.do | SQL tagged template client |
| @dotdo/postgres | Edge PostgreSQL server |
| @dotdo/supabase | Supabase-compatible client |
| @dotdo/mongodb` | MongoDB-compatible client |
---
- Documentation
- GitHub
- Neon API Reference (for API compatibility)
MIT