CCXT vs ccxws
ccxws was the realtime companion to CCXT's REST API, archived in 2023. What the same streaming job looks like in CCXT Pro today, and what ccxws still did better.
ccxws — "A JavaScript library for connecting to realtime public APIs on all cryptocurrency exchanges" — was written to be used with CCXT, not instead of it. Its README says so directly: "CCXWS uses similar market structures to those generated by the CCXT library. This allows interoperability between the RESTful interfaces provided by CCXT and the realtime interfaces provided by CCXWS." For several years that pairing — CCXT for REST, ccxws for the socket — was the standard way to build a Node.js market-data pipeline.
The repository was archived by its owner on 9 September 2023 and is read-only. So the useful question is not which library wins; it is what the same job looks like now, and what you lose by moving.
TL;DR
- If you have a working ccxws integration, it is MIT-licensed and still on npm at 0.47.0 (published 8 October 2021). Nothing stops it running; it will not receive fixes when a venue changes its stream format.
- The replacement is CCXT Pro, which is bundled in the
ccxtpackage under the same MIT licence — no separate install, no paid tier. It streams from 76 exchanges, and thewatch*methods return the same structures as the matchingfetch*methods. - ccxws still does one thing CCXT does not: level 3, order-by-order book streams. CCXT's unified order book is aggregated level 2. If you depend on L3, that is a real gap to plan around.
At a glance
| CCXT (with CCXT Pro) | ccxws | |
|---|---|---|
| Status | actively released | archived by its owner on 9 September 2023, read-only |
| Latest release | continuous — v4.5.77 | npm 0.47.0, published 8 October 2021 |
| Most recent commit | continuous | 8 October 2021 |
| Scope | REST + WebSocket, public and private, market data and trading | public realtime streams only |
| Exchanges | 104 with REST, 76 with WebSocket | 35 clients listed in the README table |
| Languages | TypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java, Rust | TypeScript / JavaScript |
| Packages to install | 1 (ccxt) | 1 (ccxws), usually alongside ccxt for markets |
| Programming model | await exchange.watch_trades(symbol) | client.on('trade', handler) + client.subscribeTrades(market) |
| Order books | merged, maintained, checksum-verified where the venue publishes one | l2snapshot / l2update events; prototype book helpers in src/orderbooks |
| Level 3 (order-by-order) | not a unified method | yes, on Coinbase Pro, Bitfinex, KuCoin, ErisX and LedgerX |
| Candles over the socket | watch_ohlcv | candle event |
| Private streams | watch_orders, watch_balance, watch_my_trades, watch_positions | not shipped; the FAQ lists private feeds as an intention |
| Order entry over the socket | createOrderWs on 23 exchanges | out of scope |
| Unsubscribe | unWatch* on 26 exchanges | unsubscribe* methods |
| Market identifiers | unified symbols after load_markets() | you supply { id, base, quote, type } yourself |
| Popularity | 43.8k GitHub stars · 494k npm + 4.7M PyPI installs/month | 639 GitHub stars · 3.3k npm installs/month |
| Licence | MIT | MIT |
| Support | Discord, Telegram, GitHub issues — usually same-day | repository is read-only; 52 open issues at archival |
Figures verified September 2026 against CCXT v4.5.77, the ccxws repository, its README and FAQ, its npm registry entry, and npm/PyPI download counts for the month ending 29 August 2026.
The same job, written both ways
ccxws is a public market-data library, so the comparable tasks are streams. Both snippets do the same thing.
Stream trades
import ccxt from 'ccxt';
const exchange = new ccxt.pro.binance ();
while (true) {
const trades = await exchange.watchTrades ('BTC/USDT');
for (const t of trades) {
console.log (t.symbol, t.side, t.amount, t.price);
}
}Two differences matter beyond style. First, ccxws asks you for the market object — id is the venue's own identifier, so you either hard-code it, load it from your own database, or (as its FAQ suggests) load it from CCXT. CCXT resolves 'BTC/USDT' against the venue's own market metadata for you. Second, ccxws is push-shaped and CCXT is pull-shaped: await returns a value, so streaming code composes with ordinary control flow and sits next to the REST code that backfills it.
Keep a live order book
import ccxt from 'ccxt';
const exchange = new ccxt.pro.binance ();
while (true) {
const orderbook = await exchange.watchOrderBook ('BTC/USDT');
console.log (orderbook.bids[0], orderbook.asks[0]);
}applySnapshot and applyUpdate are the part that is not in the snippet. ccxws delivers the venue's messages, normalised and reconnected; assembling them into a book is yours to write, and its own FAQ describes maintaining an L2 book as "a complex question [that] varies by each exchange", with prototype book implementations for several exchanges in src/orderbooks.
watchOrderBook returns the merged book. Underneath it, CCXT handles per-venue sequencing: fetching the REST snapshot and aligning it with the stream, buffering deltas that arrive during the fetch, detecting update-id gaps and re-seeding, verifying the venue's checksum where one is published, and reconnecting and resubscribing after a drop. Those are the places a hand-rolled book goes quietly wrong — it does not throw, it drifts, and you find out from a fill you did not expect.
Where the differences actually bite
Coverage, and which venues are still there
ccxws' README table lists 35 clients; the npm package describes itself as a "Websocket client for 37 cryptocurrency exchanges". Because the repository has been read-only since September 2023, that table is a snapshot of the market as it was — it still lists FTX, FTX US, Liquid, Bittrex, LedgerX, ErisX, Coinbase Pro and OKEx under those names.
CCXT ships WebSocket support for 76 exchanges today, including most of the venues on that list under their current names, and the long tail that came after it: perpetuals-first DEXes, regional venues, and 7 prediction markets in ccxt.prediction. Two ccxws clients have no CCXT streaming equivalent — bitFlyer and Digifinex are REST-only in CCXT.
Public data was the whole scope
ccxws connects to "realtime public APIs". There are no account streams; its FAQ answers the question about private feeds with an intention rather than a shipped feature. If you were pairing it with CCXT REST, your fills and balances were coming from polling.
CCXT Pro streams the private side over the same connection model: watch_orders, watch_my_trades, watch_balance, watch_positions, and order entry over the socket — createOrderWs and cancelOrderWs on 23 exchanges each, editOrderWs and cancelAllOrdersWs on 21. Venue-specific plumbing that this requires — Binance's listenKey refresh, for instance — is handled inside the library rather than in your reconnect logic.
One structure for REST and stream
In CCXT, watch_order_book returns the same structure as fetch_order_book, and watch_ohlcv the same as fetch_ohlcv. Backfill history over REST, switch to the stream, and the code downstream cannot tell which produced the candle. Swapping a polling loop for a stream is a one-word change.
With CCXT plus ccxws you had two normalisation layers that were similar by design but not identical, and the seams — a Trade class on one side, a trade dictionary on the other — were yours to reconcile.
Eight languages
ccxws is a TypeScript/JavaScript library, which was the right call for the Node.js pipelines it was built for. CCXT is written once in TypeScript and transpiled to JavaScript, Python, PHP, C#/.NET, Go, Java and Rust, with the same method names and return structures in each. A stream consumer prototyped in Python moves to a Go or C# service without a second data model.
What ccxws does better
Honest, specific, and some of it still true:
- Level 3 order books. ccxws exposes
l3snapshotandl3updateevents for Coinbase Pro, Bitfinex, KuCoin, ErisX and LedgerX — raw order-by-order data you can aggregate yourself. CCXT's unified order book is level 2; there is no unified L3 method. For queue-position modelling or order-flow research, that is a capability CCXT does not replace. - An explicit connection lifecycle. ccxws emits
connecting,connected,disconnected,reconnecting,closingandclosedas first-class events, with a documented state machine in the README and a configurablewatcherMsinactivity timer. That is easy to wire into dashboards and alerting. CCXT reconnects for you, which is what most people want, and correspondingly gives you less to observe. - Bring your own markets. A ccxws subscription needs nothing more than
{ id, base, quote, type }, so you can subscribe to a venue without an HTTP round trip and without a market-loading step at boot. CCXT callsload_markets()first, by design — that is where the precision, limits and symbol mapping come from. - A very small dependency surface. Six runtime dependencies, one job, no trading code anywhere near your API keys. If all you need is public trades from one venue in Node.js, that is a smaller thing to audit than a full trading library.
- Per-exchange transparency. One client class per venue with the venue's own quirks visible in it, rather than a shared abstraction. When you are debugging a specific exchange's stream, having a file that only does that exchange is genuinely easier to read.
If you have an L3-dependent research pipeline on the venues ccxws covers, it may still be the more direct fit — as an unmaintained dependency you have chosen deliberately, with the archival date understood.
Migrating from ccxws to CCXT
The client classes map one-to-one for most venues. Everything below is in the ccxt package; there is nothing extra to install.
| ccxws client | CCXT Pro |
|---|---|
BinanceClient | ccxt.pro.binance |
BinanceFuturesUsdtmClient | ccxt.pro.binanceusdm |
BinanceFuturesCoinmClient | ccxt.pro.binancecoinm |
BinanceUsClient | ccxt.pro.binanceus |
CoinbaseProClient | ccxt.pro.coinbaseexchange |
KrakenClient | ccxt.pro.kraken |
KucoinClient | ccxt.pro.kucoin |
OkexClient | ccxt.pro.okx |
HuobiClient | ccxt.pro.htx |
GateioClient | ccxt.pro.gate |
BitfinexClient, BitmexClient, BitstampClient, BithumbClient | ccxt.pro.bitfinex, ccxt.pro.bitmex, ccxt.pro.bitstamp, ccxt.pro.bithumb |
CexClient, CoinexClient, DeribitClient, GeminiClient | ccxt.pro.cex, ccxt.pro.coinex, ccxt.pro.deribit, ccxt.pro.gemini |
HitBtcClient, PoloniexClient, UpbitClient | ccxt.pro.hitbtc, ccxt.pro.poloniex, ccxt.pro.upbit |
BitflyerClient, DigifinexClient | REST only in CCXT — ccxt.bitflyer, ccxt.digifinex |
And the events map to methods:
| What you are doing | ccxws | CCXT |
|---|---|---|
| Identify a market | { id: 'BTCUSDT', base: 'BTC', quote: 'USDT', type: 'spot' } | 'BTC/USDT' after load_markets() |
| Ticker | on('ticker') + subscribeTicker() | watch_ticker() / watch_tickers() |
| Trades | on('trade') + subscribeTrades() | watch_trades() |
| Candles | on('candle') + subscribeCandles() | watch_ohlcv() |
| Order book | on('l2snapshot') / on('l2update') + your book | watch_order_book() — merged for you |
| Level 3 book | on('l3snapshot') / on('l3update') | no unified equivalent |
| Unsubscribe | unsubscribeTrades() and friends | unWatch* methods |
| Reconnection | connecting / disconnected / reconnecting events | automatic; failures raise typed exceptions |
| Errors | on('error') | try / except ccxt.NetworkError and 40 other typed classes |
| Account data | not in scope | watch_orders(), watch_balance(), watch_my_trades(), watch_positions() |
Start with Install, then the CCXT Pro manual.
FAQ
Is ccxws still maintained? The repository was archived by its owner on 9 September 2023 and is read-only. Its last commit and its last npm release (0.47.0) are both dated 8 October 2021. The published package still installs and is still MIT-licensed.
What replaced ccxws?
For most users, CCXT Pro — the WebSocket half of CCXT, bundled in the same ccxt package under MIT. It covers 76 exchanges with watch* methods that return the same structures as the equivalent fetch* methods, and adds private streams and socket order entry that ccxws did not cover.
Do I need a separate package or a paid licence for CCXT's WebSockets?
No. CCXT Pro is in the ccxt package. Use ccxt.pro.<exchange> in JavaScript, TypeScript and Python, and call watch* methods. There is no paid tier.
Can I use ccxws and CCXT together, the way people used to? Technically yes — they are both MIT and ccxws was explicitly designed to consume CCXT's market objects. The reason to stop is maintenance: a venue that changes its stream format breaks the ccxws side and there is no upstream to fix it. Running both also means two normalisation layers to reconcile where one now suffices.
Does CCXT support level 3 order books?
Not as a unified method. CCXT's watch_order_book and fetch_order_book return aggregated level 2 books. ccxws exposed L3 events for five venues, and that is the one capability a migration does not carry over.
Which exchanges did ccxws support that CCXT does not stream? Of the clients in its README table, bitFlyer and Digifinex are supported by CCXT over REST but not over WebSocket. Several other entries — FTX, FTX US, Liquid, Bittrex, LedgerX, ErisX — are venues that no longer operate under those names.
Next steps
- Install CCXT
- CCXT Pro manual — the
watch*andunWatch*methods - Manual — unified structures and conventions
- Supported exchanges
- More comparisons
CCXT vs OpenLimits
OpenLimits is a Rust spot-trading API built at Nash. CCXT is an MIT library for 104 venues in eight languages. Compared on coverage, typing, bindings and cadence.
CCXT vs Cryptofeed
CCXT and Cryptofeed both normalise crypto market data across exchanges. They differ on trading, licence, language coverage and storage backends — here is which one fits which job.