# Serc: CPython bytecode compiler written in Rust (Codex built, 2-4x speedup)

> Source: <https://github.com/astral-experiments/serc>
> Published: 2026-11-10 02:53:14+00:00

An experimental CPython bytecode compiler, written in Rust.

Serc produces byte-for-byte identical output (as compared to CPython) on an
extensive corpus of real-world Python code, including
[Django](https://github.com/django/django),
[Airflow](https://github.com/apache/airflow), and
[Transformers](https://github.com/huggingface/transformers), across CPython
3.12, 3.13, 3.14, and 3.15, and optimization levels 0, 1, and 2, all while
compiling [3-4x faster](https://github.com/astral-experiments/serc/blob/main/BENCHMARKS.md#project-compilation) than CPython’s
`compileall`.

But Serc is also experimental! And so may emit incorrect bytecode in some cases.

Warning

Serc is experimental. This README is human-edited, but all code changes, PR summaries, and additional documentation were authored entirely by GPT in Codex.

Install from [crates.io](https://crates.io/crates/serc-cli) with Rust 1.96 or
later:

```
cargo install serc-cli --locked
```

Given `hello.py`:

``` python
def greet(name):
    return f"Hello, {name}!"
```

Compile to bytecode, emitted at `__pycache__/hello.cpython-314.pyc`:

```
serc compile hello.py
```

Pass a directory to compile its Python files recursively, or use `--check` to
compile without writing cache files:

```
serc compile path/to/package
serc compile --check path/to/package
```

Compilation uses the available CPUs by default. Use `--jobs` (or `-j`) on the
command line or the `RAYON_NUM_THREADS` environment variable to set a limit,
including `--jobs 1` for serial compilation.

```
serc compile --jobs 4 path/to/package
```

By default, Serc skips files whose `.pyc` is up to date by checking the bytecode
format and invalidation mode, then comparing the source file's timestamp and
size (for timestamp-based caches) or its content hash (for hash-based caches).

Pass `--force` (or `-f`) to recompile every file, for example after switching
compilers or native build profiles. (Even with `--force`, Serc refuses to
overwrite symlinks or special files.)

Serc emits Python 3.14-compatible bytecode by default, but supports target
selection with `--python-version`. For example, to emit Python 3.15 bytecode:

```
serc compile --python-version 3.15 path/to/package
```

Serc supports the following CPython minor versions:

| Target | Pinned CPython release | 
|---|---|
| `3.12` | 3.12.14 | 
| `3.13` | 3.13.15 | 
| `3.14` | 3.14.5 | 
| `3.15` | 3.15.0rc2 | 

Each target writes its own cache tag and bytecode magic number, so the four
versions can coexist under `__pycache__`.

Use `-O` to remove assertions and set `__debug__` to false, matching Python's
`-O` mode. Use `-OO` to additionally remove module, class, and function
docstrings:

```
serc compile -O hello.py
serc compile -OO hello.py
```

You can also select the level explicitly with `--optimize 0`, `--optimize 1`, or
`--optimize 2`. Level 0 is the default. Optimized caches use Python's naming
convention, such as `__pycache__/hello.cpython-314.opt-1.pyc` and
`__pycache__/hello.cpython-314.opt-2.pyc`, so all three levels can coexist.

Add Serc to your `Cargo.toml`:

```
[dependencies]
serc = "0.1.0"
```

Compile Python source and serialize the resulting code object in CPython's marshal format:

``` js
let module = serc::compile("print('Hello, world!')\n", "hello.py").unwrap();
let marshaled = module.marshal();
```

Serc is licensed under either of

- Apache License, Version 2.0, ([LICENSE-APACHE](https://github.com/astral-experiments/serc/blob/main/LICENSE-APACHE) or[https://www.apache.org/licenses/LICENSE-2.0](https://www.apache.org/licenses/LICENSE-2.0) )
- MIT license ([LICENSE-MIT](https://github.com/astral-experiments/serc/blob/main/LICENSE-MIT) or[https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT) )

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Serc by you, as defined in the Apache-2.0 license, shall be dually licensed as above, without any additional terms or conditions.
