Microsoft SQL Server Client for Node.js
mssql is a robust and actively maintained Node.js client for Microsoft SQL Server, currently stable at version 12.3.1. It features a rapid release cadence, with multiple minor and patch versions frequently released, often within weeks, and major versions roughly annually. The library supports multiple underlying TDS drivers: the pure JavaScript `Tedious` driver (default) and the native `MSNodeSQLv8` driver, offering flexibility based on deployment environment and performance needs. It provides a modern API with support for async/await, Promises, ES6 tagged template literals, and streaming, alongside traditional callbacks. Key differentiators include its comprehensive API for managing connections, connection pools, and requests, as well as explicit support for SQL Server features like input/output parameters, stored procedure execution, and bulk inserts.
Common errors
-
TypeError: Do not know how to serialize a BigInt
cause Attempting to pass a JavaScript BigInt type as a parameter to a query in older versions of `mssql` that lacked proper BigInt serialization support.fixUpdate `mssql` to version 11.0.1 or higher. Alternatively, convert BigInt values to a compatible number or string type before passing them as parameters if an update is not possible. -
ConnectionError: Login failed for user 'yourusername'.
cause Incorrect username, password, or an issue with authentication mechanisms (e.g., Windows Authentication not configured, or SQL Server Authentication not enabled/user not mapped).fixVerify credentials, ensure the user exists and has correct permissions in the SQL Server database. Check if SQL Server Authentication is enabled if not using Windows Authentication. If using Windows Authentication, ensure `trustedConnection: true` is set and `msnodesqlv8` is correctly configured. -
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.
cause SQL Server is not running, TCP/IP is not enabled, firewall is blocking the connection, incorrect server name/IP, or incorrect port.fixEnsure SQL Server is running, TCP/IP is enabled in SQL Server Configuration Manager, and no firewall rules are blocking the specified port (default 1433). Verify the `server` and `port` (if specified) in your connection configuration. -
Error: Cannot find module 'msnodesqlv8' or module not found error when importing from 'mssql/msnodesqlv8'
cause The `msnodesqlv8` package was not installed or installed incorrectly, or the `msnodesqlv8` specific import path was used without the package being present.fixRun `npm install msnodesqlv8` in your project directory. Ensure you are importing correctly with `import sql from 'mssql/msnodesqlv8'` (or `require('mssql/msnodesqlv8')`) and not from the base `mssql` package if you intend to use this specific driver. -
Error: Global connection already exists. Call sql.close() first.
cause Attempting to call `sql.connect()` multiple times without first closing the previous global connection. This typically happens in development or when managing connections improperly outside a pool.fixEnsure `sql.close()` is called before attempting to establish a new global connection. For most applications, use connection pools (the default behavior when using `sql.connect(config)`) to manage multiple connections without needing to manually close and reopen the global connection for each operation.
Warnings
- breaking As of v12.0.0, configuration objects passed to `sql.connect()` are no longer cloned by the library. They are intended to be immutable and treated as readonly. Modifying these objects after passing them to `connect()` will result in undefined behavior.
- gotcha Microsoft SQL Server typically requires TCP/IP protocol to be enabled on the server instance for external connections. This is often disabled by default in fresh SQL Server installations or development environments.
- gotcha Connecting to Azure SQL Database or SQL Server with self-signed certificates requires specific `options` in the connection configuration, such as `encrypt: true` and `trustServerCertificate: true` (for self-signed certs). Incorrect settings will lead to connection failures.
- gotcha The `msnodesqlv8` driver offers native performance and Windows Authentication, but it requires a separate `npm install msnodesqlv8` and then importing `sql` from `mssql/msnodesqlv8`. It also has specific OS requirements (Windows or Linux/macOS 64 bits).
- gotcha URL encoding is critical for connection strings, especially for passwords or server names containing special characters. Incorrect encoding can lead to parsing errors or failed authentication.
- gotcha BigInt type handling has seen various fixes across versions. In older versions (e.g., before v11.0.1) passing BigInt parameters could lead to `TypeError`. The `msnodesqlv8` driver specifically treats BigInt as a string.
Install
-
npm install mssql -
yarn add mssql -
pnpm add mssql
Imports
- sql
const sql = require('mssql')import sql from 'mssql'
- TYPES
import { SqlTypes } from 'mssql'import { TYPES } from 'mssql' - Request
import { Request } from 'mssql' - msnodesqlv8_driver
import { msnodesqlv8 } from 'mssql'import sql from 'mssql/msnodesqlv8'
Quickstart
import sql from 'mssql'; // Use require('mssql') for CommonJS
const sqlConfig = {
user: process.env.DB_USER ?? 'SA', // Use 'SA' or another user if not using Windows Auth
password: process.env.DB_PASSWORD ?? 'YourStrong@Password123!',
database: process.env.DB_NAME ?? 'master',
server: process.env.DB_SERVER ?? 'localhost', // or your server IP/hostname
pool: {
max: 10,
min: 0,
idleTimeoutMillis: 30000
},
options: {
encrypt: process.env.DB_ENCRYPT === 'true', // For Azure SQL, this should be true
trustServerCertificate: process.env.NODE_ENV !== 'production' // Change to true for local dev / self-signed certs
}
};
async function runDatabaseOperations() {
let pool; // Declare pool outside try block for finally access
try {
pool = await sql.connect(sqlConfig);
console.log('Successfully connected to SQL Server.');
// Example 1: Insert data using a parameterized query
const newProductName = 'Test Product ' + Date.now();
const insertResult = await pool.request()
.input('productName', sql.NVarChar, newProductName)
.input('price', sql.Decimal(10, 2), 19.99)
.query`INSERT INTO Products (Name, Price) VALUES (@productName, @price); SELECT SCOPE_IDENTITY() AS NewId;`;
console.log(`Inserted new product with ID: ${insertResult.recordset[0].NewId}`);
// Example 2: Select data
const selectResult = await pool.query`SELECT Id, Name, Price FROM Products WHERE Name LIKE '%Test Product%';`;
console.log('Selected products:', selectResult.recordset);
// Example 3: Execute a stored procedure (assuming 'GetProductById' exists)
// const productId = insertResult.recordset[0].NewId;
// const spResult = await pool.request()
// .input('id', sql.Int, productId)
// .execute('GetProductById');
// console.log('Stored procedure result:', spResult.recordset);
} catch (err) {
console.error('Database operation failed:', err.message);
// Implement robust error handling here, e.g., logging, retries
} finally {
if (pool) {
await pool.close();
console.log('Database connection closed.');
}
}
}
// Ensure a Products table exists for the examples
// CREATE TABLE Products (Id INT IDENTITY(1,1) PRIMARY KEY, Name NVARCHAR(255), Price DECIMAL(10, 2));
// Make sure to set DB_USER, DB_PASSWORD, DB_NAME, DB_SERVER environment variables
runDatabaseOperations();