The standard path for accessing the Binance Node.js API is using the native crypto module to generate HMAC-SHA256 signatures combined with axios or undici for sending requests, or directly using community libraries like node-binance-api or binance-api-node. This article provides complete code for native encapsulation, popular SDK comparisons, WebSocket subscriptions, and TypeScript types—all of which can be run immediately after an npm install. If you don't have a Binance account yet, you can register on the Binance Official Website; new users can open an account via Free Registration.
1. Node.js SDK Comparison Table
| Library | Author | Weekly Downloads | Features | Recommended Use Case |
|---|---|---|---|---|
| node-binance-api | jaggedsoft | 30k+ | Comprehensive, callback-based | Quick script validation |
| binance-api-node | Ashlar | 50k+ | Promise + TypeScript friendly | Production TypeScript environments |
| @binance/connector | Official | 40k+ | Lightweight thin wrapper | Following API updates closely |
| ccxt | Community | 80k+ | Unified multi-exchange API | Cross-exchange quant trading |
| Custom axios + crypto | — | — | Maximum control | High-frequency market making |
2. Native crypto Signature + axios Encapsulation
1. Project Initialization
mkdir binance-node && cd binance-node
npm init -y
npm install axios dotenv
.env file:
BINANCE_API_KEY=your_key_here
BINANCE_SECRET_KEY=your_secret_here
2. Core Signature Encapsulation
src/client.js:
const crypto = require('crypto');
const axios = require('axios');
require('dotenv').config();
const API_KEY = process.env.BINANCE_API_KEY;
const SECRET_KEY = process.env.BINANCE_SECRET_KEY;
const BASE_URL = 'https://api.binance.com';
function sign(params) {
const query = new URLSearchParams(params).toString();
return crypto
.createHmac('sha256', SECRET_KEY)
.update(query)
.digest('hex');
}
async function request(method, path, params = {}, signed = false) {
const headers = {};
if (signed) {
params.timestamp = Date.now();
params.recvWindow = 5000;
params.signature = sign(params);
headers['X-MBX-APIKEY'] = API_KEY;
}
try {
const config = {
method,
url: `${BASE_URL}${path}`,
headers,
timeout: 10000,
};
if (method === 'GET' || method === 'DELETE') {
config.params = params;
} else {
config.data = new URLSearchParams(params).toString();
config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
const r = await axios(config);
return r.data;
} catch (err) {
if (err.response) {
const { code, msg } = err.response.data;
throw new Error(`Binance ${code}: ${msg}`);
}
throw err;
}
}
module.exports = { request, sign };
3. Account and Ticker Calls
src/account.js:
const { request } = require('./client');
async function getAccount() {
return request('GET', '/api/v3/account', {}, true);
}
async function getPrice(symbol) {
const r = await request('GET', '/api/v3/ticker/price', { symbol });
return parseFloat(r.price);
}
async function getDepth(symbol, limit = 20) {
return request('GET', '/api/v3/depth', { symbol, limit });
}
async function placeLimitOrder(symbol, side, quantity, price) {
return request('POST', '/api/v3/order', {
symbol,
side,
type: 'LIMIT',
timeInForce: 'GTC',
quantity,
price,
}, true);
}
async function cancelOrder(symbol, orderId) {
return request('DELETE', '/api/v3/order', { symbol, orderId }, true);
}
module.exports = { getAccount, getPrice, getDepth, placeLimitOrder, cancelOrder };
4. Running the Example
index.js:
const { getAccount, getPrice, placeLimitOrder } = require('./src/account');
(async () => {
try {
const account = await getAccount();
const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
console.log('Non-zero balances:');
nonZero.forEach(b => console.log(` ${b.asset}: ${b.free}`));
const btc = await getPrice('BTCUSDT');
console.log(`BTC Latest Price: $${btc}`);
// Place a limit order (10% below current price to avoid immediate fill)
const testPrice = (btc * 0.9).toFixed(2);
const order = await placeLimitOrder('BTCUSDT', 'BUY', '0.001', testPrice);
console.log(`Order ${order.orderId} created`);
} catch (e) {
console.error('Failed:', e.message);
}
})();
Run:
node index.js
3. Quick Solution with node-binance-api
1. Installation
npm install node-binance-api
2. Usage Example
const Binance = require('node-binance-api');
const binance = new Binance().options({
APIKEY: process.env.BINANCE_API_KEY,
APISECRET: process.env.BINANCE_SECRET_KEY,
useServerTime: true, // Sync with server time automatically
recvWindow: 10000,
test: false, // Set to true to use the testnet
});
// Check balances
binance.balance((error, balances) => {
if (error) return console.error(error);
Object.keys(balances).forEach(asset => {
const available = parseFloat(balances[asset].available);
if (available > 0) {
console.log(`${asset}: ${available}`);
}
});
});
// Market Buy
binance.marketBuy('BTCUSDT', 0.001, (error, response) => {
if (error) return console.error(error.body);
console.log('Market buy successful:', response);
});
// Limit Order
binance.buy('BTCUSDT', 0.001, 60000, { type: 'LIMIT' }, (error, response) => {
if (error) return console.error(error.body);
console.log('Limit order placed:', response.orderId);
});
// Promise Style
(async () => {
const ticker = await binance.prices('BTCUSDT');
console.log('Current price:', ticker.BTCUSDT);
const candles = await binance.candlesticks('BTCUSDT', '1h', false, { limit: 100 });
console.log('Recent K-lines:', candles.length);
})();
4. binance-api-node (Promise / TypeScript)
1. Installation
npm install binance-api-node
npm install -D typescript @types/node
2. TypeScript Example
import Binance, { Binance as BinanceClient, OrderType, OrderSide } from 'binance-api-node';
const client: BinanceClient = Binance({
apiKey: process.env.BINANCE_API_KEY!,
apiSecret: process.env.BINANCE_SECRET_KEY!,
});
async function main() {
// Automatic type inference
const time = await client.time();
console.log('Server time:', new Date(time));
const account = await client.accountInfo();
const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
console.log(`Holding ${nonZero.length} assets`);
const depth = await client.book({ symbol: 'BTCUSDT', limit: 20 });
console.log(`Bid 1: ${depth.bids[0].price}, Ask 1: ${depth.asks[0].price}`);
// Order with type checking
const order = await client.order({
symbol: 'BTCUSDT',
side: OrderSide.BUY,
type: OrderType.LIMIT,
timeInForce: 'GTC',
quantity: '0.001',
price: '60000.00',
});
console.log('Order ID:', order.orderId);
}
main().catch(console.error);
5. Real-time WebSocket Subscriptions (ws library)
const WebSocket = require('ws');
function subscribeTickers(symbols) {
const streams = symbols.map(s => `${s.toLowerCase()}@ticker`).join('/');
const url = `wss://stream.binance.com:9443/stream?streams=${streams}`;
function connect() {
const ws = new WebSocket(url);
ws.on('open', () => console.log(`Subscribed to ${symbols.length} pairs`));
ws.on('message', (raw) => {
const { stream, data } = JSON.parse(raw);
console.log(`${data.s}: Latest Price ${data.c}, 24h Change ${data.P}%`);
});
ws.on('pong', () => console.log('Received pong'));
ws.on('close', () => {
console.log('Connection closed, reconnecting in 5s');
setTimeout(connect, 5000);
});
ws.on('error', (err) => console.error('WS Error:', err.message));
// Send ping every 3 minutes to keep alive
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) ws.ping();
}, 180000);
}
connect();
}
subscribeTickers(['BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT']);
6. Futures API Node.js Example
const crypto = require('crypto');
const axios = require('axios');
const FAPI = 'https://fapi.binance.com';
function signFutures(params, secret) {
const query = new URLSearchParams(params).toString();
return crypto.createHmac('sha256', secret).update(query).digest('hex');
}
async function futuresPlaceOrder(apiKey, secret, symbol, side, quantity, price) {
const params = {
symbol,
side,
type: 'LIMIT',
timeInForce: 'GTC',
quantity: quantity.toString(),
price: price.toString(),
timestamp: Date.now(),
};
params.signature = signFutures(params, secret);
const r = await axios.post(
`${FAPI}/fapi/v1/order`,
new URLSearchParams(params).toString(),
{
headers: {
'X-MBX-APIKEY': apiKey,
'Content-Type': 'application/x-www-form-urlencoded',
},
}
);
return r.data;
}
async function futuresSetLeverage(apiKey, secret, symbol, leverage) {
const params = { symbol, leverage, timestamp: Date.now() };
params.signature = signFutures(params, secret);
const r = await axios.post(
`${FAPI}/fapi/v1/leverage`,
new URLSearchParams(params).toString(),
{ headers: { 'X-MBX-APIKEY': apiKey } }
);
return r.data;
}
7. FAQ
Q1: Is Date.now() accurate enough in Node.js?
A: Yes. Date.now() returns a millisecond-precision timestamp (13 digits), which is exactly what the Binance API requires. Ensure your system clock is accurate in container environments (using chronyd or systemd-timesyncd).
Q2: Which is better for the Binance API, axios or node-fetch?
A: axios is well-suited for REST by default (automatic JSON parsing, error retries, connection pooling). node-fetch (native in Node 18+) is lighter but requires manual error handling. For high-frequency scenarios, undici or native http.Agent is recommended, offering up to 30% higher performance than axios.
Q3: How do I avoid as any in TypeScript?
A: Use binance-api-node, which comes with full type definitions, or generate types from official OpenAPI specs using openapi-typescript. Avoid generic request<any> wrappers.
Q4: What should I watch for with pm2?
A: If a WebSocket connection is lost, the Node event loop won't exit, so pm2 won't auto-restart. Implement reconnection logic (see section 5) and set max_memory_restart: '500M' to prevent memory leaks.
Q5: How do I implement rate limiting in Node.js?
A: Use the bottleneck library:
const Bottleneck = require('bottleneck');
const limiter = new Bottleneck({
minTime: 10, // Minimum 10ms interval
maxConcurrent: 20, // Maximum 20 concurrent requests
});
const wrappedGet = limiter.wrap(axios.get);
After reviewing the Node.js solutions, return to the Category Navigation to check other SDK tutorials in the "API Integration" category.