# Crinkler: a compressing linker for tiny Windows executables

> Crinkler is a compressing linker for Windows, aimed at executables of a few kilobytes and used in the demoscene for size coded productions. The README is short, but two details matter for anyone building on it: the version identifier it writes into the output executable, and the decision to split the data compressor into a separate library so other tools can estimate a compressed size before they build.

**runestubbe/Crinkler** — Crinkler is an executable file compressor (or rather, a compressing linker) for compressing small 32-bit Windows demoscene executables. As of 2026, it is the most widely used tool for compressing 1k/4k/8k intros.

- Repository: https://github.com/runestubbe/Crinkler
- Website: http://crinkler.net/
- Stars: 1,304 · Forks: 63
- Language: C++
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/runestubbe-crinkler

## A linker that compresses, rather than a compressor that packs

The repository description is careful about what Crinkler is, and the correction it makes is the interesting part. Crinkler is an executable file compressor, or rather, a compressing linker, for compressing small 32-bit Windows demoscene executables. The README itself puts it more plainly: Crinkler is a compressing linker for Windows, specifically targeted towards executables with a size of just a few kilobytes, and its main purpose is as a tool for producing small demoscene productions.

The difference between a compressor and a compressing linker is not cosmetic. A conventional executable packer takes a finished program, compresses its sections and unpacks them at run time, which means the output carries a decompressor stub and the original image. A compressing linker goes back further: it is part of the link step, so the compressed representation is the form the program is produced in, and the decompressor is part of the linked image rather than something wrapped around it.

That is why the tool is aimed at a specific size range. Below a few kilobytes, the overhead of a wrapper is a large fraction of the result, and the difference between a packed executable and a properly compressed one is the difference between fitting in a size category and not fitting. The description says that as of 2026 it is the most widely used tool for compressing 1k, 4k and 8k intros, which is the demoscene's way of saying that the categories are defined by the final byte count.

For anyone coming from the Unix side of things, the closest relatives are the ELF and static link tricks used for size coding, and the same reasoning applies: below a few kilobytes, every byte in the stub and every byte in the format is a byte you do not have.

## Two maintainers, a permissive licence and a forum instead of an issue tracker

The distribution section is short and gives you the whole picture of the project.

Crinkler is mainly being developed by Rune L. H. Stubbe, who goes by Mentor and TBC, and Aske Simon Christensen, who goes by Blueberry and Loonies, and it is distributed under the Zlib licence. That is a permissive licence, and for a tool that other people are invited to integrate into their own toolchains, it is the right choice.

The other thing the section says is that you are welcome to integrate Crinkler into your own tools or toolchains, and then it gives a piece of advice that is more specific than it first appears. If you do so, preferably base your work on the master branch, because the Crinkler version identifier written into output executables, two digits at offset 2 in the file, will match the actual contents produced by Crinkler.

That is a small engineering detail with a large consequence, and it explains the next sentence. All feature development that significantly affects the output from Crinkler will generally take place on other branches.

So the project has a stable integration line and a set of development branches, and the stable line is the one whose output is self describing. The two digits at a fixed offset in the file are a version stamp written into the artefact itself, and keeping them honest means the branch you build from has to be the branch that matches the tool that produced the bytes.

For discussion, the README points to the Pouët.net forum, and the manual in doc/manual.txt is where the usage information and the version history live.

## The Compressor library, and estimating a size before you build

The build section contains the one piece of architecture that other projects would benefit from copying.

The data compressor itself is separated out into its own library, located in the Compressor project. The README explains why: this library enables tools to estimate how big a particular piece of data would be after being compressed by Crinkler, and it points at the CompressorExample project for a description of its usage.

That is a genuinely useful separation, and it solves a problem that is specific to size coding. In an ordinary project, you build the thing and find out how big it is. In a size coded competition, the size is a constraint you are designing against, often against a hard limit that is a multiple of a kilobyte, and a build that overshoots it means restructuring the program rather than adjusting a flag. If the compressor is a library, then a tool can answer the question how big will this be without running the whole link.

It also makes the compressor reusable in a way a monolithic linker is not. A tool that needs to reason about the compressed size of a specific asset, or that wants to compare compression strategies, can use the library without adopting the linker.

The repository structure supports the same picture. There is source/ for the main code, external/ for third party material, test/ for the test suite, doc/ for the manual, releases/ for the packaged builds, web/ for the project pages, a crossbuild/ directory, and the solution file Crinkler.sln at the root, which is how a Visual Studio project of this shape is laid out.

## Building it needs Visual Studio 2022 and nasm on the path

The build requirement is two sentences long and the second one is the trap.

Build Crinkler using Visual Studio 2022 or later. The custom build rules for the assembly files require that nasm.exe is in the executable path.

So the toolchain is a modern Visual Studio plus a Netwide assembler, and the assembler has to be discoverable by the build rather than merely installed. That second condition is what usually stops people, because a build that cannot find nasm.exe fails in a way that does not obviously point at the missing dependency, and the fix is to put the directory containing it on the PATH for the build.

The use of assembly is not surprising for the domain. A tool whose job is to make a few kilobyte executable smaller cannot afford a large runtime, and the low level parts of a compressing linker are exactly the parts where a hand written routine saves bytes that a compiler will not.

The development cadence visible in the releases is worth noting too. Version 3.0 landed on 2026-02-27, 3.0a on 2026-05-09 and 3.0b on 2026-07-30, and the last push to the repository was on 2026-08-05. The a and b suffixes on the 3.0 line suggest a staged approach to a major version, and the README's own instruction that significant output-affecting development happens on other branches is consistent with that, since the master branch is the one integrators are told to build from.

## Conclusion

Crinkler fits a demoscene author or a size coding competitor who needs the smallest possible 32-bit Windows executable and wants the whole pipeline, not just a post processing step. It does not fit a general purpose build, because it targets a narrow output shape, and it does not fit a team that wants a modern toolchain, since the build needs Visual Studio 2022 and nasm on the path. Verify three things before you build with it: that the assembler is reachable, because the custom build rules for the assembly files require nasm.exe in the executable path, that you base your integration on the master branch so the version identifier in your output matches the tool that produced it, and that you read the manual, since the README points there for usage information and version history and contains almost nothing else about the interface itself.

## FAQ

### What is Crinkler and what is it for?

It is a compressing linker for Windows, specifically targeted towards executables with a size of just a few kilobytes, whose main purpose is producing small demoscene productions. The repository description calls it an executable file compressor, or rather a compressing linker, and says that as of 2026 it is the most widely used tool for compressing 1k, 4k and 8k intros.

### Who develops Crinkler and under what licence?

It is mainly being developed by Rune L. H. Stubbe, known as Mentor and TBC, and Aske Simon Christensen, known as Blueberry and Loonies, and it is distributed under the Zlib licence. The project invites you to integrate Crinkler into your own tools or toolchains.

### Why should I base my integration on the master branch?

So that the Crinkler version identifier written into the output executables, two digits at offset 2 in the file, matches the actual contents produced by Crinkler. All feature development that significantly affects the output takes place on other branches, which is why master is the integration line.

### What is the Compressor library in the Crinkler project?

The data compressor is separated out into its own library in the Compressor project, and it exists so that tools can estimate how big a particular piece of data would be after being compressed by Crinkler. The CompressorExample project describes its usage.

### What do I need to build Crinkler?

Visual Studio 2022 or later, and nasm.exe has to be in the executable path, because the custom build rules for the assembly files require it. The usage information and version history are in the manual at doc/manual.txt, and general discussion happens on the Pouët.net forum.

## Sources

- [Issues](https://github.com/runestubbe/Crinkler/issues)
- [Project website](http://crinkler.net/)
- [README](https://github.com/runestubbe/Crinkler/blob/master/README.md)
- [Releases](https://github.com/runestubbe/Crinkler/releases)
- [runestubbe/Crinkler on GitHub](https://github.com/runestubbe/Crinkler)

---

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