Looking for a Cython Alternative? Try Py2Native
Cython is powerful. It compiles Python-like code to C, speeds up hot loops when you add type annotations, and gives you a path to call C libraries directly. But if your goal is simply to ship proprietary Python without handing over readable source code, Cython often feels like a second job: you learn .pyx and .pxd files, add cdef and cpdef declarations, run manual cythonize steps, configure compilers, and maintain a build system that can break on the next platform.
So the practical question is: is there a simpler way to compile Python to native machine code for source protection?
Py2Native is built for exactly that decision. It uses Cython under the hood but hides it completely. You write plain Python, run one uv run py2native build command, and get a native binary or shared library. This article compares Cython and Py2Native across ease of use, automation, security, price, and integration.
The Landscape: Options for Compiling Python to Native Code
The Python compiler space has a few serious options, each with a different trade-off.
Cython is the most established. It works, it is mature, and it is used in production by major projects. The cost is complexity: Cython is a superset of Python, so you maintain Cython-specific files, declare types for performance, and typically wire up your own build pipeline.
Nuitka compiles Python directly and can produce native executables, but builds can be slow and optimal results often require configuration and tuning.
mypyc compiles type-annotated Python into C extensions, but it is focused on speed for already-typed codebases, not on protecting arbitrary proprietary Python.
Py2Native is purpose-built for source protection. It automates Cython invocation, C compilation, linking, wheel creation, and uv-managed embedding. You do not write .pyx files, run cythonize, or manage a C toolchain manually. Third-party libraries remain untouched and work as-is.
Selection Criteria: What Matters When Choosing a Compiler
When you are evaluating a Python-to-native compiler for a commercial product, five criteria matter most.
- Ease of use: Can you keep writing plain Python, or do you have to learn a new syntax and file formats?
- Automation: Does the tool handle compilation, linking, and packaging automatically, or do you maintain build scripts?
- Security: Does the result actually hide your proprietary logic in native machine code?
- Price and licensing: What is open source, what is commercial, and what licensing features do you get?
- Integration: How well does it work with existing Python projects, third-party dependencies, and deployment workflows?
Side-by-Side Comparison: Cython vs. Py2Native
| Criterion | Cython | Py2Native |
|---|---|---|
| Input language | Cython superset: .pyx, .pxd, cdef, cpdef, typed declarations |
Plain Python files |
| Build workflow | Manual cythonize plus compiler/linker configuration |
One command: uv run py2native build main.py *.py |
| C compilation and linking | Manual or setuptools-heavy setup | Automatic, including platform-specific flags |
| Third-party libraries | Often require declarations, stubs, or special handling | Left unmodified; they remain Python source and work as-is |
| Output modes | Extension modules, embedded executables | Executable, shared library (--library), wheel (--wheel), uv embed (--embed) |
| Source protection | Compiled C from Python-like code | Native machine code from plain Python |
| Automation | You assemble the pipeline | build.py globs sources and calls the compiler/linker/wheel/embed paths for you |
| Licensing | Open source | Core is MIT and free; Pro plugin adds license verification |
A typical Py2Native build is short:
uv run py2native build main.py *.py --wheel dist --embed deploy/app
That command expands the globs, runs Cython automatically, invokes the platform C compiler, links the result, creates a wheel, and prepares a uv-managed deployment directory. For a shared library instead of an executable, add --library:
uv run py2native build main.py *.py --library --wheel dist
The library mode produces a compiled .pyd, .so, or .dylib and generates the required __init__.py and __main__.py files so Python imports and python -m mypkg work against the native library.
Verdict: Who Should Choose Which?
Choose Cython if you need fine-grained control over performance, are writing scientific or C-interop extensions, and are willing to invest in Cython-specific syntax and build tooling. Cython is still a great tool for that job.
Choose Py2Native if your primary goal is shipping commercial Python software without exposing source code. It gives you native binaries, shared libraries, wheels, and embedded deployments with minimal configuration. You keep your existing Python codebase; the compiler does the difficult part.
Py2Native fits teams that:
- Do not want to maintain
.pyxor.pxdfiles across the codebase. - Need a repeatable build that runs from plain Python sources.
- Ship desktop or server applications where source protection matters.
- Want third-party dependencies to continue working without custom build configuration.
If you need license enforcement, Py2Native Pro adds JWT-based verification directly into the compiled binary. You generate keys, sign license data, and verify it from your Python entry point. The full automation story is covered in Automate Python Compilation with Py2Native, and the licensing workflow is detailed in Secure JWT License Verification with Py2Native Pro.
FAQ
Is Py2Native a drop-in replacement for Cython?
Yes, for the purpose of compiling Python to native code for source protection. Py2Native uses Cython under the hood but automates the entire process, so you do not need to write .pyx files or run cythonize manually. You run:
uv run py2native build main.py
and get a native binary.
Can Py2Native compile all Python code?
Py2Native compiles your custom Python code into native machine code. Third-party libraries are left unmodified and work as-is, which means they remain as Python source. This is intentional: it preserves compatibility and complies with licenses such as LGPL. Your proprietary code is protected, while dependencies remain replaceable by the end user.
Does Py2Native require learning a new syntax?
No. Py2Native accepts plain Python files. There is no need to learn Cython-specific syntax, type annotations, or build configuration. The compiler handles translation to C, compilation, and linking automatically.
How does Py2Native handle license verification?
Py2Native Pro includes a plugin that adds JWT license verification. Generate a keypair and sign a license with:
uv run py2native keygen private.pem public.pem
uv run py2native sign --private private.pem '{"iss":"RSJ Software GmbH","aud":"TimestampGIT"}' license.dat
uv run py2native show --public public.pem license.dat
When you build with --license license.dat --public public.pem, the Pro plugin bakes the verification logic and public key into the executable. Only the public key is stored in the binary.
To call verification from your code, Py2Native Pro uses a small .pxd declaration that the compiler reads during the build:
# py2nativepro_runtime.pxd
from _p2n_bootstrap cimport _runtime_verify_es256_jwt
cdef _runtime_verify_es256_jwt(token, expected_iss=*, expected_aud=*)
Then your plain Python entry point calls the compiled verifier:
license = _runtime_verify_es256_jwt(
licenseString,
expected_iss="RSJ Software GmbH",
expected_aud="TimestampGIT",
)
if not license:
raise RuntimeError("Invalid license")
The verification call is _runtime_verify_es256_jwt(token, expected_iss="RSJ Software GmbH", expected_aud="TimestampGIT"), and it runs inside the native binary rather than in readable Python source.
Conclusion: Make the Switch to Zero-Config Compilation
Py2Native removes the main reason developers hesitate to protect Python source: build complexity. Cython remains a powerful tool for performance-focused extension work, but when your goal is shipping proprietary code, Py2Native gives you native binaries from plain Python with a single command.
Start with the simplest possible test:
uv run py2native build main.py
Add wheels, embedding, library mode, or Pro license verification only when you need them. The core compiler is MIT licensed, and the optional Pro plugin covers JWT license enforcement for commercial products.
See the official Py2Native documentation for the full command reference and build artifacts.
Related posts
- Python EXE Packaging: A Beginner’s Guide
- Automate Python Compilation with Py2Native
- Secure JWT License Verification with Py2Native Pro