Back to projects

ferryx

Rust → Python FFI codegen compiler

Write Rust. Get native Python bindings. No glue code.

View on GitHub

Demo

terminal
$ ferryx build src/lib.rs
> parsing Rust types...
> generating FFI layer...
> emitting Python stubs...
> compiling native extension...
mylib.so + mylib.pyi generated

Problem

Writing Rust extensions for Python means maintaining two separate codebases of glue: the C FFI layer and the Python wrapper. Every type change requires updates in three places.

What it does

Ferryx reads Rust source, reflects the public type surface, and emits:

  • a C FFI layer
  • Python extension module (.so / .pyd)
  • type-annotated .pyi stubs for IDE support
  • optional TypeScript bindings via WASM

Change the Rust signature; run ferryx; bindings update automatically.

Features

Zero Handwriting

Bindings generated from Rust types — no manual FFI code.

Python Stubs

Type-annotated .pyi files emitted for full IDE completion.

Native Speed

Rust performance, Python ergonomics — no marshalling overhead.

TypeScript SDK

Bindings can also target TypeScript via WASM or Node addons.

Compilation pipeline

Rust Source
Type Reflection
FFI Codegen
Python / TS Stubs
Native Extension

Generated binding

Rust input

pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

Generated Python stub

def add(a: int, b: int) -> int: ...

Build

ferryx build src/lib.rs --target python

Why I Built This

I kept rewriting PyO3 wrappers every time the Rust API changed. The binding layer was always behind the implementation.

Ferryx makes bindings a compiler output, not a maintenance burden.

Repository

View on GitHub

Links