Node.js services—Express APIs, NestJS microservices, Lambda-style workers—join enterprise MQ fabrics through the ibm-mq npm package. It is not a pure JavaScript reimplementation of the protocol; it binds to the same C client libraries Java and C use, which means your Docker image must include IBM MQ client binaries and your connect options must still respect SVRCONN, listener ports, and MCAUSER authority on the mainframe-connected hub. Developers love async/await; MQI is inherently callback and native threaded under the hood—ibm-mq bridges that gap with promises. Misconfigured containers show Dll load errors before any business logic runs. This tutorial covers installation, Connx options, put and get with buffers, CCDT environment variables in Node, TLS in containers, graceful shutdown with MQDISC, clustering many replicas against MAXINST, and mapping MQRC to the same server checks Java teams use.
npm install ibm-mq adds the package to package.json. The host needs IBM MQ client installed—often from IBM redistributable tarball or copied from official container base image. node-gyp may compile native addons during install; build images need compiler toolchain in CI. Production runtime image copies /opt/mqm or equivalent client path and sets LD_LIBRARY_PATH. Alpine versus glibc musl issues break installs—use supported base images per IBM readme. Pin ibm-mq version to queue manager compatibility matrix.
| Option | Maps to | Example |
|---|---|---|
| QueueManager | QM name | QM_PROD |
| Channel | SVRCONN | API.SVRCONN |
| Host | CONNAME host | mq-prod.corp |
| Port | Listener port | 1414 |
| CcdtUrl | CCDT path | file path or env |
123456789101112131415const mq = require('ibm-mq'); const cno = new mq.MQCNO(); const cd = new mq.MQCD(); cd.ChannelName = 'ORDERS.API'; cd.ConnectionName = 'mq-prod.corp(1414)'; cno.ClientConn = cd; const qMgr = await mq.Connx('QM_PROD', cno); const od = new mq.MQOD(); od.ObjectName = 'ORDERS.IN'; const hObj = await mq.Open(qMgr, od, mq.MQOO_OUTPUT); const md = new mq.MQMD(); const pmo = new mq.MQPMO(); await mq.Put(qMgr, hObj, md, pmo, Buffer.from('hello')); await mq.Close(qMgr, hObj, 0); await mq.Disc(qMgr);
Use try/catch and inspect err.mqrc for reason codes. Await each step—race conditions from parallel Open without connect cause confusing errors. MQMD and MQPMO are objects with defaults from constructors per ibm-mq API. Binary payloads use Buffer; UTF-8 strings need agreed CCSID with mainframe consumers.
Set process.env.MQCHLLIB and process.env.MQCHLTAB before require and connect if using table-only configuration. Kubernetes downward API injects env from ConfigMap. For local dev, dotenv loads paths—never commit production CCDT with secrets. MQSERVER string works for single-channel hackathons.
TypeScript projects import ibm-mq with type definitions where available. NestJS providers wrap connection as injectable singleton—disconnect on module destroy. Serverless functions should open short connections per invocation only if cold start latency acceptable; otherwise use dedicated worker service. Event-driven consumers loop mq.Get with wait interval in async while with cancellation on SIGTERM.
ibm-mq is a JavaScript jacket on the C client—the jacket fits only if the C client is in the building (container image).
Your Node program asks the ibm-mq helper to call the MQ post office in the same language the post office already speaks (C), and the helper reports back in JavaScript.
Write async connect to ORDERS.API on QM1 with error logging for mqrc.
List Dockerfile layers needed for ibm-mq on Linux glibc.
Design graceful shutdown on SIGTERM for a Get loop consumer.
1. Node.js MQ package is:
2. ibm-mq requires:
3. Connect options include:
4. Async code should: