{"id":43379,"library":"mysql2-ssh","title":"mysql2-ssh","description":"Provides a wrapper around mysql2 to create a MySQL connection over an SSH tunnel using ssh2. Enables async/await patterns for establishing the tunnel and executing queries. Current version 1.2.0, forks grrr-amsterdam/mysql-ssh with modern async support. Key differentiator: simple Promise-based API versus older callback-based alternatives. Key differentiator: simple Promise-based API versus older callback-based alternatives. Requires both mysql2 and ssh2 as peer dependencies. Release cadence is low, mainly bug fixes.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/Engelswoord/mysql2-ssh","tags":["javascript","mysql","remote","tunnel","ssh"],"install":[{"cmd":"npm install mysql2-ssh","lang":"bash","label":"npm"},{"cmd":"yarn add mysql2-ssh","lang":"bash","label":"yarn"},{"cmd":"pnpm add mysql2-ssh","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"MySQL client library for executing queries over the SSH tunnel","package":"mysql2","optional":false},{"reason":"SSH2 client for creating the tunnel connection","package":"ssh2","optional":false}],"imports":[{"note":"Package is ESM-only (type: module). CommonJS require works but triggers warning; use import or dynamic import.","wrong":"const getConnection = require('mysql2-ssh').getConnection","symbol":"getConnection","correct":"import { getConnection } from 'mysql2-ssh'"},{"note":"close is a named export, not a method on the connection. Must be called to cleanly close the SSH tunnel.","wrong":"","symbol":"close","correct":"import { close } from 'mysql2-ssh'"},{"note":"In CJS projects, use dynamic import() instead of require() to avoid ESM/CJS mismatch.","wrong":"const { getConnection } = require('mysql2-ssh')","symbol":"getConnection and close","correct":"const { getConnection } = await import('mysql2-ssh')"}],"quickstart":{"code":"import { getConnection, close } from 'mysql2-ssh';\n\nconst sshConfig = {\n  host: process.env.SSH_HOST ?? '',\n  username: process.env.SSH_USER ?? '',\n  privateKey: require('fs').readFileSync(process.env.SSH_KEY_PATH ?? '')\n};\n\nconst dbConfig = {\n  host: 'localhost',\n  port: 3306,\n  user: process.env.DB_USER ?? '',\n  password: process.env.DB_PASS ?? '',\n  database: process.env.DB_NAME ?? ''\n};\n\nasync function query() {\n  try {\n    const connection = await getConnection(sshConfig, dbConfig);\n    const [rows] = await connection.query('SELECT 1 AS result');\n    console.log(rows);\n  } finally {\n    await close(); // Must close the tunnel after use\n  }\n}\n\nquery();","lang":"typescript","description":"Demonstrates async/await usage for creating an SSH tunnel to a MySQL database, running a query, and closing the tunnel."},"warnings":[{"fix":"Always call await close() in a finally block after your queries.","message":"Calling close() is mandatory to release the SSH tunnel; failing to do so keeps the tunnel open indefinitely.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use dynamic import: const { getConnection } = await import('mysql2-ssh')","message":"The package is ESM-only; using require() may work but can cause instability in pure CJS projects.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade Node.js to >=12.","message":"Node.js versions <12 are not supported due to async/await usage.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Convert key to OpenSSH format using ssh-keygen -p -m PEM -f keyfile","message":"SSH private key must be in OpenSSH format; other formats may cause errors.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"search_vec":"'/mysql-ssh':37 '1.2.0':32 'altern':54,67 'amsterdam':36 'api':48,61 'around':7 'async':40 'async/await':21 'base':47,53,60,66 'bug':81 'cadenc':77 'callback':52,65 'callback-bas':51,64 'connect':13 'creat':10 'current':30 'depend':75 'differenti':43,56 'enabl':20 'establish':24 'execut':28 'fix':82 'fork':33 'grrr':35 'grrr-amsterdam':34 'javascript':83 'key':42,55 'low':79 'main':80 'modern':39 'mysql':12,84 'mysql2':2,8,70 'mysql2-ssh':1 'older':50,63 'pattern':22 'peer':74 'promis':46,59 'promise-bas':45,58 'provid':4 'queri':29 'releas':76 'remot':85 'requir':68 'simpl':44,57 'ssh':3,16,87 'ssh2':19,72 'support':41 'tunnel':17,26,86 'use':18 'version':31 'versus':49,62 'wrapper':6","created_at":"2026-06-05T16:59:31.028274+00:00","updated_at":"2026-06-05T16:59:31.028274+00:00","problems":[{"fix":"Use 'await import('mysql2-ssh')' or set 'type': 'module' in package.json","cause":"Using require() in CJS instead of import or dynamic import()","error":"Error: getConnection is not a function"},{"fix":"Verify SSH credentials and key format; use ssh -i key user@host to test","cause":"SSH authentication failure (wrong key, passphrase, or username)","error":"Error: All configured authentication methods failed"},{"fix":"Ensure MySQL is running and accessible on the remote host; check dbConfig.host and port","cause":"MySQL server not running on remote host's localhost or incorrect port","error":"Error: connect ECONNREFUSED 127.0.0.1:3306"},{"fix":"npm install mysql2","cause":"Missing peer dependency mysql2","error":"Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'mysql2'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/Engelswoord/mysql2-ssh","github":"https://github.com/Engelswoord/mysql2-ssh","docs":null,"changelog":null,"pypi":null,"npm":"mysql2-ssh","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-05","next_check":"2026-09-03","install_tag":null}}