Synchronous MySQL Client
sync-mysql is a Node.js library that provides a synchronous interface for interacting with MySQL databases. Unlike most Node.js database drivers which are asynchronous and non-blocking, this package executes SQL queries in a blocking manner, making it suitable for simple scripts, command-line tools, initial setup routines, or test environments where blocking the event loop is acceptable or desired, rather than high-concurrency server applications. The current stable version is 3.0.1, published in late 2022. The release cadence is very slow, with significant gaps between major versions, suggesting a maintenance-only status. Its key differentiator is its synchronous API, which simplifies sequential database operations at the cost of Node.js's typical non-blocking benefits.
Common errors
-
Error: connect ECONNREFUSED
cause The MySQL server is not running, is inaccessible from the specified host, or the port is incorrect.fixEnsure your MySQL server is running, check the `host` and `port` in your connection configuration, and verify no firewall is blocking the connection. For Docker, ensure the database container is healthy and ports are exposed correctly. -
TypeError: MySql is not a constructor
cause Attempted to use `MySql` without correctly requiring it or using a named import when it's a default export.fixUse `const MySql = require('sync-mysql');` to correctly import the class. If using ESM, consider if `sync-mysql` is the right tool or if a CommonJS wrapper is needed. -
Error: Query arguments required (for parameterized query)
cause A placeholder `?` was used in the SQL query string, but no array of values was provided as the second argument to `connection.query()`.fixAlways provide an array of values as the second argument to `connection.query()` when using `?` placeholders. Example: `connection.query('SELECT * FROM users WHERE id = ?', [123])`. -
ReferenceError: assert is not defined
cause The `assert` module used in quickstart examples is a built-in Node.js module but needs to be explicitly required.fixAdd `const assert = require('assert');` at the top of your script to make the `assert` function available.
Warnings
- breaking The `sync-mysql` library performs synchronous I/O operations, which fundamentally blocks the Node.js event loop. This makes it unsuitable for server applications or any context requiring high concurrency, as it will halt all other processing until database operations complete. While not an API breaking change, adopting this library in an asynchronous Node.js application is a architectural anti-pattern and will lead to severe performance bottlenecks.
- gotcha Incorrectly concatenating strings into SQL queries can lead to severe SQL injection vulnerabilities. While `sync-mysql` provides parameterized queries via the second argument to `connection.query()`, developers might mistakenly build queries with string concatenation.
- gotcha The `sync-mysql` library does not natively support connection pooling or automatic reconnection strategies, common in modern database drivers. This can lead to issues with resource exhaustion or dropped connections over time in long-running processes.
- deprecated The library shows a very slow development cadence, with the last major release (v3.0.0) primarily bumping dependencies and fixing security vulnerabilities rather than adding significant new features or modernizing the API. It lacks features like async/await support, promise-based APIs, or robust TypeScript typings that are standard in modern Node.js ecosystems.
Install
-
npm install sync-mysql -
yarn add sync-mysql -
pnpm add sync-mysql
Imports
- MySql
import MySql from 'sync-mysql';
const MySql = require('sync-mysql'); - connection.query
connection.query('SELECT ' + someVar)connection.query('SELECT 1') - connection.getRecord
const record = connection.getRecord('users', { id: 1 });const record = connection.getRecord('users', 1);
Quickstart
const MySql = require('sync-mysql');
const assert = require('assert');
const connection = new MySql({
host: 'localhost',
user: process.env.DB_USER ?? 'root',
password: process.env.DB_PASSWORD ?? 'secret',
database: process.env.DB_NAME ?? 'test_db'
});
try {
const createTableResult = connection.query('CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255))');
console.log('Table creation result:', createTableResult);
const insertResult = connection.query("INSERT INTO users (name) VALUES (?) ", ['Alice']);
console.log('Insert result:', insertResult);
assert(insertResult.insertId > 0, 'User should be inserted');
const selectResult = connection.query('SELECT * FROM users WHERE id = ?', [insertResult.insertId]);
console.log('Select result:', selectResult);
assert(selectResult.length === 1, 'Should find the inserted user');
assert(selectResult[0].name === 'Alice', 'User name should be Alice');
const solution = connection.query('SELECT 1 + 1 AS solution');
assert(solution[0].solution === 2, 'Basic calculation failed');
console.log('Synchronous queries executed successfully.');
connection.end(); // It's good practice to end the connection when done.
} catch (error) {
console.error('An error occurred:', error.message);
// Ensure connection is ended even on error
if (connection && typeof connection.end === 'function') {
connection.end();
}
process.exit(1);
}