Python to EXE: Complete Guide 2026 (Nuitka, PyInstaller, Prometheus Shield)

You have written a Python application and you want to distribute it as a standalone Windows executable. No Python installation required. No pip dependencies. Just a .exe that users double-click and it works. This is one of the most common challenges in the Python ecosystem, and the landscape of solutions in 2026 has both improved and become more complex.

This guide covers every viable method, explains the trade-offs of each, and walks through the process with real code examples. We will pay special attention to the antivirus problem — the reason most Python-to-EXE solutions trigger false positives — and how to solve it.

The Methods: Quick Comparison

ToolApproachAV SafeSpeedSizeSource Protection
NuitkaC compilationYesFastestMediumStrong
PyInstallerBundled interpreterNoModerateLargeWeak
cx_FreezeBundled interpreterNoModerateLargeWeak
py2exeBundled interpreterNoModerateLargeWeak
Prometheus ShieldAutomated pipelineYesFastOptimizedMaximum

Method 1: PyInstaller

PyInstaller is the most popular Python-to-EXE tool, and for good reason — it handles most use cases with minimal configuration. The basic usage is straightforward:

pip install pyinstaller
pyinstaller --onefile --windowed my_app.py

This produces a single .exe file in the dist/ directory. The --onefile flag bundles everything into one file (at the cost of slower startup, since it must extract to a temp directory). The --windowed flag suppresses the console window for GUI applications.

How PyInstaller Works

PyInstaller does not compile your Python code. Instead, it:

  1. Bundles the Python interpreter (python3x.dll) into the executable
  2. Bundles all imported Python modules as .pyc bytecode files
  3. Bundles all dependency DLLs and data files
  4. Creates a bootloader that unpacks everything and runs your script with the bundled interpreter

This means your code still runs as interpreted Python — it is just self-contained. The .exe is essentially a ZIP archive with a custom extractor.

The Antivirus Problem

Critical issue: PyInstaller-generated executables are routinely flagged by antivirus software as malware. This is not a bug in your code — it is a fundamental problem with PyInstaller's approach.

Here is why this happens. PyInstaller's bootloader uses techniques that are also common in actual malware:

In practice, a freshly built PyInstaller executable will trigger false positives on 5-15 out of 70+ AV engines on VirusTotal. This is devastating for commercial software distribution. Users see a malware warning and immediately delete your application.

PyInstaller Verdict

Use for: Internal tools, personal scripts, prototyping. Situations where you control the deployment environment and can whitelist the executable.

Do not use for: Commercial distribution, anything users download from the internet, applications where trust matters.

Method 2: Nuitka (Recommended)

Nuitka takes a fundamentally different approach: it compiles your Python code to C, then compiles the C code to a native executable using a standard C compiler (MSVC on Windows, GCC on Linux). The result is genuine machine code, not a bundled interpreter running bytecode.

pip install nuitka
python -m nuitka --standalone --onefile --windows-console-mode=disable my_app.py

How Nuitka Works

  1. Python to C translation — Nuitka analyzes your Python source code and generates equivalent C source code. Each Python function becomes a C function. Python objects become C structs with reference counting.
  2. C compilation — The generated C code is compiled by MSVC (Microsoft Visual C++) or another C compiler into native machine code. This is real compilation — the output is an executable with native CPU instructions, not bytecode.
  3. Runtime linking — The compiled code links against the CPython runtime (libpython) for operations that require the interpreter (dynamic typing, garbage collection). This is a significantly smaller footprint than bundling the entire interpreter.
  4. Dependency bundling — For --standalone mode, Nuitka bundles necessary DLLs and packages alongside the executable.

Why Nuitka Avoids AV False Positives

Because the output is a standard compiled C program, it looks like any other native application to antivirus software. There is no self-extracting archive, no bootloader, no dynamic bytecode loading. The executable's structure is identical to software written in C or C++ from scratch. AV engines have no reason to flag it.

In our testing across four commercial products (BeatSync PRO, Clareon, NEXUS AI, Prometheus Shield), Nuitka-compiled executables consistently achieve zero false positives on VirusTotal. This is the single most important advantage of Nuitka for commercial software distribution.

Performance Benefits

Nuitka-compiled code is typically 10-30% faster than interpreted Python for CPU-bound operations. The C compiler applies standard optimizations (loop unrolling, function inlining, register allocation) that the Python interpreter cannot. For I/O-bound code, the improvement is minimal since the bottleneck is not CPU execution.

Nuitka Setup on Windows

Nuitka requires a C compiler. On Windows, you need either:

# Install Nuitka
pip install nuitka

# Verify C compiler is available
python -m nuitka --version

# Build standalone executable
python -m nuitka --standalone --onefile ^
  --windows-icon-from-ico=icon.ico ^
  --windows-console-mode=disable ^
  --include-data-dir=assets=assets ^
  --output-dir=build ^
  my_app.py

Key flags explained:

Nuitka Build Times

Nuitka builds are slower than PyInstaller because actual C compilation happens. Typical times on a modern system:

Build time is a one-time cost per release. The AV-clean output is worth the wait.

Method 3: cx_Freeze

cx_Freeze is similar to PyInstaller in approach (bundled interpreter) but with a different configuration model based on setup.py. It is slightly less prone to AV false positives than PyInstaller but still uses the same fundamental pattern.

# setup.py
from cx_Freeze import setup, Executable

setup(
    name="MyApp",
    version="1.0",
    executables=[Executable("my_app.py", base="Win32GUI")]
)
pip install cx_Freeze
python setup.py build

cx_Freeze is a viable option for internal distribution where AV is not a concern, but it shares the same fundamental limitations as PyInstaller for commercial use.

Method 4: The Native Launcher Architecture

After experiencing AV quarantine issues across four commercial products, we developed a hybrid approach that combines Nuitka compilation with a native C launcher. This is the architecture used in BeatSync PRO, Clareon, NEXUS AI, and Prometheus Shield.

The Architecture

  1. Native C launcher (100-180KB) — A minimal C program compiled with MSVC. This is the file users double-click. It has the product icon embedded via rc.exe (Windows Resource Compiler). The launcher does one thing: spawn the actual application executable in the _internal/ subdirectory.
  2. Nuitka-compiled application — The real application, compiled with Nuitka, lives in the _internal/ directory alongside its dependencies.

Why this works:

Building the Native Launcher

Here is a simplified version of the launcher template:

// launcher.c
#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow) {
    char path[MAX_PATH];
    char dir[MAX_PATH];

    // Get directory of this launcher
    GetModuleFileNameA(NULL, path, MAX_PATH);
    char *lastSlash = strrchr(path, '\\');
    if (lastSlash) {
        size_t dirLen = lastSlash - path;
        strncpy(dir, path, dirLen);
        dir[dirLen] = '\0';
    }

    // Build path to actual executable
    char exePath[MAX_PATH];
    snprintf(exePath, MAX_PATH, "%s\\_internal\\MyApp.exe", dir);

    // Launch it
    STARTUPINFOA si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    if (CreateProcessA(exePath, NULL, NULL, NULL,
                       FALSE, 0, NULL, dir, &si, &pi)) {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }
    return 0;
}

Compile with MSVC:

rc /fo launcher.res launcher.rc
cl /O2 launcher.c launcher.res /link /OUT:MyApp.exe
    /SUBSYSTEM:WINDOWS user32.lib kernel32.lib

The .rc file embeds the icon and version information:

// launcher.rc
1 ICON "app_icon.ico"
1 VERSIONINFO
FILEVERSION 1,0,0,0
BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904B0"
    BEGIN
      VALUE "FileDescription", "MyApp"
      VALUE "ProductName", "MyApp"
      VALUE "CompanyName", "My Company"
      VALUE "FileVersion", "1.0.0"
    END
  END
END

Method 5: Prometheus Shield (Automated Pipeline)

Prometheus Shield automates the entire build pipeline described above. Instead of manually configuring Nuitka, writing C launchers, compiling with MSVC, and running QA checks, you feed your Python project into Prometheus Shield and it handles the 12-step pipeline automatically:

  1. Source analysis — 30 QA agents scan your code for issues that will cause problems during compilation
  2. Dependency resolution — Automatically identifies all imports, including hidden imports that Nuitka might miss
  3. Asset collection — Gathers data files, images, models, configs
  4. Nuitka compilation — Compiles Python to C to native code with optimized flags
  5. Native launcher generation — Creates the C launcher with embedded icon and version info
  6. MSVC compilation — Compiles the launcher
  7. Directory structure — Assembles the final distribution folder
  8. Legal document generation — Creates EULA, license, and README files
  9. QA scanning — Agents verify the build for PyInstaller markers, missing DLLs, broken imports
  10. AV pre-check — Verifies the output would not trigger common AV heuristics
  11. Size optimization — Strips unnecessary files from the distribution
  12. ZIP packaging — Creates the final distributable archive

This pipeline was developed out of necessity after manually building four commercial products and encountering every possible failure mode. The QA agents alone have saved hundreds of hours by catching issues (missing DLLs, incorrect icon formats, PyInstaller artifact leftovers) before they reach end users.

Pro tip: If you are distributing commercial Python software, the AV problem is not optional to solve. A single false positive can destroy user trust and tank your product reviews. The native launcher + Nuitka approach is the most reliable solution in 2026.

Common Pitfalls and Solutions

Hidden Imports

Both PyInstaller and Nuitka can miss dynamic imports that are not visible through static analysis:

# This import is visible to static analysis
import json

# This import is NOT visible to static analysis
module = __import__(f"plugins.{plugin_name}")

# Neither is this
importlib.import_module(f"handlers.{handler_type}")

Solution: explicitly declare hidden imports in your build configuration:

# Nuitka
python -m nuitka --include-module=plugins.audio ^
  --include-module=plugins.video ^
  --include-package=handlers ^
  my_app.py

Data Files and Assets

Images, model files, configuration files, and other non-Python assets need to be explicitly included:

# Nuitka
python -m nuitka --include-data-dir=models=models ^
  --include-data-files=config.json=config.json ^
  my_app.py

In your code, reference data files relative to the executable, not the script:

import sys
import os

if getattr(sys, 'frozen', False):
    # Running as compiled executable
    base_dir = os.path.dirname(sys.executable)
else:
    # Running as script
    base_dir = os.path.dirname(os.path.abspath(__file__))

config_path = os.path.join(base_dir, 'config.json')

Large Dependencies

Packages like PyTorch, TensorFlow, or NumPy can bloat your executable to gigabytes. Strategies to manage this:

Choosing the Right Method

Decision tree:

  1. Is this for commercial distribution? → Use Nuitka (or Prometheus Shield for full automation). The AV problem rules out PyInstaller.
  2. Is this an internal tool? → PyInstaller is fine. Fast to set up, well-documented, handles most cases.
  3. Do you need maximum source code protection? → Nuitka (compiled C is much harder to reverse-engineer than .pyc bytecode). See our guide on protecting Python source code.
  4. Do you need maximum performance? → Nuitka. The C compilation provides 10-30% speedup on CPU-bound code.
  5. Do you have a complex build with multiple products?Prometheus Shield automates the entire pipeline with 30 QA agents.

The Python-to-EXE problem is solved in 2026. The right tools exist. The key is choosing the approach that matches your distribution requirements, not just the one that is fastest to set up.

Automate Your Build Pipeline

Prometheus Shield automates the entire Python-to-EXE pipeline: Nuitka compilation, native C launcher, 30 QA agents, AV-clean output.

Get Prometheus Shield