BK

I learned something new about myself. I hate Rust.

I hate it more than C++. I did not think that was possible.

By Bhargavaram Krishnapur5 min readSoftware engineering

Painting: Albert Bierstadt, Mount Vesuvius at Midnight, 1868. Cleveland Museum of Art, CC0.

I learned something new about myself this month. I hate Rust.

I do not mean that it is hard, or that it has a learning curve. Everything has a learning curve. I mean that I have now written about 20,000 lines of it, and I hate it more than C++. I have used C++. I have seen a template error scroll off the screen. I still pick C++.

The 20,000 lines are a PDF editor that I am building, called T-Rustable. It runs offline, like most things I build. Yes, the name has the language inside it. I named it while I still liked Rust. That was not very long ago.

The editor, with a test file that its own self-test makes. The text is turned on purpose, to test pages that are rotated.

To write Rust, first install C++

On Windows, Rust has two toolchains. The GNU one is the easy one. It could not build Tauri, the app shell I chose, so I installed Visual Studio Build Tools 2022 and moved to the MSVC toolchain. The Build Tools are, for the most part, a C++ compiler.

That is only the start. The PDF work itself is done by PDFium, the PDF engine from Chromium, and by qpdf, which checks and writes the final file. Both are C++. The qpdf crate compiles qpdf from source, so a clean build of my Rust app first compiles about 200 C and C++ files. In my tests, that step alone took 36 to 61 seconds.

So the language that was going to save me from C++ needs a C++ compiler on every build machine, and it sits on top of a C++ engine. I am not saying it is a scam. I am saying that I noticed.

InterfaceSvelte 5 and TypeScriptApp shellTauri 2, RustCore and mod hostRust, wasmtime runs the modsEngine bindingRust, and most of the 54 unsafe blocksPDFium and qpdfC++, where the PDF work happens
The layers of the editor. The bottom one, the one that touches the PDF, is C++.

The safe language, with unsafe in it

There is a Rust crate for PDFium, pdfium-render. It is a good crate. It also keeps the raw PDFium document and page handles private. I needed those handles for a render that can pause and be cancelled while the document is being edited. I also needed to restart PDFium in the same process after a crash, and the crate can load PDFium only once per process.

So I wrote my own binding. Every PDFium function I use needs a declaration by hand and a safe wrapper around it. The app crates now have 54 unsafe blocks, and almost all of them live in that one module. They have tests. I keep them together, like a responsible adult.

But I came to Rust to stop writing unsafe code, and the first big thing I did was write a whole module of it.

The compiler is right, and it tells you

With C++, the deal is simple. The compiler lets you write the bug. You find it later, at night, in the program that is already running. It is a bad deal, but it is a quiet one.

Rust does not let you write the bug. It stops you, explains the problem in a paragraph, points at the line and suggests a fix. Most of the time the fix is correct. That is the problem. I cannot even be angry at it properly.

I want to run my program and see what happens. Rust wants me to understand it first. I did not ask for a teacher. I asked for a compiler.

C++ is dangerous, and honest about it. Rust is safe, and very pleased about it.

One new case broke every mod

Every tool in T-Rustable is a mod, including the built-in ones. A mod is a WebAssembly component, and wasmtime, which is written in Rust, runs it. My first plan for edits was one enum, with one case for each edit command. Then I tested what happens when the app grows.

The mod was built forThe app gives itResult
API 1.0.01.1.0, with one new functionThe mod loads
API 1.0.01.1.0, with one new enum caseRefused: "a matching implementation was not found"

One new case, and every mod built for the old version stops loading. To be fair, this is a rule of the WebAssembly component model and of how wasmtime links, not of the Rust language. I am including it anyway, because it is my blog.

The fix was to throw the enum away. Edits are now a transaction: an object with one method for each command. A new command is a new method, and old mods never see it. The price is that every type in the API is frozen. I can never add a field to a record again. I think about that sometimes.

Installing a mod. The app reads what the mod imports and shows it as permissions before anything is installed.

Six days of dependency weather

The build runs cargo-deny, which fails when a dependency has a security advisory. The first 84 commits took six days. In those six days, it stopped me three times:

  • ttf-parser, which I used to check fonts for missing glyphs, was marked unmaintained in RUSTSEC-2026-0192. I moved to skrifa.
  • zip had to go to version 9 for three advisories.
  • wasmtime had to go to 49.0.4 for two security advisories.

I like that the tool exists. I do not like that I needed it three times in one week.

Then the fuzzer. cargo-fuzz builds for its own musl target by default, and the address sanitizer does not work with a static libc. One more flag. One more evening.

So why is it still in Rust?

Because it works, and I hate that most of all.

The editor opens a PDF, draws it in tiles and lets mods add text, shapes and images, with undo. A mod that crashes takes down the mod, not the app. If the engine panics, it restarts PDFium and reloads the open documents from their journals. A 24-step self-test runs twice on Windows and twice on Linux in CI.

Every one of those guarantees came from the compiler refusing something I wanted to do. It was right every time. You cannot hate something properly when it keeps being right. I am trying anyway.

So T-Rustable stays in Rust. I will keep writing it, and I will keep hating it, more than C++. It is early, and not ready for daily use yet. If you want to watch me suffer in public, the code is on GitHub.

The T-Rustable logo. The project is not affiliated with the Rust Project, which is the nicest thing I can say about it today.

The work this is about

  • T-RustableA local, offline PDF editor for Linux and Windows. Every tool is a mod, and you can write your own. Source-available, in early development.
Bhargavaram Krishnapur
Bhargavaram Krishnapur

Computer science student at Vijaybhoomi University and founder of The Pulse Engine. I build local-first, open-source tools. See the portfolio or GitHub.

5 min readSoftware engineering · Security

Local-first software

A tool you cannot run offline is a tool somebody can switch off.