PGlite Socket
A socket implementation for PGlite enabling remote connections. This package is a simple wrapper around the net
module to allow PGlite to be used as a PostgreSQL server.
There are two main components to this package:
PGLiteSocketServer
- A TCP server that allows PostgreSQL clients to connect to a PGlite database instance.PGLiteSocketHandler
- A low-level handler for a single socket connection to PGlite. This class handles the raw protocol communication between a socket and PGlite, and can be used to create a custom server.
The package also includes a CLI for quickly starting a PGlite socket server.
INFO
As PGlite is a single-connection database, it is not possible to have multiple simultaneous connections open. This means that the socket server will only support a single client connection at a time. While a PGLiteSocketServer
or PGLiteSocketHandler
are attached to a PGlite instance they hold an exclusive lock preventing any other connections, or queries on the PGlite instance.
Installation
npm install @electric-sql/pglite-socket
# or
yarn add @electric-sql/pglite-socket
# or
pnpm add @electric-sql/pglite-socket
Usage
import { PGlite } from '@electric-sql/pglite'
import { PGLiteSocketServer } from '@electric-sql/pglite-socket'
// Create a PGlite instance
const db = await PGlite.create()
// Create and start a socket server
const server = new PGLiteSocketServer({
db,
port: 5432,
host: '127.0.0.1',
})
await server.start()
console.log('Server started on 127.0.0.1:5432')
// Handle graceful shutdown
process.on('SIGINT', async () => {
await server.stop()
await db.close()
console.log('Server stopped and database closed')
process.exit(0)
})
API
PGLiteSocketServer
Creates a TCP server that allows PostgreSQL clients to connect to a PGlite database instance.
Options
db: PGlite
- The PGlite database instanceport?: number
- The port to listen on (default: 5432)host?: string
- The host to bind to (default: 127.0.0.1)path?: string
- Unix socket path to bind to (takes precedence over host:port)inspect?: boolean
- Print the incoming and outgoing data to the console (default: false)
Methods
start(): Promise<void>
- Start the socket serverstop(): Promise<void>
- Stop the socket server
Events
listening
- Emitted when the server starts listeningconnection
- Emitted when a client connectserror
- Emitted when an error occursclose
- Emitted when the server is closed
PGLiteSocketHandler
Low-level handler for a single socket connection to PGlite. This class handles the raw protocol communication between a socket and PGlite.
Options
db: PGlite
- The PGlite database instancecloseOnDetach?: boolean
- Whether to close the socket when detached (default: false)inspect?: boolean
- Print the incoming and outgoing data to the console in hex and ascii (default: false)
Methods
attach(socket: Socket): Promise<PGLiteSocketHandler>
- Attach a socket to this handlerdetach(close?: boolean): PGLiteSocketHandler
- Detach the current socket from this handlerisAttached: boolean
- Check if a socket is currently attached
Events
data
- Emitted when data is processed through the handlererror
- Emitted when an error occursclose
- Emitted when the socket is closed
Example
import { PGlite } from '@electric-sql/pglite'
import { PGLiteSocketHandler } from '@electric-sql/pglite-socket'
import { createServer, Socket } from 'net'
// Create a PGlite instance
const db = await PGlite.create()
// Create a handler
const handler = new PGLiteSocketHandler({
db,
closeOnDetach: true,
inspect: false,
})
// Create a server that uses the handler
const server = createServer(async (socket: Socket) => {
try {
await handler.attach(socket)
console.log('Client connected')
} catch (err) {
console.error('Error attaching socket', err)
socket.end()
}
})
server.listen(5432, '127.0.0.1')
CLI Usage
This package provides a command-line interface for quickly starting a PGlite socket server.
# Install globally
npm install -g @electric-sql/pglite-socket
# Start a server with default settings (in-memory database, port 5432)
pglite-server
# Start a server with custom options
pglite-server --db=/path/to/database --port=5433 --host=0.0.0.0 --debug=1
# Using short options
pglite-server -d /path/to/database -p 5433 -h 0.0.0.0 -v 1
# Show help
pglite-server --help
CLI Options
-d, --db=PATH
- Database path (default: memory://)-p, --port=PORT
- Port to listen on (default: 5432)-h, --host=HOST
- Host to bind to (default: 127.0.0.1)-u, --path=UNIX
- Unix socket to bind to (takes precedence over host:port)-v, --debug=LEVEL
- Debug level 0-5 (default: 0)-r, --run=COMMAND
- Command to run after server starts--include-database-url
- Include DATABASE_URL in subprocess environment--shutdown-timeout=MS
- Timeout for graceful subprocess shutdown in ms (default: 5000)
Development Server Integration
The --run
option is particularly useful for development workflows where you want to use PGlite as a drop-in replacement for PostgreSQL. This allows you to wrap your development server and automatically provide it with a DATABASE_URL pointing to your PGlite instance.
# Start your Next.js dev server with PGlite
pglite-server --run "npm run dev" --include-database-url
# Start a Node.js app with PGlite
pglite-server --db=./dev-db --run "node server.js" --include-database-url
# Start multiple services (using a process manager like concurrently)
pglite-server --run "npx concurrently 'npm run dev' 'npm run worker'" --include-database-url
When using --run
with --include-database-url
, the subprocess will receive a DATABASE_URL
environment variable with the correct connection string for your PGlite server. This enables seamless integration with applications that expect a PostgreSQL connection string.
Benefits for Development
- Zero PostgreSQL installation - No need to install and manage PostgreSQL locally
- Faster startup - PGlite starts instantly compared to PostgreSQL
- Isolated databases - Each project can have its own database file
- Simplified setup - One command starts both database and application
- Automatic cleanup - Server shuts down gracefully when your app exits
Using in npm scripts
You can add the CLI to your package.json scripts for convenient execution:
{
"scripts": {
"db:start": "pglite-server --db=./data/mydb --port=5433",
"db:dev": "pglite-server --db=memory:// --debug=1",
"dev": "pglite-server --db=./dev-db --run 'npm run start:dev' --include-database-url",
"dev:clean": "pglite-server --run 'npm run start:dev' --include-database-url"
}
}
Then run with:
npm run dev # Start with persistent database
npm run dev:clean # Start with in-memory database
Unix Socket Support
For better performance in local development, you can use Unix sockets instead of TCP:
# Start server on a Unix socket
pglite-server --path=/tmp/pglite.sock --run "npm run dev" --include-database-url
# The DATABASE_URL will be: postgresql://postgres:postgres@/postgres?host=/tmp
Connecting to the server
Once the server is running, you can connect to it using any PostgreSQL client:
Using psql
# TCP connection
PGSSLMODE=disable psql -h localhost -p 5432 -d template1
# Unix socket connection (if using --path)
PGSSLMODE=disable psql -h /tmp -d template1
Using Node.js clients
// Using node-postgres
import pg from 'pg'
const client = new pg.Client({
host: 'localhost',
port: 5432,
database: 'template1',
})
await client.connect()
// Using postgres.js
import postgres from 'postgres'
const sql = postgres({
host: 'localhost',
port: 5432,
database: 'template1',
})
// Using environment variable (when using --include-database-url)
const sql = postgres(process.env.DATABASE_URL)
LLM Usage
PGlite with the socket server can be used as a drop-in replacement for PostgreSQL in development environments, and when combined with AI coding agents or app builders can significantly simplify development. It removes the need to install and manage PostgreSQL locally, or to connect to a remote database.
Example Prompt
This prompt will one-shot a working wish list app with PGlite in Bolt.new:
Please make a simple wish list app, it should have a single screen for adding items. There should be a single input for adding the text for the item. Keep it simple and minimal.
Show error messages inline in the UI, where the list is, when the backend fails to connect to the database.
Use TypeScript, React, and Vite for the front end app.
The server side should use TypeScript, tsx and Express with a Postgres database using the postgres.js lib and it's `sql` template literal syntax.
Please use concurrently to run both vite and the backend at the same time.
I want to use PGlite and its socket server for development - match these versions:
```
"@electric-sql/pglite": "^0.3.2",
"@electric-sql/pglite-socket": "^0.0.7",
```
Do something like this to run it:
```
"dev": "USE_PGLITE=true npx pglite-server -u /tmp/.s.PGSQL.5432 -r \"npm run dev:both\"",
"dev:both": "concurrently \"npm run dev:frontend\" \"npm run dev:backend\"",
"dev:frontend": "vite",
"dev:backend": "tsx watch server/index.ts",
```
and the postgres.js config should look something like this:
```
export const sql = process.env.USE_PGLITE
? postgres({
host: '/tmp/',
username: 'postgres',
password: 'postgres',
database: 'postgres',
max: 1,
connect_timeout: 0,
})
: postgres(connectionString, {
ssl: process.env.NODE_ENV === 'production',
});
```
Limitations and Tips
Important Limitations
- Remember that PGlite only supports one connection at a time. If you're unable to connect, make sure no other client is currently connected.
- SSL connections are NOT supported. For
psql
, set env varPGSSLMODE=disable
.
General Tips
- For development purposes, using an in-memory database (
--db=memory://
) is fastest but data won't persist after the server is stopped. - For persistent storage, specify a file path for the database (e.g.,
--db=./data/mydb
). - When using debug mode (
--debug=1
or higher), additional protocol information will be displayed in the console. - To allow connections from other machines, set the host to
0.0.0.0
with--host=0.0.0.0
. - When using
--run
, the server will automatically shut down if the subprocess exits with a non-zero code. - Use
--shutdown-timeout
to adjust how long to wait for graceful subprocess termination (default: 5 seconds).