# Numba: a NumPy-aware JIT compiler for numerically focused Python

> Numba compiles a subset of Python and NumPy to machine code through LLVM, with optional parallel loops and CUDA targets. It suits numerical kernels written in plain Python, not general application code.

**numba/numba** — NumPy aware dynamic Python compiler using LLVM

- Repository: https://github.com/numba/numba
- Website: https://numba.pydata.org/
- Stars: 11,167 · Forks: 1,332
- Language: Python
- License: BSD-2-Clause
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/numba-numba

## What Numba is for, and who it is not for

Numba is an open source, NumPy-aware optimizing compiler for Python sponsored by Anaconda, Inc. It uses the LLVM compiler project to generate machine code from Python syntax. The README states that it can compile a large subset of numerically-focused Python, including many NumPy functions, and that it also supports automatic parallelization of loops, generation of GPU-accelerated code, and creation of ufuncs and C callbacks.

The intended user writes loops and array math in Python, hits a speed wall, and does not want to rewrite the kernel in C or Cython. The compiler is not a general Python accelerator. The phrase "large subset" is doing real work in that sentence: code that leans on dynamic attribute lookup, arbitrary third-party objects, or heavy string processing falls outside what the type inference can handle. If your slow code is mostly waiting on a database or parsing text, Numba has nothing to offer.

## How the LLVM pipeline turns a Python function into machine code

The mechanism is just-in-time compilation. A decorated function is not compiled when the module is imported; it is compiled the first time it is called with a given set of argument types. Numba inspects those types, builds an intermediate representation, and hands it to LLVM, which emits machine code for the host CPU. Subsequent calls with the same types reuse the compiled version.

That design explains the two behaviours users notice first. The first call is slow because compilation happens then, so timing a single invocation measures the compiler rather than the kernel. And because specialization is per type signature, calling the same function with an int array and later with a float array triggers a second compilation.

The repository layout reflects the scope of the project. There is a numba/ package, a docs/ tree, buildscripts/, and a runtests.py at the top level. The build is wired through setup.py and versioneer.py, and the project tracks its releases with towncrier.toml and a CHANGE_LOG file. Parallel and GPU support are not bolted on from outside: the topics list includes cuda and parallel alongside compiler and llvm.

## Installing Numba and compiling a first kernel

The README does not inline install commands. It points to the installation page in the online documentation, and the package is published on PyPI. The install page is where the supported platforms and wheel availability are described:

```bash
https://numba.readthedocs.io/en/stable/user/installing.html
```

The build constraints in setup.py are worth reading before you install. The supported Python range is >=3.10 and <3.16, the minimum NumPy version at runtime is 1.22.3, and llvmlite is pinned to the 0.51.0dev0 to 0.52 window. Installing into an environment outside those ranges fails the version guard rather than degrading quietly.

The README also points at a set of demo notebooks hosted through mybinder, which show how the compiler is applied in practice:

```bash
https://mybinder.org/v2/gh/numba/numba-examples/master?filepath=notebooks
```

Those notebooks are the closest thing the README offers to a worked example. Note that nopython mode is what you want while developing: if a function cannot be compiled without falling back to the interpreter, you get an error instead of a silent slow path. The first call pays the compilation cost, so call the function once before timing anything.

## Where Numba fails, and the shapes of code it refuses

The most common failure mode is the object mode fallback. When Numba cannot infer types for part of a function, it can compile a version that calls back into the Python interpreter for the unsupported pieces. The result runs, and it can be slower than the original, because every such call crosses the compiled-to-interpreted boundary. Running in nopython mode exists precisely to turn that silent degradation into a loud failure.

The second constraint is the supported language surface. Reflected lists, dictionaries with mixed value types, classes with dynamic attributes, and most of the standard library are outside the numerically-focused subset the README describes. Code that works in CPython may simply be rejected.

The third is dependency coupling. Numba is tied to a specific llvmlite version range, and llvmlite is tied to LLVM. Upgrading NumPy, Python, or the compiler toolchain ahead of Numba's supported window is a common way to break an environment. The min and max bounds in setup.py are not decorative.

## Numba against Cython and JAX

Cython is the closest comparison, and the difference is where the type information comes from. Cython asks you to annotate variables and function signatures in a Cython dialect, then compiles ahead of time into an extension module. Numba asks for no annotations at all and infers types at call time. The trade is control versus ceremony: Cython gives you a predictable build artifact and access to C-level constructs, while Numba gives you a decorated Python function and a compilation pause on first call.

Against JAX, the split is different again. JAX is built around functional transformations and array programs, and it compiles through its own tracing and XLA path. Numba stays closer to imperative Python loops, which is often what a scientist already has in front of them. A loop with an accumulator and an index is natural Numba code and awkward JAX code. The reverse holds for code that wants automatic differentiation or batched transforms.

Neither comparison is settled by benchmarks you did not run. The deciding question is which style of code you already have.

## Maintenance, releases and the BSD-2-Clause licence

The repository is not archived, and the last push was on 2026-09-18. Releases are frequent: 0.67.0 on 2026-08-12, 0.66.0 on 2026-07-06, and 0.65.1 on 2026-04-24. The CHANGE_LOG file and towncrier.toml indicate a changelog-driven release process, so upgrade notes are published rather than left to be discovered.

Upgrade cost is dominated by the llvmlite coupling described above. A Numba upgrade may require a matching llvmlite version, and that in turn constrains which LLVM the wheel was built against. On platforms without a prebuilt wheel, the build path is heavier: setup.py includes a build-time switch, NUMBA_LAPACK_ILP64, for selecting the ILP64 BLAS/LAPACK ABI, and the install documentation has a section on build-time environment variables.

The licence is BSD-2-Clause, a permissive licence. Redistribution in source or binary form is allowed provided the copyright notice and licence text are retained. That is a summary of the identifier, not legal advice, and the LICENSE and LICENSES.third-party files in the repository are the authoritative texts.

## Conclusion

Adopt Numba when the hot path is a numerical loop over NumPy arrays and you want to keep the code in Python. Skip it when the bottleneck is I/O, string handling, or library calls that Numba cannot type. Before committing, check that your Python and NumPy versions fall inside the ranges setup.py enforces, and confirm that llvmlite builds on your platform. The install page at numba.readthedocs.io is the authoritative source for wheels and platform notes.

## FAQ

### What is Numba used for?

It compiles numerically-focused Python and NumPy functions to machine code through LLVM, and it also supports automatic parallelization of loops, GPU-accelerated code generation, and the creation of ufuncs and C callbacks.

### Is Numba still active?

The repository is not archived and the last push was on 2026-09-18, with 0.67.0 released on 2026-08-12.

### What is Numba vs NumPy?

NumPy provides the array types and functions that Numba understands; Numba is the compiler that translates a subset of Python and NumPy code into machine code. The README describes Numba as NumPy-aware rather than as a replacement.

### How do I install Numba?

The README points to the installation page in the online documentation, and the package is published on PyPI. setup.py enforces Python >=3.10 and <3.16 and a minimum NumPy runtime version of 1.22.3.

### How do I use Numba in Python?

The README points to demo notebooks hosted through mybinder, and the compiler applies to a large subset of numerically-focused Python, including many NumPy functions. Running in nopython mode makes the compiler raise an error instead of falling back to the interpreter when it cannot type the function.

### Is Numba faster than Cython?

The README and the repository files contain no benchmark comparing the two, so no speed claim can be made. The structural difference is that Cython compiles ahead of time from annotated Cython source, while Numba infers types at call time and compiles just in time.

## Sources

- [License: BSD-2-Clause](https://github.com/numba/numba/blob/main/LICENSE)
- [numba/numba on GitHub](https://github.com/numba/numba)
- [Project website](https://numba.pydata.org/)
- [README](https://github.com/numba/numba/blob/main/README.md)
- [Releases](https://github.com/numba/numba/releases)

---

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