Convert pg, mysql2, or ioredis code to Bun
Paste your existing database client code and get the Bun.SQL or Bun.redis equivalent instantly. Nothing saved, nothing sent anywhere.
How the converter works
- 1
Select your source library
Pick the tab matching your current code: pg (node-postgres), mysql2, or ioredis. Each tab loads the conversion rules specific to that library's syntax.
- 2
Paste your code
Drop in your existing connection setup, query calls, transaction blocks, or Redis commands. The converter works with real code snippets, not connection strings.
- 3
Pattern detection
The converter scans your code for known patterns: import statements, connection constructors (new Pool, createConnection, new Redis), query methods (.query(), .execute()), placeholder syntax ($1, ?), and Redis flag arguments ("EX", "NX").
- 4
Syntax transformation
Each detected pattern is rewritten to Bun's equivalent. Positional placeholders become tagged template interpolation. Manual transaction boilerplate becomes sql.begin(). Redis string flags become an options object.
- 5
Boilerplate removal
Import statements, explicit .connect() calls, .end()/.quit() calls, and .rows accessors are removed because Bun's built-in clients handle these automatically.
- 6
Explanation output
The "What changed and why" panel lists every transformation applied to your specific code, so you understand the difference rather than just copying the output.
What the output means
The converter produces two outputs: the rewritten code and a list of changes. Here is what each change category means.
Import removal
Bun.SQL and Bun.redis are global built-ins. There is no package to import. The converter strips require/import statements for pg, mysql2, and ioredis.
// Before: import { Pool } from "pg";
// After: (removed entirely)Connection rewrite
new Pool(), createConnection(), and new Redis() become Bun.sql() or Bun.redis(). Connection pooling is automatic in Bun.SQL, so pool configuration is simplified.
// Before: const pool = new Pool({ connectionString: url });
// After: const pool = Bun.sql(url);Placeholder conversion
pg uses $1, $2 positional placeholders. mysql2 uses ? placeholders. Both are converted to JavaScript tagged template interpolation (${variable}), which Bun.SQL parameterizes automatically to prevent SQL injection.
// Before: query('SELECT * FROM users WHERE id = $1', [userId])
// After: sql`SELECT * FROM users WHERE id = ${userId}`Transaction simplification
Manual BEGIN/COMMIT/ROLLBACK with try/catch becomes a single sql.begin() call. Bun handles commit on success and rollback on exception automatically.
// Before: await client.query('BEGIN'); try { ... } catch { await client.query('ROLLBACK'); }
// After: await sql.begin(async (tx) => { ... });Redis options conversion
ioredis passes Redis command flags as positional strings ("EX", 3600, "NX"). Bun.redis uses a typed options object ({ ex: 3600, nx: true }), which is less error-prone.
// Before: redis.set("key", "val", "EX", 60)
// After: redis.set("key", "val", { ex: 60 })Lifecycle cleanup
.connect(), .end(), .quit(), and .disconnect() calls are removed. Bun manages connection lifecycle automatically: lazy connect on first use, cleanup on process exit.
// Before: await pool.end();
// After: (removed entirely)Bun.SQL and Bun.redis syntax reference
Quick reference for the most common operations in Bun's built-in database clients.
Bun.SQL (Postgres, MySQL, SQLite)
Connect
const sql = Bun.sql("postgres://user:pass@localhost/db");Simple query
const users = await sql`SELECT * FROM users`;Parameterized
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;Insert
await sql`INSERT INTO users (name, email) VALUES (${name}, ${email})`;Transaction
await sql.begin(async (tx) => {
await tx`UPDATE accounts SET balance = balance - ${amount} WHERE id = ${from}`;
await tx`UPDATE accounts SET balance = balance + ${amount} WHERE id = ${to}`;
});SQLite
import { Database } from "bun:sqlite";
const db = new Database("app.db");Bun.redis
Connect
const redis = Bun.redis();
// Uses REDIS_URL env var by defaultGET / SET
await redis.set("key", "value");
const val = await redis.get("key");SET with expiry
await redis.set("session:abc", data, { ex: 3600 });SET if not exists
await redis.set("lock:job", "1", { ex: 30, nx: true });Hash operations
await redis.hset("user:1", { name: "Alice", role: "admin" });
const name = await redis.hget("user:1", "name");Pipeline
const pipeline = redis.pipeline();
pipeline.set("a", "1");
pipeline.set("b", "2");
await pipeline.exec();When to use this tool
| Scenario | Source | What to paste |
|---|---|---|
| Evaluating Bun.SQL for a new project | pg or mysql2 | Your typical query pattern (CRUD, joins, transactions) |
| Migrating an Express + pg app to Bun | pg | Connection setup + a few representative queries |
| Replacing ioredis with Bun.redis | ioredis | SET/GET with options, pipeline blocks |
| Learning Bun.SQL syntax | Any | Load the built-in example to see the conversion |
| Checking transaction syntax | pg or mysql2 | Your BEGIN/COMMIT/ROLLBACK block |
| Team migration kickoff | Any | 3-5 common query patterns to establish team conventions |
Frequently Asked Questions
What does the Bun Snippet Converter do?
It takes code written for pg (node-postgres), mysql2, or ioredis and rewrites it into the equivalent Bun.SQL or Bun.redis syntax. The conversion handles the most common patterns: connection setup, parameterized queries, transactions, and Redis commands with options.
This saves you from manually translating placeholder syntax ($1, ?) to tagged template literals, removing boilerplate like .connect() and .end(), and converting Redis flag arguments to options objects.
How does Bun.SQL compare to pg (node-postgres)?
| Bun.SQL | pg (node-postgres) | |
|---|---|---|
| Install | Built-in, zero dependencies | npm install pg |
| Connection | Bun.sql() with auto-pooling | new Pool() with manual config |
| Query syntax | Tagged template: sqlSELECT ${id} | String + array: query('...', [id]) |
| Transactions | sql.begin(async tx => { ... }) | Manual BEGIN/COMMIT/ROLLBACK |
| Result format | Returns array directly | Returns { rows, fields } object |
| Ecosystem | Bun-only, growing | Mature, broad ORM support |
Is my code sent to a server?
No. All conversion runs entirely in your browser using pattern-based string transformation. Nothing is uploaded, stored, or transmitted. You can verify this by opening your browser's network tab while using the tool.
How do I convert a pg transaction to Bun.SQL?
In pg, transactions use manual BEGIN/COMMIT/ROLLBACK queries wrapped in try/catch. Bun.SQL replaces this with a single sql.begin() call that handles commit and rollback automatically.
await client.query('BEGIN');
try {
await client.query('UPDATE accounts SET balance = balance - $1 WHERE id = $2', [amount, from]);
await client.query('UPDATE accounts SET balance = balance + $1 WHERE id = $2', [amount, to]);
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
}await sql.begin(async (tx) => {
await tx`UPDATE accounts SET balance = balance - ${amount} WHERE id = ${from}`;
await tx`UPDATE accounts SET balance = balance + ${amount} WHERE id = ${to}`;
});How does the ioredis SET with EX and NX convert?
ioredis passes Redis flags as positional string arguments. Bun.redis uses an options object instead, which is less error-prone and easier to read.
await redis.set("lock:job-123", "1", "EX", 30, "NX");await redis.set("lock:job-123", "1", { ex: 30, nx: true });What patterns are not supported yet?
The converter handles the most common query, connection, transaction, and command patterns. These patterns are deferred to a future version:
- pg LISTEN/NOTIFY and cursor-based streaming
- mysql2 prepared statement caching with .prepare()
- ioredis Lua scripting (.defineCommand(), .eval())
- ioredis Cluster mode (new Redis.Cluster())
- Batch conversion of multiple queries in a single file