Skip to content

Release v5.5.0

Latest

Choose a tag to compare

@TimelordUK TimelordUK released this 12 Sep 14:13
· 6 commits to master since this release

What's changed

Prebuilt binaries now ship inside the npm package. npm install msnodesqlv8 no longer downloads anything and no longer compiles anything on a supported platform — the right binary is already in the package and is selected at require time. This is the headline change and the reason for the minor bump.

  • Bundled per-platform N-API binaries via prebuildify; prebuild-install is gone (#451)
  • Production dependency tree cut from 15 packages to 2, both zero-dependency: node-addon-api + node-gyp-build
  • node-abi dropped as a dependency — nothing in the shipped package used it
  • Publishing now builds the package it publishes, and fails if any platform binary is missing (#452)
  • Package size 242 kB → 2.25 MB, which is the trade for never fetching a binary at install time

Closes the long-standing offline-install reports #263 and #365, and the prebuildify suggestion on #343. #259 asked for exactly this back in 2022.

Full Changelog: v5.4.0...v5.5.0

Upgrading

npm install msnodesqlv8

from source for non cpp dev contribution

# clone to node_modules/msnodelsqlv8 e.g. /dev/sql/v8/node_modules/msnodesqlv8
# from folder if you do not wish to build the src code, download the binary

npm run fetch-prebuild

# change  .\.env-cmdrc for your connection string e.g. LOCAL18
# is  "Driver={ODBC Driver 18 for SQL Server}; Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;",

No code changes. Two things you may notice:

  • prebuild-install and node-abi disappear from your dependency tree. If you allowlist, pin or audit dependencies, that list gets shorter.
  • The download is larger and the install is faster, because nothing is fetched or built.

If you had a workaround for install failures — vendored tarballs, a prebuild mirror, --build-from-source, a committed build/Release — you can drop it.


Prebuilt binaries ship inside the npm package

Since 5.5.0 the per-platform N-API binary is bundled in the published package. There is no download at install time and no compile step on a supported platform — npm install unpacks the right binary and that is the whole install.

This means the package installs behind a corporate proxy, from an Artifactory or Nexus mirror, on an airgapped host, and under npm ci --ignore-scripts.

node_modules/msnodesqlv8/prebuilds/
├── win32-x64/msnodesqlv8.node
├── darwin-arm64/msnodesqlv8.node
└── linux-x64/
    ├── msnodesqlv8.glibc.node
    └── msnodesqlv8.musl.node

The correct file is selected at require time, by platform, architecture and libc — not pinned at install time. One binary per platform serves every Node line and every Electron version, because the addon is pure N-API with no V8 ABI coupling.

Platform Bundled Notes
Windows x64 yes
Linux x64 (glibc) yes built on Ubuntu 22.04, needs glibc 2.35+
Linux x64 (musl) yes Alpine, built in node:22-alpine
macOS arm64 yes Apple Silicon
macOS x64 (Intel) no compiles from source on install
Linux arm64 no compiles from source on install
Windows arm64 no compiles from source on install

Where there is no bundled binary the install script falls back to a node-gyp source build, which needs a C++ toolchain and the unixODBC headers.

Runtime requirements: any Node with N-API ≥ 8 (engines: node >=18), and any Electron with N-API ≥ 8. Electron needs no electron-rebuild and no Electron-specific artifact — verified in this release against Electron 41 (ABI 145) and Electron 43 (ABI 148), both served by the same single binary.

Each bundled binary is built and smoke tested on its own platform in CI before the package is assembled, and the release is blocked if any of the four is missing.

Installing without any network access

Because the binaries are plain files with predictable names, there are three ways to place one, in increasing order of scope:

  1. Normal installnpm install msnodesqlv8. Works with --ignore-scripts; nothing is fetched or built.
  2. Global installnpm install -g msnodesqlv8 now succeeds with no network fetch of a binary. Note that npm's global node_modules is not on Node's module resolution path, so a project still needs NODE_PATH set to $(npm root -g) to require it.
  3. Beside the node executable — drop prebuilds/<platform>-<arch>/msnodesqlv8.node next to node itself and every project on that machine resolves it, with no per-project install.
Sample apps
description link
next js example, note cant run driver on UI thread. todo-with-nextjs_msnodesqlv8
next js example using app router, note cant run driver on UI thread. todo-with-nextjs-app-router_msnodesqlv8
using vite + express msnodesqlv8-vite
using in typescript msnodesqlv8_ts_sample
js example typings in IDE msnodesqlv8_yarn_sample
using sequelize msnodesqlv8-sequelize
using mssql msnodesqlv8_mssql_sample
using electron msnodesqlv8-electron
using react msnodesqlv8-react

All nine were installed from this release's package and run against SQL Server 2022 as part of verifying it.

Quick start

JavaScript:

const sql = require('msnodesqlv8')

const connectionString = "Driver={ODBC Driver 18 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;"
const query = 'SELECT top 2 * FROM syscolumns'

async function runner () {
  const res = await sql.promises.query(connectionString, query)
  console.log(JSON.stringify(res, null, 4))
}

runner().then(() => console.log('done.')).catch(e => console.error(e))

TypeScript:

import sql from 'msnodesqlv8'
import Connection = MsNodeSqlV8.Connection
import ConnectionPromises = MsNodeSqlV8.ConnectionPromises

async function t () {
  const connectionString = "Driver={ODBC Driver 18 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;"
  const con: Connection = await sql.promises.open(connectionString)
  const promises: ConnectionPromises = con.promises
  const res = await promises.query('select @@servername as server')
  console.log(JSON.stringify(res, null, 4))
  await con.promises.close()
}

t().then(() => console.log('closed'))
Feature highlights

Connection pool with transaction support. Pull a connection out of the pool, keep it busy for the life of a transaction, then commit or roll back and release it:

pool.beginTransaction(function (err, description) { /* description.connection.query() */ })
pool.commitTransaction(description, function (err) { /* IF (@@TRANCOUNT > 0) COMMIT TRANSACTION */ })
pool.rollbackTransaction(description, function (err) { /* IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION */ })

The same methods exist on the promised pool, plus a wrapper that commits on success and rolls back on a thrown error:

pool.promises.transaction(async function (description) {
  await description.connection.promises.query(`Do transaction query here`)
})

Pool growth strategies. exponential or gradual, so a burst of queries does not immediately open connections up to the ceiling:

const pool = new sql.Pool({
  connectionString,
  ceiling: 10,
  scalingStrategy: 'gradual',
  scalingIncrement: 3,
  scalingDelay: 0
})

Detailed logging. Switchable logging across both the JavaScript and C++ layers, to console or to a file, for seeing exactly what the driver is doing:

const sql = require('msnodesqlv8')

sql.logger.setLogLevel(sql.LogLevel.TRACE)
sql.logger.setConsoleLogging(true)

// sql.logger.setLogFile('/var/log/myapp/sql-trace.log')
// sql.logger.configureForDevelopment()                 // TRACE, console
// sql.logger.configureForProduction('/var/log/myapp')  // ERROR, file only
// sql.logger.configureForTesting()                     // SILENT
// sql.logger.setLogLevel(sql.LogLevel.SILENT)          // default for production
Migrating from 4.x

The 4.x → 5.x step is a large change and should be tested carefully before a production rollout.

  1. The C++ layer moved from nan to Node-API (N-API).
  2. Extensive switchable logging was added, to see exactly what the driver is doing.
  3. Building and testing moved to GitHub Actions.
  4. Linux support requires glibc 2.35+ (Ubuntu 22.04 or later). Earlier distributions must build the driver themselves.
  5. As close to a drop-in replacement for 4.x as possible.
  6. win32 (32-bit Windows) is no longer supported.
  7. Windows, Linux and macOS are the supported platforms.
  8. Alpine/musl was originally best-effort and out of scope. As of 5.5.0 a musl binary is built, smoke tested in CI and shipped in the package.