Promise MySQL Wrapper
promise-mysql is a Node.js library that provides a promise-based wrapper around the `mysqljs/mysql` driver. It leverages the Bluebird promise library to transform the traditional callback-based API of `node-mysql` into an asynchronous, promise-returning interface, supporting `async/await` patterns. Currently at version 5.2.0, this package has not seen a major release in over four years, with its core dependency, `mysqljs/mysql`, also being largely unmaintained. While it differentiates itself by offering promise support for the widely used `node-mysql` driver, modern applications might opt for `mysql2/promise` for native promise support and better performance and features. Its release cadence has been infrequent, indicating a mature but largely static project.
Common errors
-
Cannot find module 'mysql'
cause The `promise-mysql` package is a wrapper and depends on the `mysql` package (specifically `mysqljs/mysql`) as a peer dependency. This error occurs if `mysql` is not installed alongside `promise-mysql`.fixInstall the underlying MySQL driver: `npm install mysql` or `yarn add mysql`. -
Error: Connection lost: The server closed the connection.
cause This error often indicates that the MySQL server unexpectedly closed the connection, possibly due to inactivity timeouts, server restarts, or network issues. While `promise-mysql` has a `reconnect` option (default `true`), persistent connection loss indicates deeper issues.fixEnsure your MySQL server is stable and accessible. Check server logs for connection errors. For long-running applications, utilize connection pools (`mysql.createPool`) rather than individual connections (`mysql.createConnection`), as pools inherently handle connection re-establishment and rotation. If `reconnect` is explicitly set to `false`, consider enabling it. -
TypeError: connection.query is not a function
cause This usually happens if you're trying to call `query` on an object that isn't a valid `promise-mysql` connection or pool object, or if `connection` itself is `undefined` because `createConnection` or `getConnection` failed or wasn't awaited.fixVerify that `mysql.createConnection()` or `pool.getConnection()` were successfully `await`ed and resolved to a valid connection object. Ensure you are calling `query` on the object returned by these methods. Also, avoid mixing `promise-mysql` with the callback-based `mysqljs/mysql` API directly.
Warnings
- gotcha This package wraps `mysqljs/mysql` (v2.x), which is largely unmaintained (last update over 4 years ago). For new projects or better performance, consider `mysql2/promise` (v3.x or later) which offers native promise support, prepared statements, and active development.
- gotcha Promise-mysql uses the Bluebird promise library internally. While functional, modern Node.js versions have highly optimized native Promises. Relying on Bluebird adds an extra dependency and can occasionally lead to subtle interop issues or differences in promise behavior compared to native Promises.
- breaking Upgrading from `promise-mysql` v3 to v4 changed `mysql.createPool` to return a `Promise` directly, rather than the pool object itself. This was a significant shift in the API's asynchronous behavior.
- gotcha Connections from a pool *must* be explicitly released back to the pool using `connection.release()` when they are no longer needed. Failing to do so will lead to connection leaks, eventually exhausting the pool and causing 'Too many connections' errors or connection timeouts.
Install
-
npm install promise-mysql -
yarn add promise-mysql -
pnpm add promise-mysql
Imports
- createConnection
import { createConnection } from 'promise-mysql';import mysql from 'promise-mysql'; const connection = await mysql.createConnection(options);
- createPool
import { createPool } from 'promise-mysql';const mysql = require('promise-mysql'); const pool = await mysql.createPool(options); - query
connection.query('SELECT * FROM users', (err, rows) => {});const [rows, fields] = await connection.query('SELECT * FROM users');
Quickstart
const mysql = require('promise-mysql');
async function runDbOperations() {
let connection; // Declare connection outside try block for finally
try {
connection = await mysql.createConnection({
host: process.env.DB_HOST ?? 'localhost',
user: process.env.DB_USER ?? 'root',
password: process.env.DB_PASSWORD ?? 'password',
database: process.env.DB_NAME ?? 'test_db'
});
console.log('Database connected successfully!');
// Create a table if it doesn't exist
await connection.query(`
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL
);
`);
console.log('Users table ensured.');
// Insert a new user
const insertResult = await connection.query('INSERT INTO users (name, email) VALUES (?, ?)', ['Alice', 'alice@example.com']);
console.log('Inserted user:', insertResult.insertId);
// Select all users
const users = await connection.query('SELECT * FROM users');
console.log('Users:', users);
// Clean up (optional: delete the user for idempotency)
await connection.query('DELETE FROM users WHERE email = ?', ['alice@example.com']);
console.log('Cleaned up user.');
} catch (err) {
console.error('Database operation failed:', err);
} finally {
if (connection) {
await connection.end();
console.log('Connection closed.');
}
}
}
runDbOperations();