Skip to content

Node.js MQTT Client for SiliconWit.io

In this tutorial, you will learn how to build a Node.js MQTT client that simulates an IoT device sending sensor telemetry data to the SiliconWit.io platform. The client connects to the SiliconWit.io MQTT broker over a secure TLS connection and publishes random sensor readings at regular intervals.

Node.js is well-suited for IoT applications thanks to its event-driven architecture and the mature mqtt npm package. This tutorial is useful for building device simulators, IoT gateways, or server-side MQTT integrations.

  • How to install and configure the mqtt npm package
  • How to establish a secure TLS connection to the SiliconWit.io MQTT broker
  • How to authenticate using device credentials
  • How to publish JSON telemetry data on a timed interval
  • How to handle connection events and automatic reconnection
RequirementDetails
Node.jsVersion 18 or later
npmIncluded with Node.js
SiliconWit.io AccountFree IoT platform account
A registered deviceCreated from the SiliconWit.io dashboard

Verify your Node.js installation:

Terminal window
node --version
npm --version

You will need the following credentials from your SiliconWit.io dashboard after registering a device:

CredentialExampleDescription
Device IDSWD-XXXXXXUnique device identifier (MQTT username and client ID)
Access Tokenyour-access-tokenMQTT password
Publish Topicd/{device_id}/tTopic for sending sensor data (d = device, t = telemetry)

Keep your access token secure. Never share it publicly or commit it to version control.

Before writing any code, set up a device on the platform so you have credentials to connect with.

  1. Log in to your SiliconWit.io dashboard.
  2. Navigate to Devices and click Add Device.
  3. Choose a device template or select Start from Scratch.
  4. Fill in the required fields:
    • Device Name: Node.js Sensor
    • Device Type: Sensor
    • Data Interval: 10 seconds (for testing; increase for production)
  5. In the Data Fields section, configure the fields your device will send. You can add them manually or import the following JSON:
[
{ "name": "temperature", "label": "Temperature", "unit": "°C" },
{ "name": "humidity", "label": "Humidity", "unit": "%" }
]
  1. Click Create Device.
  2. Copy your Device ID and Access Token from the device detail page. You will need these in the code below.

Create a new project directory and initialize it:

Terminal window
mkdir siliconwit-node-client
cd siliconwit-node-client
npm init -y

Install the mqtt package:

Terminal window
npm install mqtt

Your project structure should look like this:

siliconwit-node-client/
├── node_modules/
├── index.js
├── package.json
└── package-lock.json

Step 2: Understand the Connection Architecture

Section titled “Step 2: Understand the Connection Architecture”

The Node.js client connects directly to the SiliconWit.io MQTT broker using the mqtts:// protocol (MQTT over TLS):

┌─────────────────────────────────────────────────────────┐
│ SiliconWit.io Cloud │
│ │
│ Dashboard <--> MQTT Broker (TLS on port 8883) │
│ | │
│ Telemetry Topic │
│ d/{device_id}/t │
└────────────────────┬────────────────────────────────────┘
│ TLS 1.2 (port 8883)
┌────────────────────┴────────────────────────────────────┐
│ Node.js Client (mqtt package) │
│ │
│ - Connects with mqtts:// protocol │
│ - Authenticates with device_id + access_token │
│ - Publishes simulated sensor data every 10 seconds │
└─────────────────────────────────────────────────────────┘

The mqtt npm package supports TLS natively via the mqtts:// URL scheme. Node.js uses its built-in TLS module, which trusts the same CA certificates as your operating system.

const mqtt = require("mqtt");
const client = mqtt.connect("mqtts://mqtt.siliconwit.io:8883", {
clientId: DEVICE_ID,
username: DEVICE_ID,
password: ACCESS_TOKEN,
});

The mqtts:// prefix tells the client to use MQTT over TLS. No additional certificate configuration is needed.

The device simulator generates random sensor readings that mimic a real IoT device. Each telemetry message includes temperature, humidity, and a battery voltage level.

function generateSensorData() {
return {
temperature: parseFloat((20 + Math.random() * 15).toFixed(1)),
humidity: parseFloat((30 + Math.random() * 50).toFixed(1)),
battery_voltage: parseFloat((3.0 + Math.random() * 1.2).toFixed(2)),
};
}
FieldTypeRangeDescription
temperaturefloat20.0 - 35.0Simulated temperature in Celsius
humidityfloat30.0 - 80.0Simulated relative humidity percentage
battery_voltagefloat3.00 - 4.20Simulated battery level in volts

Use setInterval to publish telemetry data at regular intervals:

const PUBLISH_TOPIC = `d/${DEVICE_ID}/t`;
const TELEMETRY_INTERVAL = 10000; // 10 seconds in milliseconds
setInterval(() => {
if (client.connected) {
const data = generateSensorData();
const payload = JSON.stringify(data);
client.publish(PUBLISH_TOPIC, payload, { qos: 1 });
console.log(`[TELEMETRY] Sent: ${payload}`);
}
}, TELEMETRY_INTERVAL);

Create a file called index.js with the following complete code:

const mqtt = require("mqtt");
// ========== SILICONWIT IO MQTT CONFIGURATION ==========
const MQTT_BROKER = "mqtts://mqtt.siliconwit.io:8883";
const DEVICE_ID = "SWD-XXXXXX";
const ACCESS_TOKEN = "your-access-token";
const PUBLISH_TOPIC = `d/${DEVICE_ID}/t`;
// ========== TIMING ==========
const TELEMETRY_INTERVAL = 10000; // milliseconds
// ========== SENSOR SIMULATION ==========
function generateSensorData() {
return {
temperature: parseFloat((20 + Math.random() * 15).toFixed(1)),
humidity: parseFloat((30 + Math.random() * 50).toFixed(1)),
battery_voltage: parseFloat((3.0 + Math.random() * 1.2).toFixed(2)),
};
}
// ========== MAIN ==========
console.log("=== Node.js MQTT Device Simulator -> SiliconWit.io ===\n");
// Create MQTT client with TLS
const client = mqtt.connect(MQTT_BROKER, {
clientId: DEVICE_ID,
username: DEVICE_ID,
password: ACCESS_TOKEN,
protocol: "mqtts",
reconnectPeriod: 5000,
connectTimeout: 30000,
keepalive: 60,
});
// ========== EVENT HANDLERS ==========
client.on("connect", () => {
console.log("[MQTT] Connected to SiliconWit.io");
// Send initial telemetry immediately on connect
const data = generateSensorData();
const payload = JSON.stringify(data);
client.publish(PUBLISH_TOPIC, payload, { qos: 1 });
console.log(`[TELEMETRY] Sent: ${payload}`);
});
client.on("reconnect", () => {
console.log("[MQTT] Reconnecting...");
});
client.on("disconnect", () => {
console.log("[MQTT] Disconnected");
});
client.on("error", (err) => {
console.error(`[MQTT] Error: ${err.message}`);
});
client.on("offline", () => {
console.log("[MQTT] Client offline");
});
// ========== TELEMETRY LOOP ==========
let messageCount = 0;
const telemetryInterval = setInterval(() => {
if (client.connected) {
const data = generateSensorData();
const payload = JSON.stringify(data);
client.publish(PUBLISH_TOPIC, payload, { qos: 1 }, (err) => {
if (err) {
console.error(`[TELEMETRY] Publish error: ${err.message}`);
} else {
messageCount++;
console.log(`[TELEMETRY] #${messageCount} Sent: ${payload}`);
}
});
} else {
console.log("[MQTT] Not connected, skipping telemetry...");
}
}, TELEMETRY_INTERVAL);
// ========== GRACEFUL SHUTDOWN ==========
function shutdown() {
console.log("\n[INFO] Shutting down...");
clearInterval(telemetryInterval);
client.end(false, {}, () => {
console.log(`[INFO] Disconnected. Sent ${messageCount} messages. Goodbye.`);
process.exit(0);
});
}
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);

Run the simulator:

Terminal window
node index.js

Expected output:

=== Node.js MQTT Device Simulator -> SiliconWit.io ===
[MQTT] Connected to SiliconWit.io
[TELEMETRY] Sent: {"temperature":27.3,"humidity":52.1,"battery_voltage":3.85}
[TELEMETRY] #1 Sent: {"temperature":24.8,"humidity":61.4,"battery_voltage":4.02}
[TELEMETRY] #2 Sent: {"temperature":31.2,"humidity":38.7,"battery_voltage":3.54}

Press Ctrl+C to stop the simulator gracefully.

  1. Log in to your SiliconWit.io dashboard.
  2. Navigate to your registered device.
  3. You should see temperature, humidity, and battery voltage updating every 10 seconds.
  4. SiliconWit.io automatically detects and displays each data field.

Step 8: Running as a Background Process (Optional)

Section titled “Step 8: Running as a Background Process (Optional)”

For long-running simulators or production gateways, you can use a process manager like pm2:

Terminal window
npm install -g pm2
pm2 start index.js --name siliconwit-simulator
pm2 save
pm2 startup

Useful pm2 commands:

CommandDescription
pm2 logs siliconwit-simulatorView live logs
pm2 restart siliconwit-simulatorRestart the process
pm2 stop siliconwit-simulatorStop the process
pm2 statusShow all running processes
SymptomCauseSolution
ECONNREFUSEDWrong broker address or portVerify the MQTT_BROKER URL includes mqtts:// and port 8883.
UNABLE_TO_VERIFY_LEAF_SIGNATURECA certificate issueUpdate Node.js to the latest LTS version. Run npm config set strict-ssl false as a workaround.
Error: Not authorizedInvalid credentialsVerify DEVICE_ID and ACCESS_TOKEN match your SiliconWit.io dashboard.
ETIMEOUTFirewall blocking port 8883Check that outbound port 8883 is allowed on your network.
Repeated reconnect eventsNetwork instabilityCheck your internet connection. Increase reconnectPeriod.
SymptomCauseSolution
Publish callback receives errorClient not connectedThe client.connected check should prevent this. Verify connection.
Data not showing on dashboardWrong topic formatTopic must be exactly d/{device_id}/t.
Payload too largeJSON exceeds limitSiliconWit.io accepts up to 10KB. Keep payloads small.
SymptomCauseSolution
Cannot find module 'mqtt'Package not installedRun npm install mqtt in the project directory.
High memory usage over timeMemory leakEnsure you are not accumulating data in arrays or closures.
Process exits unexpectedlyUnhandled rejectionAdd process.on('unhandledRejection', console.error) for debugging.

In this tutorial, you built a Node.js device simulator that:

  • Connects securely to the SiliconWit.io MQTT broker over TLS using the mqtts:// protocol
  • Authenticates with your Device ID and Access Token
  • Publishes simulated sensor data (temperature, humidity, battery voltage) as JSON every 10 seconds
  • Handles automatic reconnection and graceful shutdown
  • Can be run as a background service using pm2

This pattern is ideal for testing your SiliconWit.io setup, simulating multiple devices, or building Node.js IoT gateways that aggregate and forward data from connected sensors.