# Shed Skin: a restricted Python to C++ transpiler

> Shed Skin translates pure, implicitly statically typed Python 3 into optimised C++, with no type annotations to write and no interpreter left in the loop, at the cost of a restricted language subset and a refactor of your code. It suits a numerical program of a few hundred lines that has to run faster than CPython will, and it is not a general purpose port of Python.

**shedskin/shedskin** — Shed Skin is a restricted-Python-to-C++ transpiler. Read the introduction below to learn about the restrictions.

- Repository: https://github.com/shedskin/shedskin
- Website: https://shedskin.github.io/
- Stars: 1,019 · Forks: 116
- Language: C++
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/shedskin-shedskin

## What the tool does

Shed Skin is a transpiler that can translate pure, but implicitly statically typed Python 3 programs into optimized C++. It can generate stand-alone programs or extension modules that can be imported and used in larger Python programs.

The word implicitly is the key to the design. Most static Python tools ask you to write type annotations, and Cython is named in the README as the example of a tool you would use if you did not want to avoid that. Shed Skin infers the types itself, from a Python program that looks like ordinary Python, and then emits C++ that is compiled by a normal toolchain into a binary.

The two output modes matter for how you would adopt it. A stand-alone program is a self contained binary with no Python interpreter involved at run time, which is the maximum performance case. An extension module is a compiled module that a larger Python program can import, which lets you keep the slow parts in Python and accelerate one part.

The implementation is C++, the project is licensed under GPL-3.0-only, and the current version is 0.9.14 with a release in September 2026, following 0.9.13 in August and 0.9.12 in April. The last push to the repository was on 2026-10-15, so the work is current.

## The restrictions, and what they cost

The README is direct about the limits, and it is better to know them before writing any code.

Besides the typing restriction, programs cannot freely use the Python standard library, although about 25 common modules, such as random and re, are currently supported, and they cannot use any other external library at all. And not all Python features are supported, with nested functions and variable numbers of arguments given as examples.

The consequence is stated in the Restrictions section without softening. Shed Skin only supports a restricted subset of Python, so one should not expect a given program to compile without any changes, if possible at all. You may have to work a lot, or even start from scratch, to make your code compatible.

That is the central trade of the project, and it is a different trade from the one a static compiler asks for. A type annotating tool leaves your code intact and asks you to add hints, which is tedious but local. A transpiler that infers types has to constrain the language so that the inference is sound, and the constraint is the language subset. So the work is not annotation, it is restructuring, and the README's list of when to use the tool says it plainly in the last bullet, that you don't mind refactoring your code, potentially a lot, to make it compatible.

The supported module list is the practical limit. About 25 modules covers a good deal of numerical and text work, and the modules that are missing are the ones that pull in a C library you would then have to build yourself, which is the real reason for the restriction rather than a technical one.

## When to use it, and when to use something else

The README has a list headed Use Shed Skin when, and it is short enough to be worth reproducing in spirit, because the list is the tool's own marketing and it is conservative.

The first condition is scale. You have a few hundred lines of code, up to a few thousand, that you want to run at the highest possible speed. The word a few is doing the work, because the value of a static transpile comes from the compile time and the refactor, and both grow with the size of the program.

The second is independence. The code is, or can be made, independent of external libraries, which is the same restriction as above restated as a decision.

The third is that you do not want to switch to a faster language, for whatever reasons you have, and you do not want to add type annotations, with Cython named as the tool you would otherwise reach for. The fourth is that you would prefer to stick with CPython as your main interpreter, for example no PyPy, which tells you the situation, because the alternative is to change the interpreter rather than to change the language.

The alternatives are therefore visible from the list. Cython if you are willing to annotate. PyPy if you are willing to change the interpreter. A different language if you are willing to change more.

There is also a related project named at the end, TurboPython, which is a similar restricted Python to C++ language and transpiler but adds Rust-like memory management. So the space of restricted Python to C++ tools is not empty, and the differentiator is how the memory model is handled.

## The performance numbers, and how to read them

The comparison section gives one concrete benchmark, the sieve example with a hundred million iterations, and it is worth reading for what it shows rather than for the numbers themselves.

```
cpython 3.10.6:     13.4 seconds
cpython 3.11.0:     11.4
nuitka 0.6.16:      11.4
pypy 3.9.12:        5.8
numba 0.56.4:       2.5
shedskin 0.9.9:     1.9  (--int32)
shedskin 0.9.9:     1.8  (--int32 --nowrap --nobounds)
```

Two things are being controlled for, and both are about integer width. The note says that Numba defaults to int64 as its integer type, or it would be just as fast, and that Shed Skin now also defaults to int64, with the int32 flag selecting the narrower, previously default type. So the two fastest rows for Shed Skin are not the default configuration, and a fair comparison has to hold the integer width constant.

The flags in the fastest row are the other half of it. The nowrap and nobounds flags turn off two safety checks, and the difference between 1.9 and 1.8 seconds is what they cost.

The README also gives the aggregate figure, which is the more useful number for a decision. For a set of over 80 non-trivial programs, at over 25,000 lines in total counted with sloccount, measurements show a typical speedup of 1 to 100 times over CPython 3.14, with an average of 20 times and a median of 12 times.

And the methodology is stated, which is rare and welcome. The measurements were performed for a specific git tag, and PyPy was allowed to stabilize before measuring, so the comparison is not a race between a freshly started PyPy and a warmed up one.

## Building and running, and the garbage collector dependency

Using the tool is a build and a run, and the README shows both platforms.

```bash
shedskin build test
build/test
```

On Windows the same build produces an executable with a backslash path.

The installation section has a dependency that is easy to miss. Shed Skin depends on some other projects, such as the Boehm garbage collector, and the documentation explains how to install these.

That dependency is a consequence of the design rather than an accident. The transpiler produces C++ that uses a garbage collector instead of Python's reference counting, and the Boehm collector is the one that ships with the generated code. So the output is not a self-contained static binary in the naive sense, and a deployment has to account for it.

The repository layout shows the shape of the project. There is the shedskin package itself, an examples directory with a large set of programs, a tests directory, the documentation with a mkdocs configuration, the CMake build for the native side, a tox configuration for the Python side, and a small test.py at the root that is the hello world used in the usage example.

The examples are the best advertisement for the tool, and they are also the test corpus. The list includes a chess program, a gene algorithm, a path finding set, a cellular automaton, a ray tracer, a compression implementation, a snake game, a 3d game engine, a text adventure and a brainfuck interpreter. A project like this is only credible if someone has actually ported a chess engine, and the directory listing says someone has.

## The build system, and the shape of the project

The recent work on the repository has been as much about tooling as about the transpiler, and the Makefile shows a modern Python project.

The environment is managed with uv. There is a sync target that installs the dependencies and the package, and a build target that reinstalls just the package so that a code change does not require a full environment rebuild. The tests run with pytest against the unit test directory, and there is a separate target that translates, compiles and runs the tests through cmake and ctest, which is the one that actually exercises the transpiler end to end. The examples have their own equivalent target, so the eighty example programs are also part of the test suite.

Quality is enforced with ruff for linting and formatting and mypy in strict mode, and a single qa target runs the test, lint, typecheck and format steps together. The ruff invocations exclude the vendored library directory inside the package, which is the standard treatment for generated or bundled code.

Distribution is handled by uv building a wheel and a source distribution, with twine checking them, and separate targets for a TestPyPI upload and a PyPI upload. The package itself declares no runtime dependencies, which is remarkable for a tool that compiles to C++ and needs a garbage collector, and it is accurate: the collector is a native dependency of the generated program rather than something the Python package imports.

The project metadata is minimal and correct for the shape of the thing, with the licence declared as GPL-3.0-only, a Python requirement of 3.9 or later, and a console script named shedskin.

## Conclusion

Adopt Shed Skin if you have a self contained numerical program of a few hundred lines that must run much faster than CPython and you would rather not annotate types or change language, because the transpiler infers the types and the resulting binary is a normal C++ program. Do not adopt it for a project that leans on the standard library or on dynamic Python features, because the supported subset is small and the refactor is called out as potentially large. Before you start, read the restrictions in the documentation, because the language subset and the list of supported modules decide whether your code is a candidate at all.

## FAQ

### What is Shed Skin?

It is a transpiler that translates pure, but implicitly statically typed Python 3 programs into optimized C++, generating either stand-alone programs or extension modules that can be imported into larger Python programs. It infers the types itself, so no type annotations are required.

### What are the main restrictions of Shed Skin?

Programs cannot freely use the Python standard library, although about 25 common modules such as random and re are supported, and no other external library can be used. Not all Python features are supported, with nested functions and variable numbers of arguments given as examples, so a program may need substantial refactoring or a rewrite.

### How much faster is Shed Skin than CPython?

For a set of over 80 non-trivial example programs of more than 25,000 lines in total, the README reports a typical speedup of 1 to 100 times over CPython 3.14, with an average of 20 times and a median of 12 times. The individual sieve benchmark is timed against CPython, PyPy, Numba and Nuitka.

### What does Shed Skin need installed to build?

It depends on other projects, such as the Boehm garbage collector, and the documentation explains how to install them. Using the tool itself is a build and a run, with the build command producing a binary that is then executed directly.

## Sources

- [Issues](https://github.com/shedskin/shedskin/issues)
- [Project website](https://shedskin.github.io/)
- [README](https://github.com/shedskin/shedskin/blob/main/README.md)
- [Releases](https://github.com/shedskin/shedskin/releases)
- [shedskin/shedskin on GitHub](https://github.com/shedskin/shedskin)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/shedskin-shedskin
