Introducing tmux-rs: The First Rust-Based Version of the Popular Terminal Multiplexer tmux

Developer Colin Richards has unveiled an open-source project called tmux-rs. This is the first alpha version of the terminal multiplexer tmux, reimplemented using the Rust programming language.

The port’s description highlights that the project is currently in alpha testing and contains numerous known bugs. tmux-rs is primarily developed with unsafe Rust. The author advises against using this work unless users are prepared to deal with frequent crashes.

«Approximately six months ago, I quietly began porting tmux from C to Rust. Recently, I reached a significant milestone: the codebase is now 100% (unsafe) Rust. I wanted to share the experience of converting the original codebase, which consisted of around 67,000 lines of C code, into roughly 81,000 lines of Rust (excluding comments and blank lines). You may wonder why I chose to rewrite tmux in Rust. Well, I don’t have a compelling reason—it’s just a hobby project. Think of it like gardening but with a lot of segmentation faults,” Richards remarked in a detailed blog post about the project.

Throughout the development process, Richards did not use AI. He attempted to utilize Cursor but eventually found he spent just as much time reviewing the generated code as he would have rewriting it himself. After that experience, he opted to forego AI assistance and worked manually.

Initially, Richards tried to make the port with C2Rust, a tool designed to transpile C to Rust. However, he found this tool challenging to set up, and while the generated code functioned, it was largely unmaintainable and three times larger than the original C code.

Ultimately, Richards decided to handle the porting entirely on his own, developing a clear understanding of how the project should be structured. For tmux, this meant using autotools. He figured out where to add or remove files in autogen.sh and how to modify the generated Makefile to link with the static library created by Rust Crate using the crate-type = «staticlib» option. This indicated that the process of building the port was not as simple as just running Cargo build. Richards created a build.sh script that would call Cargo and then execute Make. This worked for a while, but every time he finished translating a file, he had to reconfigure and adjust the Makefile. In the end, he found it easier to consolidate everything into a single crate.

During the porting process, Richards made many mistakes in translating the code. He aimed to identify and rectify them on the fly, yet some still remain in the project.

As he worked on this project, Richards employed a variety of text editors and IDEs. He primarily used Neovim and custom macros to streamline the translation process. For instance, he created vim macros for conversions like «ptr == NULL» to «ptr.is_null()» and «ptr->field» to «(*ptr).field». While most of these adjustments were relatively simple to implement, applying them all at once through search and replace proved challenging. He ended up making such changes manually thousands of times.

“Although the code is now 100% converted, I’m not sure I achieved my primary goal. My manually ported code is not substantially better than the output from C2Rust. The project can still crash quite easily, and I am aware of many bugs. The next objective is to transform the codebase into safe Rust. Despite all of this, I am releasing version 0.0.1 to share it with other Rust and tmux enthusiasts,” Richards concluded.