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.
OpenLimits describes itself as "a open source Rust high performance cryptocurrency trading API with support for multiple exchanges and language wrappers. Focused in safety, correctness and speed." It was built at Nash and overlaps CCXT on one idea: one normalised interface in front of several exchanges, so your strategy code does not care which venue it is talking to.
The two answer that idea very differently, and the deciding question is simple: do you need Rust's type system, or do you need venue coverage?
TL;DR
- Pick OpenLimits if your system is Rust and you want a small, statically checked trait interface —
Currencyas an enum,Decimalprices,limit_buyandmarket_sellas separate methods that cannot be combined wrongly — over Binance, Coinbase or Nash spot. - Pick CCXT if you need breadth: 104 exchanges with REST, 76 of them with WebSocket, spot and derivatives, in TypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java or Rust.
- Check the calendar before you commit either way. OpenLimits' latest crates.io release is 0.3.0, published 29 November 2021; the most recent commit on its
mainbranch is "Adding Binance RateLimitType variant", dated 16 July 2022. CCXT ships releases continuously. - Both reach Rust, so decide on coverage and cadence. CCXT's Rust target carries all 104 venues and is released alongside every other language; OpenLimits covers three spot venues and last moved in 2022.
At a glance
| CCXT | OpenLimits | |
|---|---|---|
| Primary purpose | unified trading + market data API | unified spot trading API for Rust |
| Exchanges | 104 REST, 76 with WebSocket | 3 — Binance, Coinbase, Nash |
| Languages | TypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java, Rust | Rust; a C# wrapper published to NuGet |
| Instrument types | spot, margin, swap, future, option, plus 7 prediction venues | spot; futures and options are listed under "Future goals" |
| Market data | fetch_ticker, fetch_order_book, fetch_ohlcv, fetch_trades and dozens more | get_price_ticker, order_book, get_historic_rates, get_historic_trades |
| Order entry | create_order() plus trigger, stop, take-profit, trailing, post-only, reduce-only | limit_buy, limit_sell, market_buy, market_sell, with post-only and time-in-force |
| WebSockets | yes — watch* methods on 76 exchanges | yes — subscribe() with a callback |
| Raw endpoint access | yes — implicit methods for every documented endpoint (808 on Binance) | inner_client() returns the underlying venue client |
| Rate limiting | throttler with per-endpoint weights, on by default | Binance's declared limits are parsed into a typed RateLimit / RateLimitType |
| Unified error types | 41 typed exceptions in one hierarchy | one OpenLimitsError enum |
| Testnet / sandbox | exchange.set_sandbox_mode(True) | BinanceParameters::sandbox() / Environment::Sandbox |
| Latest release | continuous — v4.5.77 | 0.3.0, 29 November 2021 |
| Most recent commit on the default branch | continuous | 16 July 2022 |
| Popularity | 43.8k GitHub stars · 4.7M PyPI + 494k npm installs/month | 322 GitHub stars · 34.1k crates.io downloads all-time, 210 in the last 90 days |
| Licence | MIT | BSD-2-Clause |
| Support | Discord, Telegram, GitHub issues — usually same-day | Discord link in the README, GitHub issues |
Figures verified September 2026 against CCXT v4.5.77, the OpenLimits repository and README, its crates/ and bindings/ directories, its main branch commit feed, and the crates.io and NuGet registries.
The same job, written both ways
Fetch a ticker
import ccxt
exchange = ccxt.binance()
ticker = exchange.fetch_ticker('BTC/USDT')
print(ticker['last'], ticker['baseVolume'])The shapes tell you the philosophies. CCXT identifies a market with the string 'BTC/USDT' and returns a unified ticker structure — a dictionary with the same keys on every venue. OpenLimits identifies it with MarketPair(Currency::BTC, Currency::USDT), where Currency is an enum with eleven named variants and an Other(String) escape hatch, and returns a Ticker struct with Decimal fields. Typos become compile errors on one side and runtime errors on the other.
Place a limit order
import ccxt
exchange = ccxt.binance({'apiKey': '...', 'secret': '...'})
order = exchange.create_order('BTC/USDT', 'limit', 'buy', 0.001, 60000)
print(order['id'], order['status'])CCXT takes type and side as arguments, which is what lets create_order be one method across every venue and every instrument kind. OpenLimits splits them into four methods — limit_buy, limit_sell, market_buy, market_sell — with different request structs, so "market order with a price" is not expressible. That is a genuinely nicer failure mode; it also means a fifth order kind is a new method rather than a new argument.
Stream an order book
import ccxt.pro
import asyncio
async def main():
exchange = ccxt.pro.coinbaseexchange()
while True:
orderbook = await exchange.watch_order_book('ETH/BTC')
print(orderbook['bids'][0], orderbook['asks'][0])
asyncio.run(main())CCXT is pull-shaped: await a method and get the merged book back, so streaming code sits next to REST code and composes with ordinary control flow. OpenLimits is push-shaped: register a callback and match on the message variant.
Where the differences actually bite
Coverage: three venues versus 104
OpenLimits' umbrella crate depends on openlimits-binance, openlimits-coinbase and openlimits-nash, and its exchange module re-exports exactly those three. The repository's crates/ directory also holds an openlimits-huobi folder, which is not a dependency of the umbrella crate and has no published crate on crates.io.
CCXT covers 104 exchanges with REST and 76 with WebSocket, plus 7 prediction-market venues in ccxt.prediction (Polymarket, Kalshi, Limitless, Myriad, Opinion, and the Binance and Hyperliquid prediction products). Adding a venue is a change of identifier:
for exchange_id in ['binance', 'bybit', 'okx', 'coinbase', 'kraken']:
exchange = getattr(ccxt, exchange_id)()
print(exchange_id, exchange.fetch_ticker('BTC/USDT')['last'])Spot versus derivatives
OpenLimits' README states the project "is initially focused on spot exchanges", and lists "Support for futures trading" and "Support for options trading" under Future goals. Its account trait models spot order entry: limit and market, buy and sell, with post-only and time-in-force.
CCXT models spot, margin, swaps, futures and options through the same create_order call, selected by options.defaultType and the unified symbol:
exchange = ccxt.binance({'apiKey': '...', 'secret': '...',
'options': {'defaultType': 'future'}})
order = exchange.create_order('BTC/USDT:USDT', 'limit', 'buy', 0.001, 60000)It also unifies positions, leverage, margin mode, funding rates, transfers and deposit addresses — the account plumbing around order entry, not just order entry.
The language wrappers
The README lists "Thin layer wrappers for Java, C#, Python and Node.js" among the project goals. What shipped is the C# one: the repository's bindings/ directory contains a csharp folder (FFI types such as ExchangeClient.cs, LimitOrderRequest.cs, Orderbook.cs) and a file named REMOVE_ME, and NuGet carries a package Openlimits described as "This is the offical openlimits c# wrapper", latest version 0.1.15, published 18 December 2020, 10.5k downloads all-time. There is no openlimits package on npm or PyPI. In the root Cargo.toml, the bindings feature and its ligen build dependencies are commented out.
CCXT takes the opposite approach: one TypeScript source of truth, transpiled to JavaScript, Python, PHP, C#/.NET, Go, Java and Rust, so the method names, arguments and return structures are the same in all eight. A change lands in every language in the same release — fetchTicker in TypeScript, fetch_ticker in Python, FetchTicker in C# and Go, returning the same structure.
Release cadence
OpenLimits' crates.io history runs from 0.1.0 in August 2020 to 0.3.0 on 29 November 2021, and the most recent commit on main is dated 16 July 2022. The repository is not archived and the README's warning that "the project is still in development and a lot of breaking changes are being made" still stands.
Exchange APIs change without notice — endpoints move, fields get renamed, signing schemes are revised. Whichever library you pick, that maintenance is either someone else's job or yours. CCXT ships continuously and the fix reaches you as a version bump.
Rate limits and precision
CCXT encodes each venue's per-endpoint request weights and ships a throttler that is on by default (enableRateLimit = True), plus amount_to_precision, price_to_precision and cost_to_precision backed by the Precise string-arithmetic class, so quantities do not drift through float rounding.
OpenLimits leans on Rust's type system for the second half of that problem — prices and sizes are rust_decimal::Decimal, not f64, which rules out the same class of bug at the language level. For the first half, its Binance crate deserialises the venue's declared limits into typed RateLimit and RateLimitType values; pacing the calls is the caller's job.
What OpenLimits does better
Real advantages, and the reason the project is worth reading even now:
- It is Rust. No garbage collector, no interpreter, one static binary, and the borrow checker between you and a class of concurrency bug. CCXT reaches Rust through a crate generated from its TypeScript source, so it reads like CCXT rather than like Rust; OpenLimits was designed as Rust from the start. For a single-binary Rust execution service this is decisive, and no amount of venue coverage substitutes for it.
- Illegal states are harder to build.
limit_buy/limit_sell/market_buy/market_selltake different request structs, so a market order carrying a price does not compile.Currencyis an enum.MarketPairis a two-field tuple struct, not a delimited string. Prices areDecimal. CCXT catches the same mistakes, but at runtime, on the venue's rejection. - The trait design is clean and extensible.
Exchange: ExchangeInfoRetrieval + ExchangeAccount + ExchangeMarketDatameans you can writefn strategy(exchange: &impl Exchange)and have the compiler prove the venue supports what you call. CCXT's equivalent is thehascapability map, checked at runtime. OpenLimits' own test suite is built exactly this way — one generic template run against each venue. - Environment is a constructor parameter, not a mode.
BinanceParameters::sandbox()andEnvironment::Sandboxmake testnet a value you pass in rather than a flag you flip on a live object. - The whole surface fits on one page. Four market-data methods and eleven account methods. That is a real virtue when you are auditing what a library can do with your keys.
If you are building in Rust, trading spot on Binance, Coinbase or Nash, and you value a compiler-checked interface over breadth, OpenLimits is the better shape — with the release dates above factored into your decision.
Migrating from OpenLimits to CCXT
| What you are doing | OpenLimits | CCXT |
|---|---|---|
| Construct a client | Binance::new(BinanceParameters::production()) | ccxt.binance({'apiKey': '...', 'secret': '...'}) |
| Identify a market | MarketPair(Currency::BTC, Currency::USDT) | 'BTC/USDT' (spot), 'BTC/USDT:USDT' (linear swap) |
| Market metadata | get_pair() / ExchangeInfoRetrieval | load_markets() |
| Ticker | get_price_ticker() | fetch_ticker() |
| Order book | order_book() | fetch_order_book() |
| Candles | get_historic_rates() | fetch_ohlcv() |
| Public trades | get_historic_trades() | fetch_trades() |
| Limit order | limit_buy() / limit_sell() | create_order(symbol, 'limit', side, amount, price) |
| Market order | market_buy() / market_sell() | create_order(symbol, 'market', side, amount) |
| Cancel | cancel_order() / cancel_all_orders() | cancel_order() / cancel_all_orders() |
| Open orders | get_all_open_orders() / get_open_orders() | fetch_open_orders() |
| Order history | get_order_history() | fetch_orders() / fetch_closed_orders() |
| Fills | get_trade_history() | fetch_my_trades() |
| Balances | get_account_balances() | fetch_balance() |
| Streams | subscribe(OrderBookUpdates(pair), callback) | await watch_order_book(symbol) on ccxt.pro.<id> |
| Testnet | BinanceParameters::sandbox() | exchange.set_sandbox_mode(True) |
| Venue-specific calls | inner_client() | the same endpoint as an implicit method |
Start with Install, then the Manual.
FAQ
Does CCXT have a Rust version?
Not a published one. CCXT is generated from one TypeScript source into TypeScript, JavaScript, Python, PHP, C#/.NET, Go, Java and Rust, and there is no ccxt crate on crates.io as of September 2026. If your system must be a Rust binary, that is a real reason to look at a Rust-native library — or to put CCXT behind a small service in one of the eight supported languages.
Which exchanges does OpenLimits support?
Three: Binance, Coinbase and Nash. Its umbrella crate depends on openlimits-binance, openlimits-coinbase and openlimits-nash, and its exchange module re-exports those three. An openlimits-huobi folder exists in the repository's crates/ directory but is not wired into the umbrella crate and has no published crate.
Did the Java, Python and Node.js bindings ever ship?
The README lists them as project goals. The bindings/ directory in the repository contains a csharp folder, and NuGet carries an Openlimits package described as the official C# wrapper, last published at version 0.1.15 in December 2020. There is no openlimits package on npm or PyPI.
Is OpenLimits still being released?
Its most recent crates.io release is 0.3.0, published 29 November 2021, and the most recent commit on the main branch is dated 16 July 2022. The repository is public and not archived.
Does CCXT support derivatives, or only spot?
Spot, margin, perpetual swaps, dated futures and options, through the same create_order call, plus positions, leverage, margin mode and funding rates as unified methods. OpenLimits' README describes it as "initially focused on spot exchanges", with futures and options listed under Future goals.
Do I need CCXT Pro separately for WebSockets?
No. CCXT Pro is bundled in the ccxt package under MIT. Use ccxt.pro.<exchange> and the watch* methods.
Next steps
- Install CCXT in your language
- Manual — the unified API, structures and conventions
- CCXT Pro manual — the
watch*streaming methods - Supported exchanges
- More comparisons
CCXT vs ccapi
ccapi is a header-only C++ library connecting your server straight to exchanges. Compared with CCXT on latency, build complexity, coverage and language reach.
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.