{"id":10403,"library":"mysql2","title":"MySQL2 Node.js Client","description":"mysql2 is a high-performance, native JavaScript MySQL client for Node.js, currently stable at version 3.22.1. It provides a robust and efficient way to interact with MySQL databases, emphasizing speed through a re-written protocol parser. The library maintains broad API compatibility with the popular 'Node MySQL' package while introducing advanced features such as comprehensive prepared statement support, binary log protocol, SSL/TLS encryption, and data compression. It also includes a first-class promise-based API wrapper for modern async/await patterns. mysql2 is under active development with a rapid release cadence, frequently pushing out bug fixes, performance improvements, and new features, including recent security enhancements like disabling the `mysql_clear_password` plugin by default and supporting `Symbol.dispose` for resource management.","status":"active","version":"3.22.1","language":"javascript","source_language":"en","source_url":"https://github.com/sidorares/node-mysql2","tags":["javascript","mysql","client","server","typescript"],"install":[{"cmd":"npm install mysql2","lang":"bash","label":"npm"},{"cmd":"yarn add mysql2","lang":"bash","label":"yarn"},{"cmd":"pnpm add mysql2","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"TypeScript type definitions for Node.js runtime environment, primarily for development.","package":"@types/node","optional":true}],"imports":[{"note":"For direct connections, less common than pooling in production. Use the promise wrapper for async/await.","wrong":"const createConnection = require('mysql2').createConnection;","symbol":"createConnection","correct":"import { createConnection } from 'mysql2';"},{"note":"Standard way to manage database connections in Node.js applications.","wrong":"const createPool = require('mysql2').createPool;","symbol":"createPool","correct":"import { createPool } from 'mysql2';"},{"note":"This specific import provides the promise-based API for `createConnection`, `createPool`, etc. It's a default export of an object containing the promise-wrapped functions.","wrong":"import { createConnection, createPool } from 'mysql2/promise';","symbol":"mysql/promise","correct":"import mysql from 'mysql2/promise';"},{"note":"Type import for explicit type annotations in TypeScript. Connection and Pool types are often used.","symbol":"Connection (type)","correct":"import type { Connection } from 'mysql2';"}],"quickstart":{"code":"import mysql from 'mysql2/promise';\nimport { RowDataPacket, OkPacket, ResultSetHeader } from 'mysql2';\n\nasync function runExample() {\n  const pool = mysql.createPool({\n    host: process.env.DB_HOST ?? 'localhost',\n    user: process.env.DB_USER ?? 'root',\n    password: process.env.DB_PASSWORD ?? 'password',\n    database: process.env.DB_DATABASE ?? 'test_db',\n    waitForConnections: true,\n    connectionLimit: 10,\n    queueLimit: 0\n  });\n\n  try {\n    // Create a table if it doesn't exist\n    await pool.execute<ResultSetHeader>(`\n      CREATE TABLE IF NOT EXISTS users (\n        id INT AUTO_INCREMENT PRIMARY KEY,\n        name VARCHAR(255) NOT NULL,\n        email VARCHAR(255) UNIQUE NOT NULL\n      )\n    `);\n    console.log('Table \"users\" ensured.');\n\n    // Insert a new user using a prepared statement\n    const name = 'Alice';\n    const email = 'alice@example.com';\n    const [insertResult] = await pool.execute<OkPacket>(\n      'INSERT INTO users (name, email) VALUES (?, ?)',\n      [name, email]\n    );\n    console.log(`Inserted user with ID: ${insertResult.insertId}`);\n\n    // Select users\n    const [rows] = await pool.execute<RowDataPacket[]>('SELECT id, name, email FROM users WHERE name = ?', [name]);\n    if (rows.length > 0) {\n      console.log('Found users:');\n      rows.forEach(row => {\n        console.log(`- ID: ${row.id}, Name: ${row.name}, Email: ${row.email}`);\n      });\n    } else {\n      console.log(`No user found with name: ${name}`);\n    }\n\n  } catch (error) {\n    console.error('Database operation failed:', error);\n  } finally {\n    // Ensure the pool is closed when done\n    await pool.end();\n    console.log('Database pool closed.');\n  }\n}\n\nrunExample();","lang":"typescript","description":"This quickstart demonstrates how to establish a connection pool, execute a prepared statement for inserting data, and query for data using the `mysql2/promise` API with async/await, and proper resource management."},"warnings":[{"fix":"If needed, set `authPlugins.mysql_clear_password.enabled = true` in your connection or pool options. However, it's recommended to use stronger authentication methods.","message":"The `mysql_clear_password` authentication plugin is now disabled by default for enhanced security. Users relying on this plugin must explicitly enable it in connection options if still required.","severity":"breaking","affected_versions":">=3.22.0"},{"fix":"Upgrade to `v3.22.1` or later to ensure correct async stack trace reporting.","message":"A regression in async stack trace reporting was introduced by a previous fix and patched in `v3.22.1`. If upgrading from versions between `v3.22.0` and `v3.22.1`, async stack traces might point to incorrect source locations.","severity":"breaking","affected_versions":"3.22.0"},{"fix":"Upgrade to `v3.19.1` or newer to mitigate these security risks.","message":"Security vulnerabilities related to out-of-bounds reads in null-terminated string parsing and potential Denial-of-Service (DoS) from malformed geometry payloads were addressed.","severity":"breaking","affected_versions":"<3.19.1"},{"fix":"For `BIGINT`, set `supportBigNumbers: true` and `bigNumberStrings: true` in your connection options to receive them as strings. For `DATETIME`/`TIMESTAMP`, consider `dateStrings: true` to avoid JavaScript `Date` object limitations.","message":"When handling `BIGINT` or `DECIMAL` types, Node.js's default number precision limits might lead to data loss. Options like `supportBigNumbers`, `bigNumberStrings`, and `dateStrings` should be carefully configured.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Change your import from `import { createPool } from 'mysql2';` to `import mysql from 'mysql2/promise';` and use `await mysql.createPool(...)` and `await pool.execute(...)`.","message":"For modern asynchronous code, it is highly recommended to use the promise-based API by importing `mysql2/promise` instead of the callback-based API from `mysql2` directly.","severity":"gotcha","affected_versions":">=1.5.0"},{"fix":"Always use `connection.execute(sql, [values])` or `pool.execute(sql, [values])` for queries with user-supplied data, rather than `connection.query()` with string interpolation.","message":"When using prepared statements with `pool.execute()` or `connection.execute()`, parameter values are passed as an array and correctly escaped. Avoid string concatenation for parameters to prevent SQL injection.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"search_vec":"'3.22.1':20 'activ':91 'advanc':56 'also':73 'api':46,82 'async/await':86 'base':81 'binari':64 'broad':45 'bug':101 'cadenc':97 'class':78 'clear':116 'client':3,13,129 'compat':47 'comprehens':60 'compress':71 'current':16 'data':70 'databas':32 'default':120 'develop':92 'disabl':113 'effici':26 'emphas':33 'encrypt':68 'enhanc':111 'featur':57,107 'first':77 'first-class':76 'fix':102 'frequent':98 'high':8 'high-perform':7 'improv':104 'includ':74,108 'interact':29 'introduc':55 'javascript':11,127 'librari':43 'like':112 'log':65 'maintain':44 'manag':126 'modern':85 'mysql':12,31,52,115,128 'mysql2':1,4,88 'nativ':10 'new':106 'node':51 'node.js':2,15 'packag':53 'parser':41 'password':117 'pattern':87 'perform':9,103 'plugin':118 'popular':50 'prepar':61 'promis':80 'promise-bas':79 'protocol':40,66 'provid':22 'push':99 'rapid':95 're':38 're-written':37 'recent':109 'releas':96 'resourc':125 'robust':24 'secur':110 'server':130 'speed':34 'ssl/tls':67 'stabl':17 'statement':62 'support':63,122 'symbol.dispose':123 'typescript':131 'version':19 'way':27 'wrapper':83 'written':39","created_at":"2026-04-18T08:58:38.500585+00:00","updated_at":"2026-04-19T05:46:55.849360+00:00","problems":[{"fix":"Verify the MySQL server status, check network connectivity, firewall rules, and ensure the `host`, `port` and `bind-address` in your MySQL server configuration allow connections from your application's host.","cause":"The MySQL server is not running, is inaccessible from the client, or network configuration is blocking the connection.","error":"Error: Can't connect to MySQL server on 'localhost' (111)"},{"fix":"Ensure proper error handling for queries and connection releases. For pooled connections, `pool.execute()` and `pool.query()` should handle connection reuse, but persistent connection issues may indicate server problems or network instability. Consider increasing connection timeout.","cause":"This often occurs when the connection state is corrupted, frequently due to unexpected server disconnections, network issues, or sometimes mixing callback and promise APIs on the same connection.","error":"UnhandledPromiseRejectionWarning: Error: Packet sequence number wrong"},{"fix":"Change your import statement to `import mysql from 'mysql2/promise';` and create your pool using `mysql.createPool(...)`. The promise API uses `execute` for prepared statements.","cause":"You are likely trying to call `execute` on a pool object created using the standard `mysql2` import, not the `mysql2/promise` import.","error":"TypeError: pool.execute is not a function"},{"fix":"Double-check your `user`, `password`, and `database` credentials. Ensure the MySQL user exists and has `GRANT` privileges for your application's host and the target database.","cause":"Incorrect username or password, or the user lacks permissions to connect from the specified host or access the database.","error":"Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'youruser'@'localhost' (using password: YES)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":"https://sidorares.github.io/node-mysql2/","github":"https://github.com/sidorares/node-mysql2","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/mysql2","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}