# nanobind: Faster C++/Python Bindings with Smaller Binaries Than pybind11

> nanobind is a BSD-3-Clause C++ library for exposing C++ types in Python, designed as a faster replacement for pybind11 with near-identical syntax. The benchmarks in the README show up to 4x faster compile times, 5x smaller binaries, and 10x lower runtime overhead than pybind11. It requires Python 3.10 or later.

**wjakob/nanobind** — nanobind: tiny and efficient C++/Python bindings

- Repository: https://github.com/wjakob/nanobind
- Stars: 3,732 · Forks: 329
- Language: C++
- License: BSD-3-Clause
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/wjakob-nanobind

## What nanobind Does and Who It Targets

nanobind is a C++ library that exposes C++ types in Python and Python types in C++. The README describes it as reminiscent of Boost.Python and pybind11 and using near-identical syntax to both. In contrast to those tools, it compiles faster, produces smaller binaries, and imposes lower runtime overhead.

The target users are C++ library developers who want to provide Python bindings for their code. A typical use case is a high-performance C++ library, such as a numerical computation or machine learning component, that needs to be callable from Python without the overhead of ctypes or cffi. The near-identical syntax to pybind11 means that teams already familiar with pybind11 can start using nanobind with minimal relearning.

The author is Wenzel Jakob (EPFL), who lists an academic BibTeX citation in the README for use in scientific work. The library is BSD-3-Clause licensed, which permits commercial use and redistribution with attribution. The current development version in pyproject.toml is 3.2.0-dev1.

## Benchmark Figures: Compile Time, Binary Size, and Runtime Overhead

The README cites benchmark figures from the documentation site comparing nanobind against pybind11: approximately 4x faster compile time, 5x smaller binaries, and 10x lower runtime overheads. Against Cython, the comparisons show 3 to 12x binary size reduction and 1.6 to 4x compilation time reduction, with similar runtime performance.

The compile time improvement is particularly significant for large binding codebases. Projects that wrap dozens or hundreds of C++ classes with pybind11 often face build times that slow iteration. nanobind's faster compile path reduces this cost.

Binary size matters for projects that distribute Python wheels. A 5x reduction in binding binary size directly translates to smaller download sizes and faster import times. The 10x runtime overhead reduction means that the per-call cost of crossing the Python/C++ boundary is lower, which matters for workloads that make many small calls across the binding layer.

All of these figures come from benchmarks documented at nanobind.readthedocs.io, not from independent testing.

## Python Stable ABI and Multi-Version Distribution

One of the reasons JAX migrated to nanobind, as documented in the README, is its support for the Python Stable ABI starting with Python 3.12. The JAX contributor writes: "nanobind can target the Python Stable ABI starting with Python 3.12. This means that we will not need to ship per-Python version CUDA plugins starting with Python 3.12."

For projects that distribute compiled Python extensions, maintaining separate builds for Python 3.10, 3.11, 3.12, and each future release is a real operational burden. The Stable ABI allows a single binary extension to run across all supported Python versions from 3.12 onward. Projects that move to nanobind on Python 3.12 or later can ship a single wheel rather than a version matrix.

The Python version requirement for nanobind itself is Python 3.10 or later, as set in pyproject.toml. Stable ABI targeting is a separate opt-in that begins at Python 3.12. Projects on Python 3.10 or 3.11 can use nanobind but will still need per-version builds.

## Installing nanobind and Setting Up a New Extension

nanobind is published to PyPI under the package name `nanobind`. The pyproject.toml sets requires-python to >=3.10, so a Python 3.10 or later environment is required:

```bash
pip install nanobind
```

The library uses scikit-build-core as its build backend, as declared in pyproject.toml:

```toml
[build-system]
requires = ["scikit-build-core >=0.10"]
build-backend = "scikit_build_core.build"
```

For building a new extension that uses nanobind, the standard approach is a CMake-based project that links against nanobind. The repository includes a CMakeLists.txt and a cmake/ directory with nanobind's configuration. An example project is available at github.com/wjakob/nanobind_example, referenced in the README, which demonstrates the project structure and CMake configuration needed to build a minimal nanobind extension.

The repository structure is: include/ for nanobind's C++ headers, src/ for compiled C++ components, nanobind-backend/ for backend code, tests/ for the test suite, and docs/ for the documentation source. Full tutorial and reference documentation is at nanobind.readthedocs.io in HTML and PDF formats.

## Real-World Adoption Evidence from the README

The README includes testimonials from developers at Google, Apple, and other organizations who migrated from pybind11 to nanobind in production. The README quotes the IREE team: "It has been one of the single best dep decisions I've made. Not only is it much-much faster to compile, it produces smaller binaries and has a much more lean interface to the underlying Python machinery that all adds up to significant performance improvements."

Apple's MLX team reports: "MLX uses nanobind to bind C++ to Python. It's a critical piece of MLX infra and is why running Python code is nearly the same speed as running C++ directly. Also makes it super easy to move arrays between frameworks."

The FEniCS/DOLFINx team adds specific context about multi-dimensional array wrapping: "nanobind is smaller than pybind11, the wrappers build faster and it has significantly improved support for wrapping multi-dimensional arrays, which we use heavily."

JAX and XLA/MLIR at Google, and PennyLane's Catalyst project, are also listed among the migration testimonials. These are documented claims from the README, not an independent assessment of their accuracy.

## What nanobind Does Not Cover

nanobind requires Python 3.10 or later, as declared in pyproject.toml. Any project that must maintain compatibility with Python 3.9 or earlier cannot use nanobind. This is a harder constraint than pybind11, which supports older Python versions.

The README describes the syntax as near-identical to pybind11, not drop-in compatible. Migrating an existing pybind11 codebase to nanobind requires reviewing and updating the binding code, not just changing a header include. The FEniCS contributor's quote acknowledges that the migration involves real work: understanding the memory management in the wrapper layer.

The repository has no GitHub releases; releases are tracked through Git tags. Teams relying on GitHub Releases notifications for dependency updates will not find a signal here.

The Python Stable ABI advantage applies from Python 3.12 onward. Projects on Python 3.10 or 3.11, even with nanobind, still need to build per-version wheels for distribution.

## pybind11 as the Direct Predecessor

pybind11 is a widely-used header-only C++ library for creating Python bindings that nanobind was explicitly designed to improve upon. The README says nanobind "is reminiscent of" pybind11 and "uses near-identical syntax."

The key qualitative difference is age and design philosophy. pybind11 is a mature, battle-tested library with wider Python version support and a large body of existing extensions. Many scientific Python projects, such as NumPy, SciPy, and PyTorch, have used pybind11 for their C++ binding layer. pybind11 is header-only, which simplifies its integration into build systems but contributes to longer compile times.

nanobind makes different trade-offs: it has compiled components rather than being purely header-only, which allows it to move work out of the header layer and reduce per-project compile times. It requires a newer Python, and the near-identical syntax does not eliminate migration effort for existing pybind11 codebases.

For a new project starting without an existing binding layer, nanobind's faster build times and smaller output are arguments in its favor. For an existing project on pybind11 that works and has no performance or binary size constraints, migration has a real cost and offers incremental, not essential, gains.

## Conclusion

C++ developers who are wrapping library code for Python and either already use pybind11 or are starting fresh should evaluate nanobind. The critical thing to check before migrating an existing pybind11 codebase: the README describes the syntax as near-identical, not drop-in compatible, so migration requires code review rather than a simple search-and-replace. Python 3.10 or later is required, so projects that must support older Python versions cannot use nanobind. The Python Stable ABI support from Python 3.12 onward eliminates the need to ship separate builds for each Python minor version. The last push to the repository was on 2026-09-25.

## FAQ

### What is nanobind?

nanobind is a BSD-3-Clause C++ library for creating Python bindings for C++ code, similar to pybind11 and Boost.Python but designed for faster compile times, smaller binaries, and lower runtime overhead. It requires Python 3.10 or later and is published on PyPI.

### Which is better, pybind11 or nanobind?

According to the benchmarks cited in the README, nanobind compiles approximately 4x faster, produces 5x smaller binaries, and has 10x lower runtime overhead than pybind11. The trade-off is that nanobind requires Python 3.10 or later, while pybind11 supports older Python versions. The syntax is near-identical, not drop-in compatible, so migrating an existing pybind11 codebase requires code review.

### How do I install nanobind?

nanobind is published on PyPI under the package name nanobind and requires Python 3.10 or later. For building a new extension, the standard approach uses scikit-build-core (version 0.10 or later) and CMake. An example project is available at github.com/wjakob/nanobind_example, linked from the README.

## Sources

- [Issues](https://github.com/wjakob/nanobind/issues)
- [License: BSD-3-Clause](https://github.com/wjakob/nanobind/blob/master/LICENSE)
- [README](https://github.com/wjakob/nanobind/blob/master/README.md)
- [wjakob/nanobind on GitHub](https://github.com/wjakob/nanobind)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wjakob-nanobind
