Skip to main content

uv add nimlang

Use Nim in a Python project with nothing but uv.

nimlang is a Python package that ships the Nim compiler in its wheels and compiles C through zig cc from the ziglang package, so you need no system Nim and no C compiler.

nimpy is the core Nim dependency: it is the binding library that exports Nim procs to Python ({.exportpy.}) and lets Nim call Python. Every Nim extension module built with nimlang uses it.

AI disclosure: this project is mostly vibed. Currently level 7 on visidata AI scale: Human specced, bots coded.

Status: alpha. Ideas for evolution: ROADMAP.md.

Try it: a Python project with a Nim function

uv init uv-add-nimlang-demo && cd uv-add-nimlang-demo
uv add nimlang
uv run nimlang add nimpy            # Nim deps go in [tool.nimlang] in pyproject.toml
uv run nimlang info                 # bundled Nim and zig, and the project's Nim deps

slow.py, you have a slow function in Python:

def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)

fast.nim, you write it in Nim:

import nimpy

proc fib(n: int): int {.exportpy.} =
  if n < 2: n else: fib(n - 1) + fib(n - 2)

fast.py, and import it in Python (it needs the extensione module built):

from fast import fib

Build the extension module and compare slow and fast versions with timeit:

uv run nimlang build-ext fast.nim   # writes nimfib.<python-tag>.so (.pyd on Windows) next to it
uv run python -m timeit -s "from slow import fib" "fib(30)"   # 2 loops, best of 5: 135 msec per loop
uv run python -m timeit -s "from fast import fib" "fib(30)"   # 20 loops, best of 5: 10.6 msec per loop

How Nim and Nim dependencies are provided

The Nim compiler comes inside the nimlang wheel for your platform (Linux x86_64/aarch64, macOS arm64/x86_64, Windows x86_64). Each nimlang release bundles one Nim version, currently 2.2.6, along with atlas. uv run nim runs it with zig cc as the C compiler and with the project's Nim dependencies on the path:

uv run nim --version         # 2.2.6
uv run nim c -r hello.nim
uv run nimlang info          # which Nim and zig are used, and the project's Nim deps

On other platforms nimlang uses $NIMLANG_NIM_HOME or a nim on PATH. Choosing the Nim version per project is on the roadmap.

The C compiler is zig cc from the ziglang package, installed as a regular dependency.

Nim dependencies are declared in pyproject.toml, next to the Python ones, and pinned in a lock file, like uv does for Python packages:

[tool.nimlang]
dependencies = ["nimpy", "cligen >= 1.7"]
uv run nimlang add nimpy     # adds it to [tool.nimlang] and syncs
uv run nimlang remove nimpy  # removes it and syncs
uv run nimlang sync          # installs exactly what nimlang.lock pins
uv run nimlang lock          # resolves again to the newest allowed versions
  • Version constraints use atlas (nimble) syntax: the usual ==, >=, < operators, & to combine them ("nimib >= 0.3 & < 0.4"), and #head or #<commit> for git refs ("nimpy#head"). A package name alone takes the newest release, which the lock then pins.
  • nimlang.lock records the git URL and commit of every package, including transitive ones. Commit it, so every checkout and every wheel build uses the same code.
  • Packages are cloned with the bundled atlas into .nimlang/ (git-ignored), so git is needed. Builds through nimlang see only those packages, never ~/.nimble.
  • nimlang drives atlas for you: there is no atlas command, and nimble is not shipped. [tool.nimlang] and nimlang.lock are the only places dependencies are managed.

Ship Nim code in a Python package

uv-add-nimlang-lib-demo is a minimal package built this way and published on PyPI as nimlang-lib-demo. Its users get prebuilt wheels and need neither nimlang nor a compiler:

uv run --with nimlang-lib-demo python -m timeit -s "from nimlang_lib_demo.slow import fib" "fib(30)"
uv run --with nimlang-lib-demo python -m timeit -s "from nimlang_lib_demo.fast import fib" "fib(30)"

The setup is nimlang as a build requirement, plus its hatch hook pointing at the Nim files:

[build-system]
requires = ["hatchling", "nimlang"]
build-backend = "hatchling.build"

[tool.hatch.build.hooks.nimlang]
extensions = ["src/mypkg/fast.nim"]  # importable as mypkg.fast
# binaries = ["src/mypkg/mytool.nim"]  # installed as the `mytool` command

[tool.nimlang]
dependencies = ["nimpy"]

uv build produces a py3-none-<platform> wheel that works on every CPython 3 version. On Linux it is manylinux-compliant out of the box, and NIMLANG_TARGET=aarch64-macos uv build cross-builds for other platforms. The demo's CI builds all five platform wheels on one Linux machine and tests each on its own OS. Code that links a macOS system framework (std/random needs Security) finds it in the SDK xcrun reports on a Mac; to cross-build such code from another OS, point SDKROOT at a macOS SDK.

  • nimpy: Nim-Python bindings, the core dependency of every extension module (nimlang add nimpy).
  • nimpy_numpy: numpy array interop on top of nimpy, registered in the Nim package list (nimlang add nimpy_numpy).

Experiments in shipping Nim code to Python with nimlang:

  • uv-add-nimlang-lib-demo: minimal package published on PyPI as nimlang-lib-demo, with prebuilt wheels for five platforms.
  • nimpy-numpy: its tests and benchmark build Nim extensions with nimlang (a Vandermonde matrix, standard vs contiguous fast path, against numpy).
  • not1d: a minimal Nim port of ot1d (1D optimal transport), as a test of a non-trivial algorithm and of the C++ backend (an optional build uses C++ pdqsort). Not on PyPI; install it from git.

Building nimlang wheels

python scripts/make_wheels.py --nim-dist nim-2.2.6-linux_x64.tar.xz --platform-tag manylinux_2_17_x86_64

CI builds them for Linux (x86_64, aarch64), macOS (arm64, x86_64) and Windows x86_64, and publishes to PyPI when a v* tag is pushed.

Escape hatch: your own C compiler

If zig cc can't build something, NIMLANG_CC=system makes Nim use its default C compiler (gcc, clang or MSVC) instead. It is not tested in CI and cannot cross-compile, so it can't build wheels on Linux, where they always target glibc 2.17.

Metadata

Release files for nimlang 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nimlang 0.0.3
File Size Uploaded
nimlang-0.0.3.tar.gz 39.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for nimlang 0.0.3
File
nimlang-0.0.3-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
nimlang-0.0.3-py3-none-manylinux_2_17_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
nimlang-0.0.3-py3-none-manylinux_2_17_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
nimlang-0.0.3-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details
nimlang-0.0.3-py3-none-macosx_10_13_x86_64.whl Python 3 none macOS 10.13+ x86-64 Details

Total release size: 46.4 MB

Release files / nimlang-0.0.3.tar.gz

Download URL nimlang-0.0.3.tar.gz
Size 39.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b4a64f92ff7cdc47c88da3c4c523c86aff327b97072f35a0592fab857d1d7ade
BLAKE2b-256 checksum
How to use checksums
5a323ca3e2bc70a537e87fb5e83a4f77251175f9316ac2d2e4cb0bbee8813104
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nimlang-0.0.3-py3-none-win_amd64.whl

Download URL nimlang-0.0.3-py3-none-win_amd64.whl
Size 13.6 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
79f5f114c9cb8ae6a854aa1eff5785d3ee543b69e2dba1593b119f7f808238aa
BLAKE2b-256 checksum
How to use checksums
4490e7d8b3aef773d9d31507008714cde8197400a56221296c04de27a411dce8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nimlang-0.0.3-py3-none-manylinux_2_17_x86_64.whl

Download URL nimlang-0.0.3-py3-none-manylinux_2_17_x86_64.whl
Size 7.4 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
56468e7785a69b8d51fd48af3f60cd6bccf2c6be43aee3d9720b0fcc60840552
BLAKE2b-256 checksum
How to use checksums
c8a5c3f4b34cee777d688be40ae9a665a8e3c1d024b5a1488c2cae4c607b3e7e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nimlang-0.0.3-py3-none-manylinux_2_17_aarch64.whl

Download URL nimlang-0.0.3-py3-none-manylinux_2_17_aarch64.whl
Size 16.1 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
af242cb200fa428033b79acf49bc7921fd7d149b8c9ebfae85784efa7da36437
BLAKE2b-256 checksum
How to use checksums
1b81610390d649e869c2ca673ace3744e3591beb6060ca490bed8595080e8728
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nimlang-0.0.3-py3-none-macosx_11_0_arm64.whl

Download URL nimlang-0.0.3-py3-none-macosx_11_0_arm64.whl
Size 4.5 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
9c03ea6ba728135e32046632eb96f30b9001a9624e76f9dc83f526a550bb74b8
BLAKE2b-256 checksum
How to use checksums
f3b94473c6c6bc3fc534dfd7729fade6e7da3c6dc4924f7843026e3bbc948fb8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release files / nimlang-0.0.3-py3-none-macosx_10_13_x86_64.whl

Download URL nimlang-0.0.3-py3-none-macosx_10_13_x86_64.whl
Size 4.8 MB
Tags Python 3 macOS 10.13+ x86-64
SHA-256 checksum
How to use checksums
1f967774fe711b821067ca59501797be7d44c6fca9f13822cc0cd840fc358e38
BLAKE2b-256 checksum
How to use checksums
b8ac6474fa088dc65c04318af251dcea1a3afa627c3e427820bbbb481d8c0da0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.3 This release

6 release files

0.0.2

6 release files

0.0.1

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page