DEV Community

Cover image for I built a Python -> C transpiler. Then it transpiled itself.
Johnny
Johnny

Posted on

I built a Python -> C transpiler. Then it transpiled itself.

A few weeks ago I needed to run Python scripts in initramfs — the tiny Linux environment that exists before your actual OS boots. No interpreter. No dynamic linker. Nothing.

So I built Transpilatron: an AI agent that takes Python code and produces a fully static C binary.

uvx transpilatron your_code.py
Enter fullscreen mode Exit fullscreen mode

That's it. No C knowledge required.

The benchmarks

First, does it actually work? I ran two tests:

Benchmark Python C Speedup
Sieve of Eratosthenes (10M numbers) 0.526s 0.022s 24x
Selection sort (10K elements) 1.963s 0.033s 58x

Same output. Verified on the same machine. The C binary is fully static — no runtime, no interpreter, no dependencies.

The Flask demo

Then I tried something more interesting. A 14-line Flask app:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello from the webserver!'

@app.route('/ping')
def ping():
    return 'pong'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
Enter fullscreen mode Exit fullscreen mode

One command:

uvx transpilatron web.py
Enter fullscreen mode Exit fullscreen mode

Output: a native C HTTP server. No Flask. No Python runtime.

$ curl http://localhost:8080/
Hello from the webserver!

$ curl http://localhost:8080/ping
pong
Enter fullscreen mode Exit fullscreen mode

Verified memory-safe by valgrind: 0 errors, 0 leaks.

Then it transpiled itself

Here's where it gets weird.

Transpilatron is written in Python. So I pointed it at its own source code:

uvx transpilatron src/transpilatron/agent.py
Enter fullscreen mode Exit fullscreen mode

The agent read its own Python source, wrote 400+ lines of C, fixed its own compiler errors autonomously, ran a memory audit, and produced a working binary.

$ ./out/agent --help
Usage: ./agent [--minimal|--full] <entry_file>
  --minimal  Use minimal mode: static linking, raw sockets only
  --full     Use full mode (default): dynamic linking, libcurl, etc.

$ ./out/agent examples/web.py
Thinking...
I'll help you convert the Python project to C...
Enter fullscreen mode Exit fullscreen mode

A C binary, orchestrating an AI agent, transpiling Python to C.

Valgrind result: 0 errors, 0 leaks.

How it works

Transpilatron wraps the Poolside CLI (free) as its agentic backend. The agent:

  1. Reads your Python entry file and follows all imports
  2. Transpiles the full project to C
  3. Writes a Makefile and compiles with -O3
  4. Auto-installs missing build tools via your system package manager
  5. Runs the binary under valgrind to verify zero memory leaks
  6. Audits the C for race conditions, NULL dereferences, and logic bugs
  7. Retries up to 3 times if compilation fails

Two modes

Mode Linking HTTP Best for
--minimal Static only Raw BSD sockets initramfs, scratch containers, embedded
--full Dynamic permitted libcurl Web apps, ML inference, general use

--full mode supports Flask/FastAPI → libmicrohttpd, torch/tensorflow → libtorch/TFLite, OpenCV, and more.

Why not Nuitka?

Nuitka bundles CPython. PyInstaller bundles CPython. Both produce 30MB+ binaries that require a Python runtime.

Transpilatron strips CPython entirely. The output binary has no idea Python exists.

That's the only approach that works for initramfs, scratch containers, or embedded targets with no OS.

Try it

uvx transpilatron your_code.py
Enter fullscreen mode Exit fullscreen mode

Requires only uv. Everything else (Poolside CLI, gcc, make, valgrind) is auto-installed on first run.

GitHub: NoodlixProject/transpilatron


Transpilatron was originally built to compile boot scripts for Noodlix — a Python-only OS I'm building. That project is ongoing.

Top comments (0)