How to send/write and receive/read (BIDI) USB Device Data from Javascript
Product JSPrintManager Published 05/13/2026 Updated 05/21/2026 Author Neodynamic
Overview
JSPrintManager supports Bidirectional (BIDI) USB Device Communication from Javascript allowing you to Send/Write & Receive/Read data strings to any USB Device reachable from the client system. Based on pure Javascript code, you can enable BIDI USB Device Comm on any web page (written on top of any Web Platform including ASP.NET MVC/CORE, PHP, Django, Ruby On Rails (RoR), Express.js, Angular, React, Vue).
In this walkthrough, you'll learn how to Send/Write & Receive/Read data strings from Javascript through any USB Device reachable from the client machine. This solution works with any popular browser like Chrome, Firefox, IE/Edge & Safari on Windows!
Follow up these steps
-
JSPrintManager Client App
Be sure you install in your dev machine JSPrintManager (JSPM) (Available for Windows, Linux, Raspberry Pi, Android & Mac)
IMPORTANT: This small app must be installed on each client! -
HTML & Script References
- Download JSPrintManager.js
- Copy all of these *.js files to the same folder where the next
index.htmlpage sample will be located in. - By using your favorite Web Development IDE or Text Editor, create a new HTML file naming it
index.html
Copy/paste the following code inside that html file:
<!DOCTYPE html> <html> <head> <title>JSPrintManager</title> <meta charset="utf-8" /> </head> <body> <div style="text-align:center"> <h1>BIDI USB Device Comm from Javascript</h1> <hr /> <div> <label> USB Device Path <select id="usbDevice"></select> </label> <br /><br /> <button type="button" onclick="doOpen();"> Open </button> <button type="button" onclick="doClose();"> Close </button> </div> <br /><br /> <div> <label> <strong>Data to Send</strong> <input id="txtDataToSend" value="type here..." /> </label> <button onclick="doSendData();">Send...</button> </div> <hr /> <div> <textarea id="txtDataReceived" readOnly style="background-color:#302a2a;color:#fff;font-family: 'Courier New', Courier, monospace;" cols="100" rows="10"></textarea> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/3.3.5/bluebird.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <!--IMPORTANT: BE SURE YOU HONOR THIS JS LOAD ORDER--> <script src="JSPrintManager.js"></script> <script> var _usbComm = null; var _dataToSend = ''; var _dataReceived = ''; var _this = this; //JSPrintManager WebSocket settings JSPM.JSPrintManager.auto_reconnect = true; JSPM.JSPrintManager.start(); JSPM.JSPrintManager.WS.onStatusChanged = function () { if (jspmWSStatus()) { //get usb devices JSPM.JSPrintManager.getUsbDevices().then(function (usbList) { var options = ''; for (var i = 0; i < usbList.length; i++) { options += '<option>' + usbList[i] + '</option>'; } $('#usbDevice').html(options); }); } }; //Check JSPM WebSocket status function jspmWSStatus() { if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Open) return true; else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Closed) { console.warn('JSPrintManager (JSPM) is not installed or not running! Download JSPM Client App from https://neodynamic.com/downloads/jspm'); return false; } else if (JSPM.JSPrintManager.websocket_status == JSPM.WSStatus.Blocked) { alert('JSPM has blocked this website!'); return false; } } //Sending data to USB device function doSendData() { if (!this._usbComm) { this._dataReceived += "USB Comm is not created!\r\n"; this.refreshDisplay(); } else { this._dataToSend = $('#txtDataToSend').val(); if (this._dataToSend.length > 0) { this._usbComm.send(this._dataToSend); this._dataReceived += "> " + this._dataToSend + "\r\n"; this.refreshDisplay(); } } } function doOpen() { this._usbComm = new JSPM.USBComm($('#usbDevice').val()); this._usbComm.onDataReceived = function (data) { _this.dataReceived += "< " + data + "\r\n"; console.log("Data Received:" + data); _this.refreshDisplay(); }; this._usbComm.onError = function (data, is_critical) { _this.dataReceived += "ERROR: " + data + "\r\n"; console.log("Error: " + data); _this.refreshDisplay(); }; this._usbComm.onClose = function (data) { _this.dataReceived += "COMM CLOSED!" + "\r\n"; console.log("Closed: " + data); _this.refreshDisplay(); }; this._usbComm.connect().then(_ => { _this.dataReceived += "COMM OPEN!" + "\r\n"; _this.refreshDisplay(); }); } function doClose() { if (!this._usbComm) { this._dataReceived += "USB Comm is not open!\r\n"; this.refreshDisplay(); } else this._usbComm.close(); } function refreshDisplay() { $('#txtDataReceived').val(this._dataReceived); } </script> </body> </html>
- That's it! Run your website and test it.