{"id":1850,"library":"nanobind","title":"nanobind: tiny and efficient C++/Python bindings","description":"nanobind is a C++17-first binding library designed for creating efficient and minimalistic C++/Python interoperability layers. It enables seamless exposure of C++ types and functions to Python, often with significantly faster compile times, smaller binaries, and lower runtime overhead compared to alternatives like pybind11 and Cython. The library is actively developed, with a focus on performance and modern C++ practices, and supports Python 3.9+ and PyPy 7.3.10+.","status":"active","version":"2.12.0","language":"en","source_language":"en","source_url":"https://github.com/wjakob/nanobind","tags":["C++ bindings","FFI","performance","extension module","CMake","build system"],"install":[{"cmd":"pip install nanobind","lang":"bash","label":"Recommended via Pip (includes C++ and CMake source)"},{"cmd":"conda install -c conda-forge nanobind","lang":"bash","label":"Via Conda"}],"dependencies":[{"reason":"Runtime, requires Python 3.9+ or PyPy 7.3.10+.","package":"Python","optional":false},{"reason":"Build-time, requires CMake 3.15+ to compile nanobind extensions.","package":"CMake","optional":false},{"reason":"Build-time, requires Clang 8+, GCC 8+, MSVC2019+, MinGW-w64, Intel ICX, or CUDA NVCC.","package":"C++17 Compiler","optional":false},{"reason":"Build-time backend for creating Python packages with nanobind extensions.","package":"scikit-build-core","optional":false}],"imports":[{"note":"nanobind provides C++ headers; in Python, you import the *generated* extension module, not 'nanobind' directly. E.g., for a module named 'my_ext', you'd `import my_ext`.","symbol":"nanobind","correct":"import your_nanobind_module"}],"quickstart":{"code":"# Assuming you have built a nanobind extension named 'my_ext'\n# For example, with C++ code like:\n# NB_MODULE(my_ext_impl, m) { m.def(\"hello\", []() { return \"Hello world!\"; }); }\n# And an __init__.py with: from ._my_ext_impl import hello\n\nimport my_ext\n\nmessage = my_ext.hello()\nprint(message)\n","lang":"python","description":"This quickstart demonstrates the Python side of interacting with a nanobind-generated extension. It assumes a C++ module (e.g., `_my_ext_impl`) has been built and exposed via a Python package (`my_ext`), following the recommended packaging guidelines. The C++ code defines a simple 'hello' function, which is then imported and called from Python."},"warnings":[{"fix":"Ensure all dependent nanobind-based modules are rebuilt against the same nanobind version. Monitor nanobind's ABI version in the changelog.","message":"nanobind has a separate ABI version that is not subject to semantic versioning. Upgrades to nanobind (e.g., from 2.1 to 2.2) can introduce ABI incompatibilities, requiring all downstream packages that use nanobind to be rebuilt. This is critical for projects relying on pre-built binary wheels from other nanobind-dependent libraries.","severity":"breaking","affected_versions":"All versions, especially between minor releases (X.Y.Z where Y changes)."},{"fix":"Upgrade your Python environment to 3.9+ or use nanobind < 2.10.0.","message":"Support for Python 3.8 was officially dropped with nanobind version 2.10.0, which was released in December 2025. Projects using older Python versions must either upgrade their Python environment or pin nanobind to a version prior to 2.10.0.","severity":"breaking","affected_versions":">=2.10.0"},{"fix":"Update code to access `my_enum_entry.value` for integer representation, especially if the enum is not guaranteed to be `enum.IntEnum`-derived.","message":"In nanobind 2.0.0, the `nb::enum_<T>()` binding declaration changed to create `enum.Enum` or `enum.IntEnum`-derived types. Code that previously cast enum entries directly to integers might break if the enum is not `enum.IntEnum`-derived. Accessing `my_enum_entry.value` is the recommended approach.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Review nanobind's documentation on reference leaks and ensure correct ownership management. When possible, use nanobind wrappers over direct Python C API calls. Consider adding cleanup handlers if issues persist with type annotation caches.","message":"Warnings about 'leaked instances/functions/types' can occur, often indicating underlying reference counting issues within the binding code. This can be exacerbated by Python type annotations or improper `Py_INCREF` usage, leading to resource leaks during interpreter finalization.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that if common types are exposed across multiple extensions, their bindings are consistent. Consider using opaque types or isolating namespaces where conflicts are unavoidable.","message":"Conflicting type bindings can arise if multiple nanobind-based extensions expose or interact with the same C++ types (e.g., `std::latch`) inconsistently. nanobind will warn about such conflicts (e.g., `RuntimeWarning: nanobind: type 'latch' was already registered!`), which can lead to unpredictable behavior or crashes.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}