CCXT

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 ccxt package under the same MIT licence — no separate install, no paid tier. It streams from 76 exchanges, and the watch* methods return the same structures as the matching fetch* 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
Statusactively releasedarchived by its owner on 9 September 2023, read-only
Latest releasecontinuous — v4.5.77npm 0.47.0, published 8 October 2021
Most recent commitcontinuous8 October 2021
ScopeREST + WebSocket, public and private, market data and tradingpublic realtime streams only
Exchanges104 with REST, 76 with WebSocket35 clients listed in the README table
LanguagesTypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java, RustTypeScript / JavaScript
Packages to install1 (ccxt)1 (ccxws), usually alongside ccxt for markets
Programming modelawait exchange.watch_trades(symbol)client.on('trade', handler) + client.subscribeTrades(market)
Order booksmerged, maintained, checksum-verified where the venue publishes onel2snapshot / l2update events; prototype book helpers in src/orderbooks
Level 3 (order-by-order)not a unified methodyes, on Coinbase Pro, Bitfinex, KuCoin, ErisX and LedgerX
Candles over the socketwatch_ohlcvcandle event
Private streamswatch_orders, watch_balance, watch_my_trades, watch_positionsnot shipped; the FAQ lists private feeds as an intention
Order entry over the socketcreateOrderWs on 23 exchangesout of scope
UnsubscribeunWatch* on 26 exchangesunsubscribe* methods
Market identifiersunified symbols after load_markets()you supply { id, base, quote, type } yourself
Popularity43.8k GitHub stars · 494k npm + 4.7M PyPI installs/month639 GitHub stars · 3.3k npm installs/month
LicenceMITMIT
SupportDiscord, Telegram, GitHub issues — usually same-dayrepository 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 l3snapshot and l3update events 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, closing and closed as first-class events, with a documented state machine in the README and a configurable watcherMs inactivity 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 calls load_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 clientCCXT Pro
BinanceClientccxt.pro.binance
BinanceFuturesUsdtmClientccxt.pro.binanceusdm
BinanceFuturesCoinmClientccxt.pro.binancecoinm
BinanceUsClientccxt.pro.binanceus
CoinbaseProClientccxt.pro.coinbaseexchange
KrakenClientccxt.pro.kraken
KucoinClientccxt.pro.kucoin
OkexClientccxt.pro.okx
HuobiClientccxt.pro.htx
GateioClientccxt.pro.gate
BitfinexClient, BitmexClient, BitstampClient, BithumbClientccxt.pro.bitfinex, ccxt.pro.bitmex, ccxt.pro.bitstamp, ccxt.pro.bithumb
CexClient, CoinexClient, DeribitClient, GeminiClientccxt.pro.cex, ccxt.pro.coinex, ccxt.pro.deribit, ccxt.pro.gemini
HitBtcClient, PoloniexClient, UpbitClientccxt.pro.hitbtc, ccxt.pro.poloniex, ccxt.pro.upbit
BitflyerClient, DigifinexClientREST only in CCXT — ccxt.bitflyer, ccxt.digifinex

And the events map to methods:

What you are doingccxwsCCXT
Identify a market{ id: 'BTCUSDT', base: 'BTC', quote: 'USDT', type: 'spot' }'BTC/USDT' after load_markets()
Tickeron('ticker') + subscribeTicker()watch_ticker() / watch_tickers()
Tradeson('trade') + subscribeTrades()watch_trades()
Candleson('candle') + subscribeCandles()watch_ohlcv()
Order bookon('l2snapshot') / on('l2update') + your bookwatch_order_book() — merged for you
Level 3 bookon('l3snapshot') / on('l3update')no unified equivalent
UnsubscribeunsubscribeTrades() and friendsunWatch* methods
Reconnectionconnecting / disconnected / reconnecting eventsautomatic; failures raise typed exceptions
Errorson('error')try / except ccxt.NetworkError and 40 other typed classes
Account datanot in scopewatch_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

On this page