16 March 2026

Nuitka Release 4.0

This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”.

This release is a major release with many new features and the long wanted improvements for scalability of the Python compilation.

Bug Fixes

  • Accelerated: The enhanced detection for uninstalled Anaconda and WinPython was not fully working. (Fixed in 2.8.1 already.)

  • Onefile: Fixed an issue in DLL mode where signal handlers were not being registered, which could prevent proper program termination on signals like CTRL-C. (Fixed in 2.8.1 already.)

  • Windows: Fixed incorrect handling of forward slashes in cache directory paths, which caused issues with Nuitka-Action. (Fixed in 2.8.1 already.)

  • UI: The --output-dir option was not being honored in accelerated mode when --output-filename was also provided. (Fixed in 2.8.2 already.)

  • UI: The --output-filename option help said it wouldn’t work for standalone mode when in fact it did for a while already. (Fixed in 2.8.2 already.)

  • Onefile: On Windows, fixed a crash when using --output-dir where it was checking for the wrong folder to exist. (Fixed in 2.8.2 already.)

  • macOS: Fixed a crash that could occur when many package-specific directories were used, which could lead to the otool command line being too long. (Fixed in 2.8.2 already.)

  • Standalone: For the “Python Build Standalone” flavor, ensured that debug builds correctly recognize all their specific built-in modules, preventing potential errors. (Fixed in 2.8.4 already.)

  • macOS: Fixed an issue where $ORIGIN r-paths were set but ended up unused, which in some cases caused errors by exhausting the header space and preventing the build entirely. (Fixed in 2.8.5 already.)

  • macOS: Fixed an issue to ensure the system xattr binary is used.

    Otherwise, using arch -x86_64 python for compilation could fail when some packages are installed that provide xattr as well, because that might be an arm64 binary only and would not work. (Fixed in 2.8.5 already.)

  • UI: Fixed a misleading typo in the rejection message for unsupported Python 3.13.4. (Fixed in 2.8.5 already.)

  • Accelerated: The runner scripts .cmd or .sh now are also placed respecting the --output-filename and --output-dir options. (Fixed in 2.8.5 already.)

  • Plugins: Ensured that plugins detected by namespace usage are also activated in module mode. (Fixed in 2.8.5 already.)

  • Standalone: Fixed an issue where non-existent packages listed in top_level.txt files could cause errors during metadata collection. (Fixed in 2.8.6 already.)

  • Standalone: Corrected the classification of the site module, which was previously treated as a standard library module in some cases. (Fixed in 2.8.6 already.)

  • Windows: Ensured that temporary link libraries and export files created during compilation are properly deleted, preventing them from being included in the standalone distribution. (Fixed in 2.8.6 already.)

  • Python3.14: Adapted to core changes by no longer inlining hacl code for this version. (Fixed in 2.8.6 already.)

  • Python 3.14: Follow allocator changes and immortal flags changes.

  • Python 3.14: Follow GC changes for compiled frames as well.

  • Python 3.14: Catch attempts to clear a compiled suspended frame object.

  • Fixed a potential mis-optimization for uses of locals() when transforming the variable name reference call. (Fixed in 2.8.6 already.)

  • Module: Fixed pkgutil.iter_modules not working when loading a module into a namespace. (Fixed in 2.8.7 already.)

  • Reports: Fixed a crash when creating the compilation report before the source directory is created. (Fixed in 2.8.7 already.)

  • Standalone: Fixed ignoring of non-existent packages from top_level.txt for metadata. (Fixed in 2.8.7 already.)

  • UI: The --no-progress-bar option was not disabling the Scons progress bars. (Fixed in 2.8.7 already.)

  • UI: Fixed an exception in the tqdm progress bar during process shutdown. (Fixed in 2.8.7 already.)

  • Windows: Fixed incorrect sys.executable value in onefile DLL mode. (Fixed in 2.8.9 already.)

  • Python3.14: Added missing implicit dependency for _ctypes on Windows. (Fixed in 2.8.9 already.)

  • Python3.13+: Fixed missing export of PyInterpreter_* API.

  • Python3.14: Adapted to change in evaluation order of __exit__ and __enter__.

  • Multiprocessing: Fixed issue where sys.argv was not yet corrected when argparse was used early in spawned processes.

  • Scons: Fixed an issue where Zig was not used as a fallback when MinGW64 was present but unusable.

  • Windows: Made onefile binary work on systems without runtime DLLs installed as well.

  • Scons: Made tracing robust against threaded outputs.

  • Python3.12+: Enhanced workaround for loading of extension modules with sub-packages to cover more cases.

  • Scons: Fixed missing Zig version output.

  • Scons: Fixed Zig detection to enforce PATH or CC usage on macOS instead of download, since it’s not available.

  • UI: Fixed normalization of user paths, improving macOS support for reporting.

  • Linux: Fixed the workaround for the memset zero length warning, which was wrongly applied to Clang. Only GCC requires it, and Clang complained about it.

  • Linux: More robust fallback to g++ when gcc is too old for C11 support.

  • Compatibility: Fixed a bug where del of a subscript could cause wrong runtime behavior due to missing control flow escape annotations for the subscript value itself and the index.

  • macOS: Fixed an issue where Info.plist user-facing entitlements keys mapping to multiple internal entitlements were not handled correctly.

  • UI: Ensured tracing uses at least 80 characters for very narrow terminals to maintain readability.

  • Compatibility: Fixed an issue where nested loops could have incorrect traces, potentially leading to mis-optimizations.

  • Linux: Fixed an issue where _XOPEN_SOURCE was mistakenly appended for Clang, causing warnings.

  • Scons: Improved passed variables handling by detecting None or invalid types earlier.

  • Fixed a bug where propagating class dictionaries needed extra micro passes to ensure proper optimization of their traces for the new variables.

  • Scons: Fixed an issue with process spawning when using rusage capture.

  • Scons: Followed the file closing behavior of the standard communicate closer to avoid potential hangs.

Package Support

  • Anti-Bloat: Avoided a warning during program shutdown when using a compiled xgboost package. (Fixed in 2.8.1 already.)

  • Standalone: Added support for the oracledb package. (Fixed in 2.8.2 already.)

  • macOS: Added support for newer PySide6 versions. (Fixed in 2.8.4 already.)

  • Standalone: Added support for including more metadata for the transformers package. (Fixed in 2.8.5 already.)

  • Standalone: Metadata from Nuitka Package Configuration is now only included if the corresponding package is part of the compilation. (Fixed in 2.8.5 already.)

  • Standalone: Added support for the win32ctypes package. (Fixed in 2.8.6 already.)

  • Standalone: Added support for newer versions of the dask package. (Fixed in 2.8.6 already.)

  • Standalone: Added support for the dataparser package. (Added in 2.8.7 already.)

  • Standalone: Added support for puremagic, pygments.lexers and tomli in standalone mode.

  • Standalone: Added automatic detection of mypyc runtime dependencies, no need to manually configure that anymore. Also our configuration was often only correct for a single OS, and single upstream versions which is now fixed for packages having it before.

  • Standalone: Added support for the newer av (PyAV) package version.

  • Standalone: Added support for the sentry_sdk, jedi, parso, and line_profiler packages.

  • Standalone: Added support for newer pandas versions.

New Features

  • UI: Added support for --project parameter to build using configuration from pyproject.toml (e.g. Poetry, Setuptools).

    With this, you can simply run python -m nuitka --project --mode=onefile and it will use the pyproject.toml or setup.py/setup.cfg files to get the configuration and build the Nuitka binary.

    Previously Nuitka could only be used for building wheels with build package, and for building wheels that is still the best way.

    The --project option is currently compatible with build and poetry and detects the used build system automatically.

  • Zig: Added experimental support for using Zig project’s zig cc as a C compiler backend for Nuitka. This can be enabled by setting the CC environment variable to point to the zig or zig.exe executable.

  • Reports: Started capturing rusage for OSes that support it.

    • Only POSIX-compliant OSes will do it (Linux, macOS, and all BSD variants), but Android does not.

    • Not yet part of the actual report, as we need to figure out how to use and present the information.

  • Scons: Added experimental support for enabling Thin LTO with the Clang compiler.

  • Standalone: Honor --nofollow-import-to for stdlib modules as well.

    This allows users to manually reduce standard library usage, but it can also cause crashes from extension modules not prepared for the absence of standard library modules.

  • Onefile: Allowed disabling the onefile timeout and hard killing on CTRL-C entirely by providing --onefile-child-grace-time=infinity.

  • Scons: Added newer inline copy of Scons which supports Visual Studio 2026. (Added in 2.8.7 already.)

  • Scons: Allowed using Python versions only partially supported for Nuitka with Scons. (Added in 2.8.7 already.)

  • UI: Added option --devel-profile-compilation for compile time profiling. Also renamed the old runtime profiling option --profile to --debug-profile-runtime, that is however still broken.

  • Reports: Including CPU instr and cycle counters in timing on native Linux.

    • With appropriate configuration on Linux this allows to get at very precise timing configuration so we can judge even small compile time improvements correctly. We then don’t need many runs to average out noise from other effects.

    • Don’t use wall clock but process time for steps that are not doing IO like module optimization for more accurate values otherwise, it is however not very accurate still.

  • Python3.12+: Added support for function type syntax (generics).

  • Python3.14: Added groundwork for deferred evaluation of function annotations.

  • Python3.14: Added support for uncompiled generator integration which is crucial for asyncio correctness and general usability with modern frameworks.

  • Debugging: Added --debug-self-forking to debug fork bombs.

  • Windows: Added --include-windows-runtime-dlls option to control inclusion of Windows C runtime DLLs. Defaults to auto.

  • Python 3.14: Added experimental support for deferred annotations.

  • Plugins: Added option --qt-debug-plugins for debugging Qt plugin loading.

  • DLLs: Added support for DLL tags to potentially control inclusion with more granularity.

  • macOS: Added support for many more protected resource entitlements (Siri, Bluetooth, HomeKit, etc.) to the bundle details.

  • Python: Added support for @nuitka_ignore decorator to exclude functions from compilation.

    @nuitka_ignore
    def my_cpython_func():
        # This function is not compiled, but stays bytecode
        ...
    
  • UI: Added support for merging user and standard YAML Nuitka package configurations, currently only including proper merging of implicit imports.

Optimization

  • Avoid making duplicate hard imports by dropping assignments if the variable was already assigned to the same value.

  • Found previous assignment traces faster.

    • The assignment and del nodes were using functions to find what they already knew from the last micro pass. The self.variable_trace already kept track of the previous value trace situation.

    • For matching unescaped traces we will do similar, but it’s not really used right now, so make it only a TODO as that will eventually be very similar.

    • Also speeds up the first micro pass even more, because it doesn’t have to search and do other things. If no previous trace exists, none is attempted to be used.

    • Also the common check if no by-name uses or merges of a value occurred was always used inverted and now should be slightly faster to use and allow to short-circuit.

    • While this accelerated the first micro pass by a lot for per-assignment work, it mainly means to cleanup the design such that traces are easier to re-recognize. And this is a first step with immediate impacts.

  • Much faster Python passes.

    • The “Escape” and “Unknown” traces now have their own number spaces. This allows doing some quick checks for a trace without using the actual object, but just its number.

    • Narrow the scope of variables to the outline scope that uses them, so that they don’t need to be dealt with in merging later code where they don’t ever change anymore and are not used at all.

    • When checking for unused variables, do not ask the trace collection to filter its traces. Instead it works off the ones attached to the variable already. This avoids a lot of searching work. It also uses a method to decide if a trace constitutes usage rather than a long elif chain.

  • Faster variable trace maintenance.

    • We now trace variables in trace collection as a dictionary per variable with a dictionary of the versions, this is closer to our frequent usage per variable.

    • That makes it a lot easier to update variables after the tracing is finished to know their users and writers.

    • Requires a lot less work, but also makes work less memory local such that the performance gain is relatively small despite less work being done.

    • It also avoids having to maintain a per-variable set for its using scopes.

    • Decide presence of writing traces for parameter variables faster.

  • Avoid unnecessary micro passes.

    • Detect variable references discarded sooner for better micro-pass efficiency. We were spending an extra pass on the whole module to stabilize the variable usage, which can end up being a lot of work.

    • After a module optimization pass found no changes, we no longer make an extra micro pass to avoid stabilization bugs, but only check against it not happening in debug mode. Depending on the number of micro passes, this can be a relatively high performance gain. For the telethon.tl.types module this was a 13% performance gain on top.

  • For “PASS 1” of telethon.tl.types, which has been one of the known troublemakers with many classes and type annotations, all changes combined improve the compilation time by 1500%.

  • Faster code generation.

    • Indentation in generated C code is no longer performed to speed up code generation. To restore readability, use the new option --devel-generate-readable-code which will use clang-format to format the C code.

  • Recognized module variable usages inside outlined functions that are in a loop, which improves the effectiveness of caching at run-time. (Added in 2.8.6 already.)

  • Standalone: Partially solved a TODO of minimizing intermediate directories in r-paths of ELF platforms, by only putting them there if the directory they point to will contain DLLs or binaries. This removes unused elements and reduces r-path size.

  • Windows: Made the caching of external paths effective, which significantly speeds up DLL resolution in subsequent compilations. (Fixed in 2.8.6 already.)

  • macOS: Removed extended attributes from data files as well, improving performance. (Fixed in 2.8.7 already.)

  • Scons: Stopped detecting installed MinGW to avoid overhead as it is not supported. (Fixed in 2.8.9 already.)

  • Scons: Added caching for MSVC information to reduce compilation time and if already available, use that to detect Windows SDK location rather that using vswhere.exe each time.

  • Avoid computing large % string interpolations at compile time. These could cause constants to be included in the binary as a result.

  • Avoid including importlib._bootstrap and importlib._bootstrap_external as they are available as frozen modules.

  • Fixed un-hashable dictionary keys not being properly optimized, forcing runtime handling.

Anti-Bloat

  • Avoid including tzdata on non-Windows platforms. (Fixed in 2.8.7 already.)

  • Avoid including pyparsing.testing in the pyparsing package.

  • Added configuration to avoid compiled via C for large generated files for the sqlfluff package.

Organizational

  • UI: Don’t say --include-data-files-external doesn’t work in standalone mode.

    It actually has worked for a while, and we since renamed that option, but the help still said it wouldn’t work in standalone mode.

  • Debugging: Added assertions for code object creation.

    We were getting assertions from Python when built with Zig, and these are supposed to provide those as well.

  • Debugging: In case of tool commands failing, output the too long command line if that was the error given.

  • Anti-Bloat: Don’t allow custom nofollow modes, point the user to the correct option instead. This was never needed, but two ways of providing this user decision make no sense.

  • UI: The help text for --include-data-files-external was updated to reflect that it works in standalone mode. (Fixed in 2.8.5 already.)

  • Release: Use lowercase names for source archives in PyPI uploads. (Fixed in 2.8.7 already.)

  • Quality: Fixed an issue where “assume yes” was not being passed for downloads in the commit hook.

  • UI: Improved wording for missing C compiler message.

  • Debugging: More clear verbose trace for dropped expressions.

  • Debugging: Output what module had extra changes during debug extra micro pass.

  • Quality: Manage more development tools (clang-format, etc.) via private pip space for better consistency and isolation.

  • AI: Enhanced pull request template with directions for AI-driven PRs.

  • AI: Added agent command create-mre to assist in creating a minimal reproduction example (MRE).

  • User Manual: Added documentation about redistribution requirements for Python 3.12-3.14.

  • Quality: Added --un-pushed argument to auto-format tool for checking only un-pushed changes.

  • Scons: Improved error message to point to Zig support if no C compiler is found.

  • MonolithPy: Follow rename of our Python fork to MonolithPy to avoid confusion with the Nuitka compiler project itself.

  • Scons: Prefer English output and warn user for missing English language pack with MSVC in case or outputs being made.

  • UI: When running non-interactively, print the default response that is assumed for user queries to stdout as well, so it becomes visible in the logs.

  • UI: Warn when using protected resources options without standalone/bundle mode enabled on macOS.

  • Reports: Sort DLLs and entry points in compilation reports by destination path for deterministic output.

  • Quality: Skip files with spell-checker: disable in codespell checks.

  • Release: Avoid compiling bytecode for inline copies that are not compatible with the running Python version during install.

  • Visual Studio: Ignored names in backticks and code blocks in ReST for spelling checks.

  • Actions: Ensured compilation reports are always recorded, even in case of errors, as they are most useful then.

  • AI: Added a workflow create-mre to assist in creating a Minimal Reproducible Example from a larger file triggering a Nuitka bug. This has guidance on avoiding standalone mode and instructions for reducing code to just produce a MRE that is really small.

  • AI: Added a workflow fix-module-not-found-error for solving simple ModuleNotFoundError at runtime errors.

  • AI: Added further strategies for Minimal Reproducible Example (MRE) reduction to the agent workflow.

  • UI: Reject input paths from standard library locations to prevent compiling files from there as main files.

Tests

  • Added support for --all with --max-failures option to the test runner to stop after a specified number of failures, or just run all tests and output the failed tests in the end.

    Also the tests specified can be a glob pattern, to match multiple tests, not just a test name.

    Added examples to the help output of the runner to guide the usage of the developers.

  • Ignore multiline source code outputs of Python3.14 in tracebacks for output comparison, Nuitka won’t do those.

  • Added test cases for poetry and distutils. Also verify that standalone mode works with --project for the supported build systems.

  • Made the distutils tests cases much more consistent.

  • Watch: Improved binary name detection from compilation reports for better mode support beyond standalone mode.

  • Allow downloading tools (like clang-format) for all test cases.

  • Added options to enforce Zig or Clang usage for C compiling.

  • Suppress pip output when not running interactively to avoid test output differences.

  • Added nuitka.format and nuitka.package_config to self-compilation tests.

  • Added colorization to test comparison diffs if a tty is available.

  • Avoided using --nofollow-imports in tests as some Python flavors do not work with it when using --mode=standalone.

Cleanups

  • Moved options to new nuitka.options package.

  • Python3.14: Fixed a type mismatch warning seen with MSVC. (Fixed in 2.8.9 already.)

  • Massive amounts of spelling cleanups. Correct spelling is more and more places allows identification of bugs more immediately, therefore these are very worthwhile.

  • Code cleanup and style improvements in Errors and OutputDirectories modules.

  • Replaced usages of os.environ.get with os.getenv for consistency and denser code.

  • Moved MSVC re-dist detection to DllDependenciesWin32.

  • Release: Don’t install zstandard by default anymore.

  • UI: Tone down complaint about checksum mismatches.

  • Static source files are now provided by Nuitka directly.

  • Renamed C function modulecode_ to module_code_ for consistency.

Summary

This release is finally a break-through for scalability. We will continue the push for scalability in the next release as well, but with more of a focus on the C compilation step, to generate C code that is easier for the backend compiler.

Also, this release finally addresses many usability problems. The non-deployment hooks for imports not found, that were actively excluded, are one such thing. The start of --project enables far easier adoption of Nuitka for existing projects.

Other huge improvements are related to generics, they are now much better support, closing gaps in the Python3.12 support.

The onefile DLL mode as used on Windows is finally perfect and should have no issues anymore, while enabling big future improvements.

Unfortunately 3.14 support is not yet ready and will have to be delayed until the next release.