Node.js / JavaScript quickstart
Read a public BTC price and receive a WebSocket update with binance in Node.js. No API key or TypeScript compiler is needed. Prices are BTCUSDT last traded prices.
Create the project
Use Node.js 24 with npm. Download the complete Node.js JavaScript starter, or copy the files below.
mkdir binance-node-quickstart
cd binance-node-quickstartCopy the files below, or extract the downloaded archive into this directory (adjust the download path if needed):
tar -xzf ~/Downloads/node.tar.gzInstall the dependencies after saving or extracting the files:
npm installThe SDK installs from latest. The archive contains both an import example and a require example. Choose either command below; both make the same public requests.
Project files
package.json
{
"name": "binance-node-quickstart",
"private": true,
"type": "module",
"scripts": {
"start": "node prices.js",
"start:require": "node prices.cjs"
},
"dependencies": {
"binance": "latest"
}
}market.js
export const endpoints = {"rest": "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT", "websocket": "wss://stream.binance.com:9443"};
export function client(sdk) { return new sdk.MainClient({}, {timeout:15000}); }
export async function read(client) {
const response = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
if (Array.isArray(response)) throw new Error('Expected one ticker');
return response.price;
}
export function stream(sdk, logger) { return new sdk.WebsocketClient({}, logger); }
export const event = 'message';
export function value(message) { return message.e === '24hrTicker' ? message.c : undefined; }
export async function subscribe(ws) { await ws.subscribeSpotSymbol24hrTicker('btcusdt'); }price.js
import * as sdk from 'binance';
import * as market from './market.js';
function positivePrice(value) {
if (!Number.isFinite(Number(value)) || Number(value) <= 0) {
throw new Error('The exchange did not return a positive BTC price.');
}
return String(value);
}
export async function readPrice() {
return positivePrice(await market.read(market.client(sdk)));
}
// Returns cleanup without waiting for subscription acknowledgement.
export function watchPrice(onPrice, onError) {
const ws = market.stream(sdk);
let stopped = false;
const receive = message => {
const value = market.value(message);
if (!stopped && value !== undefined) {
clearTimeout(deadline);
try { onPrice(positivePrice(value)); } catch (error) { fail(error); }
}
};
const fail = error => { if (!stopped) onError(error); };
const deadline = setTimeout(() => fail(new Error('No BTC update within 30 seconds. Check network access.')), 30000);
ws.on(market.event, receive);
ws.on('exception', fail);
// React may clean up an effect before its queued subscription starts.
Promise.resolve().then(async () => {
if (stopped) return;
try {
await market.subscribe(ws);
} finally {
// A connection may finish opening after cleanup was requested.
if (stopped) ws.closeAll();
}
}).catch(fail);
return () => {
if (stopped) return;
stopped = true;
clearTimeout(deadline);
ws.closeAll();
ws.removeListener(market.event, receive);
ws.removeListener('exception', fail);
};
}prices.js
import process from 'node:process';
import { readPrice, watchPrice } from './price.js';
async function main() {
console.log('BTC REST price:', await readPrice());
let stop;
try {
const price = await new Promise((resolve, reject) => {
stop = watchPrice(resolve, reject);
});
console.log('BTC WebSocket price:', price);
} finally {
stop?.();
console.log('WebSocket closed.');
}
}
main().catch(error => {
console.error(error.message || String(error));
process.exitCode = 1;
});market.cjs
const endpoints = {"rest": "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT", "websocket": "wss://stream.binance.com:9443"};
function client(sdk) { return new sdk.MainClient({}, {timeout:15000}); }
async function read(client) {
const response = await client.getSymbolPriceTicker({ symbol: 'BTCUSDT' });
if (Array.isArray(response)) throw new Error('Expected one ticker');
return response.price;
}
function stream(sdk, logger) { return new sdk.WebsocketClient({}, logger); }
const event = 'message';
function value(message) { return message.e === '24hrTicker' ? message.c : undefined; }
async function subscribe(ws) { await ws.subscribeSpotSymbol24hrTicker('btcusdt'); }
module.exports = { endpoints, client, read, stream, event, value, subscribe };price.cjs
const sdk = require('binance');
const market = require('./market.cjs');
function positivePrice(value) {
if (!Number.isFinite(Number(value)) || Number(value) <= 0) {
throw new Error('The exchange did not return a positive BTC price.');
}
return String(value);
}
async function readPrice() {
return positivePrice(await market.read(market.client(sdk)));
}
// Returns cleanup without waiting for subscription acknowledgement.
function watchPrice(onPrice, onError) {
const ws = market.stream(sdk);
let stopped = false;
const receive = message => {
const value = market.value(message);
if (!stopped && value !== undefined) {
clearTimeout(deadline);
try { onPrice(positivePrice(value)); } catch (error) { fail(error); }
}
};
const fail = error => { if (!stopped) onError(error); };
const deadline = setTimeout(() => fail(new Error('No BTC update within 30 seconds. Check network access.')), 30000);
ws.on(market.event, receive);
ws.on('exception', fail);
// React may clean up an effect before its queued subscription starts.
Promise.resolve().then(async () => {
if (stopped) return;
try {
await market.subscribe(ws);
} finally {
// A connection may finish opening after cleanup was requested.
if (stopped) ws.closeAll();
}
}).catch(fail);
return () => {
if (stopped) return;
stopped = true;
clearTimeout(deadline);
ws.closeAll();
ws.removeListener(market.event, receive);
ws.removeListener('exception', fail);
};
}
module.exports = { readPrice, watchPrice };prices.cjs
const process = require('node:process');
const { readPrice, watchPrice } = require('./price.cjs');
async function main() {
console.log('BTC REST price:', await readPrice());
let stop;
try {
const price = await new Promise((resolve, reject) => {
stop = watchPrice(resolve, reject);
});
console.log('BTC WebSocket price:', price);
} finally {
stop?.();
console.log('WebSocket closed.');
}
}
main().catch(error => {
console.error(error.message || String(error));
process.exitCode = 1;
});Run
For ES modules with import:
npm start
# Equivalent: node prices.jsFor CommonJS with require:
npm run start:require
# Equivalent: node prices.cjsBoth examples print a REST price and the first valid WebSocket price, close the client in finally, then exit. SDK connection logs may also appear.
BTC REST price: 65000.5
BTC WebSocket price: 65001.2
WebSocket closed.The .js files use import because package.json sets "type": "module". The .cjs files use require even in that project. These are Node.js module rules, not a TypeScript requirement.
Troubleshooting
- If Node says
require is not defined, useprices.cjsfor the CommonJS example. If it rejectsimport, keep"type": "module"for the.jsfiles. - If the SDK cannot be resolved, run
npm installin the directory containingpackage.json. - For a rejected HTTP request or no update within 30 seconds, allow the HTTPS and WSS endpoints in
market.jsormarket.cjs. Exchange regional restrictions apply. - See Runtime compatibility for recorded runtime versions and WebSocket subscriptions for continuous streams and shutdown.