# Codon: compiling Python to native code with a NumPy rewrite

> Codon is a Python implementation from Exaloop that compiles ahead of time to native machine code and ships its own compiled NumPy. It is for numeric and parallel workloads, not for code that depends on CPython runtime behaviour.

**exaloop/codon** — A high-performance, zero-overhead, extensible Python compiler with built-in NumPy support

- Repository: https://github.com/exaloop/codon
- Website: https://docs.exaloop.io
- Stars: 16,842 · Forks: 603
- Language: Python
- License: Apache-2.0
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/exaloop-codon

## What Codon solves, and for whom

CPython interprets bytecode and holds the GIL, so a numeric loop that runs for minutes in Python is often rewritten in C, C++ or Rust. Codon removes that rewrite step for a subset of Python by compiling the same source ahead of time to native machine code. The README describes typical speedups over vanilla Python as being on the order of 10-100x or more on a single thread, and says performance is typically on par with C and C++. Its stated goals include no learning curve relative to CPython syntax and semantics, full multicore and GPU support, and interoperability with Python's package ecosystem.

The audience is narrower than "Python developers". It is people who own a compute-bound kernel: simulation loops, array math, prime counting, image generation, anything where the interpreter is the bottleneck. The README is explicit that Codon is not a drop-in replacement for CPython and that parts of Python unsuitable for static compilation are not supported. Larger codebases are expected to reach Codon through the JIT decorator or the Python extension backend rather than by rewriting everything.

## How the compilation pipeline and runtime work

Codon is a compiler, not an interpreter with a faster loop. Source goes through the compiler front end and is lowered to LLVM IR; the README shows `codon build -release -llvm file.py` as a way to emit that IR directly, which is the clearest evidence that LLVM sits underneath. The output is native machine code, and the README states there is no runtime overhead, which is why the project describes itself as zero-overhead.

Two consequences follow from that design. First, the standard library is reimplemented rather than delegated: the README says Codon includes a feature-complete, fully-compiled native NumPy implementation that uses the same API as NumPy but re-implements everything in Codon, which is what allows optimizations across array operations. Second, parallelism is a language-level concern. `@par` annotates a `for` loop and maps to OpenMP; the README example passes `schedule='dynamic'`, `chunk_size=100` and `num_threads=16`. The README notes that Codon automatically turns a `total += 1` in the loop body into an atomic reduction to avoid race conditions, so the reduction is inferred rather than written by hand.

GPU support is exposed two ways. There is a `gpu` module with a `@gpu.kernel` decorator, where the kernel reads `gpu.block.x`, `gpu.block.dim.x` and `gpu.thread.x` and is launched with an explicit `grid` and `block` shape. The README also states the same work can be expressed with `@par(gpu=True)`. Both paths are documented under the GPU programming section of the docs.

## Installing Codon and running a first program

The README gives a single install command that downloads and runs the project's install script. After the prompts finish, the `codon` command is on the path. Building from source is possible but the README points to a separate advanced build page in the docs rather than describing it inline.

```bash
/bin/bash -c "$(curl -fsSL https://exaloop.io/install.sh)"
```

With the compiler installed, `codon run` executes a file and `codon build` produces an executable. The `-release` flag enables optimizations, and the README lists `-llvm` as an option that emits IR instead of a binary.

```bash
codon run -release fib.py
codon build -release fib.py
codon build -release -llvm fib.py
```

The README's own benchmark script is a recursive Fibonacci function using `time()` from the `sys`-adjacent standard library. Running it through Codon prints the same answer as CPython, but the README reports 0.275645 seconds for `codon run -release fib.py` against 17.979357957839966 seconds for `python3 fib.py` on `fib(40)`. Treat those as the project's published numbers on its own hardware, not a guarantee for your workload.

If you need a Python package, the import form changes. The README shows `from python import matplotlib.pyplot as plt` and notes that the `CODON_PYTHON` environment variable must point at the CPython shared library, as described in the Python interoperability docs.

```python
from python import matplotlib.pyplot as plt
data = [x**2 for x in range(10)]
plt.plot(data)
plt.show()
```

## The @par annotation and what it assumes about your loop

The parallel example in the README counts primes below a limit. The loop body calls `is_prime(i)` and increments `total`. The annotation supplies the scheduling policy, the chunk size and the thread count, and Codon infers the reduction on `total`.

```python
@par(schedule='dynamic', chunk_size=100, num_threads=16)
for i in range(2, limit):
    if is_prime(i):
        total += 1
```

This is the part of Codon that differs most from ordinary Python, and it is worth being precise about the trade-off. Inference of the reduction is convenient, but it means the compiler has to decide that `total += 1` is safe to make atomic. A loop whose body mutates shared state in a less obvious way, through an aliased list or a captured object, is not covered by the example the README gives. The README points to the multithreading docs for detail; the README itself does not document the failure modes of a mis-inferred reduction. If your parallel loop writes to anything beyond a scalar accumulator, read that page before trusting the annotation.

## Where Codon is the wrong tool

The non-goals section is the most useful part of the README for a decision. Codon is not a drop-in replacement for CPython, and the project does not intend to become one. Aspects of Python that do not suit static compilation are left out. That single sentence rules out a large class of code: anything relying on runtime mutation of classes, on `eval`-style dynamism, or on libraries that assume they are running inside a CPython process with the full C API available.

The second non-goal is about syntax. The project tries to avoid adding new keywords or language features, and the README admits Codon does add syntax in a couple of places, naming parallelism as the example. So the language is close to Python but not identical, and the docs maintain a dedicated "Differences with Python" page rather than claiming equivalence.

There is also a practical boundary around the ecosystem. Python interop exists and the README demonstrates importing matplotlib, but it requires `CODON_PYTHON` to be set to a CPython shared library. That is a configuration step with a real failure mode: if the variable is wrong or unset, the import path described in the README will not work, and the README defers the details to the interoperability docs rather than restating them. If your program is mostly glue around third-party packages, Codon adds a build step and an environment variable without removing the interpreter from the picture.

## Codon against Numba and Cython

The obvious alternatives for speeding up numeric Python are Numba and Cython, and the difference is where compilation happens. Numba is a JIT: you decorate a function, and machine code is generated at runtime for the argument types it sees. Cython is a separate language that compiles to a CPython extension module, so the result is still loaded into a CPython process and still subject to the GIL unless you release it explicitly.

Codon compiles the whole program ahead of time to a native binary, and the README's central claim is that no runtime is involved. That is what makes `codon build -release fib.py` produce a standalone executable and what makes native multithreading possible without the GIL. The README states plainly that unlike Python, Codon supports native multithreading.

The cost of that approach is compatibility. Numba and Cython sit inside CPython, so the rest of your program keeps working unchanged. Codon asks you to move the program into its compiler, accept the documented differences, and use `from python import` when you need a CPython package. If your bottleneck is one function inside a large CPython application, a JIT or an extension module is the smaller change. If the whole program is the bottleneck and you want a binary at the end, Codon's model is the one that matches.

## Licence, releases and what an upgrade costs

Codon is licensed under Apache-2.0. That is a permissive licence, and the repository carries a LICENSE file at the top level alongside CODEOWNERS and CONTRIBUTING.md. This is a description of what the repository states, not legal advice; if you redistribute Codon or link against it, read the licence text and your own counsel's reading of it.

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent and versioned: v0.20.0 on 2026-09-08, v0.20.1 on 2026-09-10 and v0.20.2 on 2026-09-16. The 0.x version numbers are the thing to weigh. A compiler at 0.x can change semantics between minor releases, and the docs maintain a "Differences with Python" page that may be updated alongside the compiler. The repository layout includes a `test/` directory and a `bench/` directory, so there is a test suite to run against your own code, but the README does not describe a compatibility or deprecation policy for language changes across releases.

Upgrade cost therefore depends on how much of the documented difference surface you touch. Code that stays inside the supported subset and uses the compiled NumPy is cheap to move forward. Code that leans on `from python import` interop sits closer to the boundary between two runtimes, and that is where a version bump is most likely to require work. The README does not document rollback, so pinning a specific release is the only mechanism it implies.

## Conclusion

Codon suits engineers with numeric, array-heavy or parallel Python who can restructure code around static compilation and accept that some CPython behaviour is unsupported. It does not suit projects that rely on dynamic features, on arbitrary CPython packages, or on being a drop-in replacement. Before committing, verify that your hot path avoids the differences listed in the docs, that CODON_PYTHON points at a CPython shared library if you need Python interop, and that your build target is covered by the platform notes in the documentation.

## FAQ

### How do I install Codon?

The README gives a single command that downloads and runs the install script, after which the codon command is available. Building from source is also possible, and the README links to an advanced build page in the docs for that path.

### How do I use Codon with Python code?

Codon supports much of Python, and the README says many Python programs work with few if any modifications. To call a CPython package, import it with from python import, and set the CODON_PYTHON environment variable to the CPython shared library as the interoperability docs describe.

### Is Codon a drop-in replacement for CPython?

No. The README lists drop-in replacement for CPython as an explicit non-goal, because some aspects of Python are not suitable for static compilation. Larger codebases are expected to use the JIT decorator or the Python extension backend instead.

### Does Codon support NumPy?

Yes. The README states that Codon includes a feature-complete, fully-compiled native NumPy implementation that uses the same API as NumPy but re-implements everything in Codon itself.

### How does Codon handle multithreading?

Codon supports native multithreading through OpenMP, and unlike Python it has no GIL. The @par annotation parallelizes a for loop with options such as schedule, chunk_size and num_threads, and the README notes that a scalar increment in the loop body is turned into an atomic reduction automatically.

### What license is Codon released under?

The repository lists Apache-2.0 and carries a LICENSE file at the top level.

## Sources

- [exaloop/codon on GitHub](https://github.com/exaloop/codon)
- [License: Apache-2.0](https://github.com/exaloop/codon/blob/develop/LICENSE)
- [Project website](https://docs.exaloop.io)
- [README](https://github.com/exaloop/codon/blob/develop/README.md)
- [Releases](https://github.com/exaloop/codon/releases)

---

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