Node-OPCUA Server
The `node-opcua-server` package provides a pure JavaScript and TypeScript implementation of an OPC UA (Open Platform Communications Unified Architecture) server stack, designed for Node.js environments. It facilitates secure and reliable data exchange in industrial automation, M2M, and IoT applications. The project is under active development, with frequent minor and patch releases, currently stable at version 2.169.0. Key differentiators include its complete native Node.js implementation, comprehensive support for OPC UA standards including full OPC UA 1.05 compliance (featuring subtyped structures, unions, and optimized data type handling), and a robust, typed event system. It ships with full TypeScript type definitions, enhancing developer experience. While the core server is open-source (MIT licensed), Sterfive SAS offers commercial support and value-added companion modules for advanced features like PubSub, web proxying, optimized clients, and Global Discovery Services.
Common errors
-
Error: listen EADDRINUSE: address already in use :::4840
cause The configured OPC UA server port (default 4840) is already being used by another process on the system.fixChange the `port` in the `OPCUAServer` constructor to an available port, or stop the conflicting process. On Linux, use `sudo lsof -i :4840` to identify the process. -
Bad_SecurityChecksFailed (0x80030000)
cause The client's certificate is not trusted by the server, or there is a mismatch in security policies/modes, preventing a secure connection.fixEnsure the client's certificate is added to the server's trust list. Verify that the client and server are configured with compatible `securityMode` (e.g., `None`, `Sign`, `SignAndEncrypt`) and `securityPolicy` (e.g., `None`, `Basic256Sha256`). Regenerate certificates if they are expired or malformed. -
Error: Cannot find module 'node-opcua'
cause The `node-opcua` package is not installed or not resolvable in the current project context.fixRun `npm install node-opcua` in your project directory. If using a monorepo or specific sub-packages, ensure all dependencies are correctly linked or installed. -
Client unable to connect to opc.tcp://my-server-ip:4840/UA/MyAwesomeServer
cause The server is not accessible at the specified endpoint, possibly due to firewall rules, incorrect IP/hostname, or misconfigured advertised endpoints (especially in Docker/NAT environments).fixCheck server configuration for `port`, `resourcePath`, and especially `serverInfo.discoveryUrls` and `serverInfo.alternateEndpoints` if running behind NAT or Docker. Verify network connectivity and firewall settings. Ensure the server has started successfully without errors.
Warnings
- breaking Version 2.168.0 migrated core packages from `async` and `lodash` to native JavaScript patterns. While primarily internal, applications relying on implicit availability or specific behaviors of these dependencies within `node-opcua` might encounter unexpected issues or require adjustments.
- breaking The certificate management architecture has undergone several overhauls (v2.164.2, v2.167.0, v2.168.0), including `TrustListClient.addCertificate` now accepting certificate chains and a new typed event system for post-handshake notifications. Existing code for certificate handling or event listeners might need updates.
- gotcha For deployments behind Docker, NAT, or reverse proxies, correctly configuring 'Advertised Endpoints' (introduced in v2.165.0) is crucial. Incorrect configuration will lead to clients being unable to connect or browse the server, as the server advertises incorrect connection details.
- gotcha Major performance improvements and OPC UA 1.05 compliance updates, particularly for DataType handling (v2.163.0), might introduce subtle behavioral changes. Applications with complex information models or custom data types should be thoroughly tested.
- breaking Security upgrades, such as the Node.js runtime update to 20.19.6 in v2.159.0, highlight the importance of keeping your Node.js environment updated. Using outdated Node.js versions can expose your application to known vulnerabilities.
Install
-
npm install node-opcua-server -
yarn add node-opcua-server -
pnpm add node-opcua-server
Imports
- OPCUAServer
import OPCUAServer from 'node-opcua-server';
import { OPCUAServer } from 'node-opcua'; - DataType
import { DataType } from 'node-opcua-data-model';import { DataType } from 'node-opcua'; - Variant
import { Variant } from 'node-opcua-data-value';import { Variant } from 'node-opcua'; - StatusCodes
import { StatusCodes } from 'node-opcua'; - NodeId
import { NodeId } from 'node-opcua';
Quickstart
import { OPCUAServer, DataType, Variant, StatusCodes, NodeId } from 'node-opcua';
const server = new OPCUAServer({
port: 4840, // default OPC UA port
resourcePath: '/UA/MyAwesomeServer',
buildInfo: {
productName: 'My Awesome OPCUA Server',
buildNumber: '7658',
buildDate: new Date(2026, 3, 19)
}
});
async function startServer() {
await server.start();
console.log('Server started and listening on', server.endpoints[0].endpointUrl);
console.log('Press Ctrl+C to stop the server.');
server.on('post_initialize', () => {
// Define the address space
const addressSpace = server.engine.addressSpace;
if (!addressSpace) {
console.error('Address space not available.');
return;
}
const namespace = addressSpace.get = addressSpace.registerNamespace('http://mynamespace.com/UA/MyAwesomeServer/');
const device = namespace.addObject({
organizedBy: addressSpace.rootFolder.objects,
browseName: 'MyDevice'
});
let temperature = 25.0;
namespace.addVariable({
componentOf: device,
nodeId: 's=Temperature',
browseName: 'Temperature',
dataType: DataType.Double,
value: {
get: () => new Variant({
dataType: DataType.Double,
value: temperature
})
}
});
// Simulate temperature changes
setInterval(() => {
temperature = 20 + 10 * Math.sin(Date.now() / 10000); // Oscillation between 10 and 30
}, 1000);
console.log('Address space initialized with a Temperature variable.');
});
process.on('SIGINT', async () => {
console.log('Caught interrupt signal, shutting down server...');
await server.shutdown();
console.log('Server shut down.');
process.exit(0);
});
}
startServer().catch(console.error);