Open-source project
underloam/xbbg avatar
underloam/xbbg

xbbg: a Bloomberg client built on a Rust engine with Narwhals output

Intuitive Data Workflows

707 stars64 forksRustApache-2.0

At a glance

What is it?
xbbg is an independent Bloomberg client whose Python surface sits on a shared Rust engine that handles request execution, parsing, Arrow-shaped data movement, async workers and typed errors, with JavaScript and Node bindings beside it. The catch is the one the project states plainly: it grants no access to Bloomberg and you must bring your own entitlement.
Who is it for?
Adopt xbbg if you already hold Bloomberg access and your Python work has outgrown a one-off bdp wrapper, in particular if you need intraday bars, BQL, streaming, managed B-PIPE or SAPI environments, or a pipeline that is not pandas shaped. Do not adopt it as a way to obtain Bloomberg data, because the project grants no entitlement of any kind, and do not adopt it for a single small script, where the dependency footprint and the setup cost are pure overhead.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What xbbg is, and the entitlement it does not give you

xbbg is a Bloomberg client with Python as the primary surface, companion JavaScript and Node bindings, and a shared Rust engine underneath that does request execution, response parsing, Arrow-shaped data movement, async workers, typed errors and diagnostics.

The scope is stated concretely. There are request helpers for BDP, BDS, BDH, intraday bars, ticks, BQL, BEQS, BSRCH, BQR, BTA and YAS. The default connection target is the local Bloomberg Desktop API, with configuration for managed Bloomberg environments including B-PIPE and SAPI, ZFP leased lines, TLS, failover hosts, SOCKS5 and SDK logging. There are sync and async Python APIs over the same engine, and output can be Narwhals, native xbbg Arrow carriers, PyArrow, pandas, Polars, DuckDB and other optional Narwhals-backed libraries.

The legal and practical caveat is stated in the README with unusual clarity. xbbg is an independent open-source project, not affiliated with, endorsed by, sponsored by or approved by Bloomberg Finance L.P. It does not grant access to Bloomberg services, data, software, licences, credentials or entitlements, and users must obtain and use those separately under their own Bloomberg agreements and applicable policies. Bloomberg, Bloomberg Terminal, B-PIPE, BQL and the related names are trademarks of their respective owners.

That sentence is the single most important line in the documentation for anyone evaluating the project, and it is the reason the project can exist at all as an open source release.

A Cargo workspace with bindings and an MCP application

The repository is a Rust workspace with a clear internal structure, and the workspace manifest lists the members. The engine side is seven crates: xbbg-arrow, xbbg-core, blpapi-sys, xbbg-async, xbbg-ext, xbbg-recipes and xbbg-log, plus xbbg-bench. The bindings are bindings/pyo3-xbbg for Python and bindings/napi-xbbg for Node, and there is an application crate at apps/xbbg-mcp.

Several details follow from that layout. blpapi-sys is the low-level interface to Bloomberg's C SDK, so the whole stack sits on the vendor's native library rather than reimplementing the wire protocol. xbbg-arrow is a separate crate, which means the Arrow-shaped data representation is not tangled with request logic. xbbg-async is separate again, so the async worker pools and isolated subscription sessions are an optional layer rather than something every code path pays for.

The workspace is on edition 2024 with a rust-version floor of 1.88, and the version is 1.5.1, matching the published release. The default members list excludes the application crate, so a plain cargo build of the workspace does not build the MCP server.

The manifest also shows a discipline that is worth noting because it is unusual to see documented. The workspace dependencies block is the single source of truth for every third party version, members inherit with the workspace = true form, and default-features is kept at the workspace level on purpose, with a comment explaining that when a workspace entry omits it, a member's own default-features = false is silently ignored and Cargo warns about it. This is the kind of detail that saves a team an afternoon of chasing a feature flag that does not apply.

Installing without the blpapi Python package

Installation for Python is a single pip command:

bash
pip install xbbg

Conda users have a conda-forge build:

bash
conda install -c conda-forge xbbg

The important detail is what is not required. blpapi is not needed as a Python dependency. What xbbg does need is Bloomberg's shared runtime library, blpapi3_64.dll on Windows and libblpapi3_64.so on macOS and Linux, and that can come from a Bloomberg Terminal or DAPI install, a managed Bloomberg C++ SDK install, or Bloomberg's official blpapi wheel.

The Python metadata confirms the version range and the licence, and it also shows how the project handles identity:

toml
requires-python = ">=3.11,<3.16"
license = "Apache-2.0"
license-files = ["LICENSE"]

The classifiers cover Python 3.11 through 3.15 and list Rust as a programming language, and the project is marked as production stable. The author field is deliberately a project identity rather than a person, because that metadata is published to PyPI on every release and the security contact is GitHub private vulnerability reporting.

The JavaScript and Node side has its own package, @xbbg/core, with a Node.js version badge, and the Rust engine itself is published separately as the xbbg_core crate on crates.io with an MSRV badge. So there are three distribution surfaces for one engine: Python, npm and crates.io.

How the Python extension is tied to the build that produced it

The setup.py file in the repository is not a legacy artefact to be ignored, it is where a specific safety property is implemented.

The build hook stamps the distribution version into the Rust extension. The comment explains the sequence: project metadata lives in pyproject.toml, setuptools-scm computes the version when the build starts, and build_rust exports that exact version to Cargo so that xbbg._core.__version__ names the distribution the binary was built for.

The consequence is stated plainly: the Python package refuses an extension that came from a different build. In other words, a compiled xbbg._core from one release cannot be silently loaded by a Python distribution of another version. That is a real class of bug in projects with a native extension, where a stale build artefact in a wheel or a cache produces a runtime failure that looks like a mystery, and here it is turned into an explicit check.

The implementation is small and readable. A StampedBuildRust class overrides run, sets the XBBG_DIST_VERSION environment variable from the distribution version, and calls the parent. The environment variable is read by the build script at bindings/pyo3-xbbg/build.rs, which declares it as rerun-if-env-changed, so a new version always recompiles the extension rather than reusing a cached object file.

The PEP 517 hook process is dedicated to the build, and setuptools-rust passes the environment to Cargo, which is what makes the hand-off reliable. The Python package also ships a typing marker, so type checkers pick up the extension's types.

The comparison table is where the real argument lives

The README does not simply assert that xbbg is better than the alternatives, it tabulates the differences against raw blpapi, pdblp and blp, bbg-fetch and polars-bloomberg, and the shape of the table is itself informative.

The pattern is that xbbg covers the breadth of the request surface where the raw SDK requires manual code, and that the other Python wrappers cover a narrower slice. Intraday bars and ticks are yes for xbbg, manual SDK code for raw blpapi, limited or no for pdblp and blp, no for bbg-fetch, and partial for polars-bloomberg. Streaming subscriptions are yes for xbbg and manual SDK code for raw blpapi, and no for the other three. Managed environment support, covering DAPI, SAPI and B-PIPE, ZFP, TLS, failover and SOCKS5, is configurable engine support for xbbg and limited for the wrappers.

The project also states the case against itself accurately. If all you need is a tiny one-off bdp wrapper, several packages can work, and xbbg is built for the path where that notebook later grows into intraday data, BQL, streaming, managed environments, async services, typed errors, diagnostics and non-pandas pipelines.

The one number worth reading closely is the install footprint. For Windows x64 with Python 3.14, xbbg 1.5.1 with narwhals 2.26.0 and no blpapi is 18.650 MiB, the blpapi wheel alone is 14.702 MiB, pdblp with pandas, numpy and blpapi is 130.816 MiB, bbg-fetch with the same pandas stack is 130.863 MiB and polars-bloomberg with polars and blpapi is 191.118 MiB. The xbbg figure excludes the Bloomberg runtime library, which is a separate install, so the comparison is not entirely like for like, but the difference in shape is real: the wrappers that depend on the blpapi wheel carry a large pandas and numpy tree, and xbbg's own tree is much smaller.

Output backends, async and the MCP server

The output story is what separates a modern data client from an old one. Results can be handed back as Narwhals objects, as native xbbg Arrow carriers, as PyArrow, or converted to pandas, Polars, DuckDB and other optional Narwhals-backed libraries, and the other libraries are optional rather than mandatory.

That optionality has a hard edge, and the project documents it in its own metadata. The dependency floor for narwhals was raised because 2.10.0 is the first release whose plugin discovery honours the narwhals.plugins entry point the package registers. On 2.0 to 2.9 the plugin is never loaded, so converting an xbbg result raises a TypeError complaining that it expected a pandas-like dataframe, a Polars dataframe or a Polars lazyframe and got xbbg._core.ArrowTable. The comment in the manifest records the failure precisely, which is a good sign about how the project handles its own sharp edges.

Async is a first-class surface rather than an afterthought. There are sync and async Python APIs over the same engine, with async worker pools and isolated subscription sessions, and the subscription model distinguishes raw, tick mode and all fields. The README's table of contents also lists exchange auctions and imbalance, entitlement IDs, output backends and an MCP server section.

The MCP application crate in the workspace is the newest element to look at. An MCP server built on the same engine means a coding agent can query the data through the same typed request layer rather than through a generated wrapper script, which fits the way financial data workflows are being written now. The repository also ships a langgraph directory for both the Python and JavaScript sides, which is the pattern people use when they want the agent to plan a sequence of market data calls.

What the project will not do for you

The limits are mostly a consequence of the entitlement boundary and of the choice to sit on top of Bloomberg's C SDK rather than to reimplement the protocol.

The first is that xbbg cannot help you if you do not have Bloomberg access. Every capability in the table is conditioned on the user supplying their own authorized access, whether that is a desktop session, a DAPI environment, a B-PIPE or SAPI feed or a ZFP leased line. The engine handles the transport, the session management, the failover and the parsing, and none of that is usable without a session the vendor has granted. A team evaluating this on the assumption that a library can substitute for a terminal will be disappointed, and the README is careful to say so.

The second is that xbbg is not a data vendor. It does not cache, store, historise or serve market data, and it does not remove the need to keep your own records of what you pulled and when. The field cache mentioned in the capability table is a request-level optimisation inside a session, not a data store.

The third is the cost of the native dependency. Because the stack sits on the Bloomberg shared runtime library, every machine that imports xbbg needs that library present and correctly licensed, and the Python package version check described earlier only protects against a mismatched build of xbbg itself, not against a runtime library that is missing or out of date. The Docker directory in the repository exists precisely because of this kind of packaging problem, and anyone deploying this needs to solve the library distribution question before the first import.

The alternative worth naming is writing directly against the raw blpapi SDK, which the table lists as a column of its own. That approach gives you total control and no wrapper layer, and it costs you the request helpers, the typed errors, the diagnostics, the async workers and the Arrow-shaped output, all of which the table marks as manual SDK code. xbbg is the answer to the question of whether those layers are worth having, and the honest framing is that they are worth having once your workflow passes the one-off wrapper stage, and not before.

Editorial conclusion

Adopt xbbg if you already hold Bloomberg access and your Python work has outgrown a one-off bdp wrapper, in particular if you need intraday bars, BQL, streaming, managed B-PIPE or SAPI environments, or a pipeline that is not pandas shaped. Do not adopt it as a way to obtain Bloomberg data, because the project grants no entitlement of any kind, and do not adopt it for a single small script, where the dependency footprint and the setup cost are pure overhead. Before you commit, confirm that your Bloomberg agreement permits the access path you intend to use, check that the shared runtime library is available on the machine that will import xbbg, and verify that the output backend you need is covered by the Narwhals-based conversions rather than assuming pandas is the default.

Frequently asked questions

What is xbbg?

xbbg is an independent Bloomberg client with Python as the primary surface, companion JavaScript and Node bindings, and a shared Rust engine handling request execution, response parsing, Arrow-shaped data movement, async workers, typed errors and diagnostics. It provides helpers for BDP, BDS, BDH, intraday bars, ticks, BQL, BEQS, BSRCH, BQR, BTA and YAS.

Do I need Bloomberg access to use xbbg?

Yes. The project states that it does not grant access to Bloomberg services, data, software, licences, credentials or entitlements, and that users must obtain and use those separately under their own Bloomberg agreements. It is not affiliated with Bloomberg Finance L.P.

How do I install xbbg?

Run pip install xbbg, or conda install -c conda-forge xbbg for the conda-forge build. The blpapi Python package is not required; xbbg needs Bloomberg's shared runtime library, blpapi3_64.dll on Windows or libblpapi3_64.so on macOS and Linux, from a Terminal or DAPI install, a managed C++ SDK install or the official blpapi wheel.

Which output formats does xbbg support?

Results can be returned as Narwhals objects, native xbbg Arrow carriers, PyArrow, pandas, Polars, DuckDB and other optional Narwhals-backed libraries. The metadata notes that the narwhals floor was raised to 2.10.0 because earlier versions do not load the plugin entry point and conversion raises a TypeError about an ArrowTable.

Which Python versions does xbbg support?

The package metadata requires Python 3.11 or newer and below 3.16, with classifiers for 3.11 through 3.15. The Rust engine is on edition 2024 with a rust-version floor of 1.88, and the workspace ships crates for the Python and Node bindings.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. underloam/xbbg on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/underloam-xbbg.svg)](https://hysenlabs.com/projects/underloam-xbbg)

Was this useful?