Why I packaged ZFS for Omarchy instead of opening a giant PR

or: How I Learned to Stop Forking and Love the Package Manager

I installed my first Linux system in 1997. Since then I've changed distributions more than a dozen times. Caldera, back before that name turned into a lawsuit. Slackware. Red Hat, then CentOS, until CentOS stopped being CentOS. Debian, Ubuntu, Mint. SuSE, then openSUSE. Intel's Clear Linux. Manjaro, Arch, EndeavourOS, CachyOS.

Desktops too. GNOME 2, then the GNOME 3 schism, then KDE. In 2010 Paul Ostazeski at Intridea got me into tiling window managers and I never went back. xmonad first, because I decided my window manager should be a configuration language, and for a while that language was Haskell. Then awesome. Then i3, where I was happy for years, right up until it stopped picking up the features I wanted. Then Hyprland, where I still am. I gave Niri an honest try. It's very good and I don't love it. Both of those can be true.

I've also built at least a dozen machines to run all of it on. Not bought. Built, one part at a time, with the case picked last and loved longest.

Add it up: twenty-nine years, a dozen-plus di[[discord-post-omarchy-zfs]]stros, half a dozen desktops, a dozen-odd machines. Every one of those things got replaced.

The data didn't. The photos, the mail, the ~/src directory full of half-finished ideas have outlived every distro I installed and every motherboard I ever screwed into a case.

That's why I care about filesystems. A distro is a weekend. A build is a month of watching for sales. Your data is your life.

The hardlink years

Before ZFS my backups were the ones a lot of us built. rsync with --link-dest, one directory per run, unchanged files hardlinked back to the previous snapshot. You got a browsable tree for every backup at roughly the disk cost of the changes.

Mike Rubel wrote the canonical version of that trick in 2004. rsnapshot packaged it. Back In Time put a GUI on it.

Apple shipped Time Machine in 2007, and afterward everybody described the technique as "like Time Machine," which always felt backwards to me. We were doing it first.

It worked. I ran it for years.

So why leave? Because it has a ceiling.

Hardlink snapshots are an accounting trick sitting on top of a filesystem that has no idea what you're doing. They can't tell you whether the bytes they copied are the bytes you wrote. Nothing is atomic, so a file that changes mid-run is just a torn file in your backup. Restores are file-level, so "put this whole tree back the way it was Tuesday" isn't an operation you have. And every run walks the entire filesystem to work out what changed, so the bigger the tree got, the slower it got.

I was also tired of watching fsck on boot. There's a particular kind of dread in a progress bar standing between you and your computer when the only move available is waiting.

2019: I tried btrfs first, and I liked it

People expect me to get this part wrong, so let me be clear about it. When I went looking for a copy-on-write filesystem in 2019, I tried btrfs first, and I liked it. Subvolumes made sense. Snapshots were instant. The tools were pleasant. I wasn't a reluctant convert hunting for an excuse.

There was one thing I wanted that it couldn't do. Put a small SSD in front of a pile of spinning disks and let the filesystem handle the caching. btrfs had no answer for that. I decided I could live without it.

Then a disk failed in the array holding my music library. 250 GB, most of a lifetime of collecting, and the array didn't save me. I was, and I am choosing my words carefully here, upset.

Multi-device redundancy was the weakest part of btrfs then, and it was the part experienced people warned about loudest. In 2019 those warnings were right, at least for me, at least that day.

(A coda, in the interest of honesty. Months later I found the whole library sitting in an Amazon Glacier archive I'd half forgotten about. It all worked out. That's its own lesson and not a small one. The thing that saved me wasn't a clever filesystem. It was a boring off-site copy I made once and stopped thinking about. Every good storage decision I've made since comes out of that.)

I want to be fair here, because this is where a post like this usually turns unfair. btrfs in 2026 is not btrfs in 2019. It has had years of serious work and it's the default on major distributions for good reasons. My scar tissue is a data point about one era, not a verdict on the filesystem today.

But it sent me looking, and by then I knew what I wanted. Snapshots as a real filesystem primitive instead of an rsync convention. Checksums, so the filesystem tells me when it lost something instead of handing me bad bytes and staying quiet. No fsck between me and a boot. Multi-disk redundancy I trusted. And SSD cache in front of spinning rust. ZFS had all five, and had had them for a decade.

The license I had to make peace with

Knowing what I wanted didn't make me switch.

So why did I sit on it for another stretch? The reason was legal, not technical.

ZFS is CDDL licensed. That's Sun's license, written for OpenSolaris.

Linux is GPLv2. Almost everybody who has looked at the pair concludes you can't combine them and then redistribute the result as a binary.

GPLv2 says derivative works of the kernel have to be GPLv2, and the CDDL won't let you relicense. So ZFS will never land in mainline. Linus has said so direct ly, and his condition for changing his mind was an official letter from Oracle's legal counsel, or preferably from Larry Ellison.

The copyright belongs to Oracle now, who got it along with Sun, and who could settle the whole argument by relicensing, and never has.

The workaround everybody settled on is to ship source and build the module on your own machine with DKMS. Compiling a module for a computer you own isn't distribution, so the contested act never happens. Canonical is the loud exception. They ship a prebuilt zfs.ko and argue it's fine, the Software Freedom Conservancy publicly disagreed, nothing got resolved, and it just became normal.

I find that unsatisfying. I also think the real cost isn't legal, it's operational. ZFS is out of tree permanently. It has to be rebuilt for every kernel. It can lag a new kernel by months. And kernel developers occasionally tighten something that lands on ZFS in particular. In 2019 a set of FPU symbols went GPL-only and ZFS lost its SIMD acceleration for a while.

Every guard in the package I eventually wrote exists because of those two paragraphs. Out-of-tree modules are why a kernel upgrade can strand you, why a DKMS build failure being a mere warning is dangerous, and why something has to watch your back. The license sits upstream of all of it.

Getting ZFS onto Clear Linux

I was on Intel's Clear Linux at the time. Aggressively optimized, stateless, opinionated in its own ways, and with no real story for out-of-tree kernel modules. When people asked for ZFS, the answer from the core team was no. Here's a maintainer on a 2019 request for a ZFS bundle:

Unlikely this will happen. Please consider using btrfs which is supported out of the box, or compile the drivers yourself.

Four days later he closed it: "This seems unreasonable to keep open unless licensing concerns are addressed by the copyright owner of this code." The official FAQ carried an entry titled "Is ZFS Available?" and the answer was not encouraging.

Worth noting who else was in that thread. One person wanted ZFS because they were trying to put an SSD cache in front of an HDD array and btrfs had no easy support for it, which is my own motivation coming out of a stranger's mouth. Jim Salter, whose sanoid I now list as a dependency, turned up eight months later stuck on the same build.

So I compiled it myself and wrote up how. That became the original Clear Linux ZFS guide in Intel's own documentation, merged in June 2020.

Not root-on-ZFS, to be accurate about my own history. Pools on non-root devices, with the kernel module and userspace tools built by hand and a systemd unit to load the module at boot. My PR said so at the time: "I stopped before adding a ZFS-on-root section because this tutorial is already long.

ZFS-on-root is substantially harder." Once it merged, the core team deleted the "Is ZFS Available?" FAQ entry.

It was the first time I noticed how much more useful "here's exactly how I did this" is than "somebody should support this."

(A parenthetical I've never quite gotten over. The Clear Linux core team then reformatted essentially every line of that guide without changing the content. Wild.)

Intel has since wound Clear Linux down. clearlinux.org doesn't resolve anymore and the forums are gone. The guide outlived the distribution, which is either poetic or the entire point of this post, depending on my mood.

Where I am now

The current machine, number twelve or thereabouts, lives in a Fractal North. I love that case more than is reasonable for a box that mostly sits under a desk being quiet.

Inside it, an NVMe mirror for the root pool. Behind that, a pool of spinning disks with a 256 GB NVMe in front doing read cache and log duty, which makes a stack of cheap rust behave a lot like a very large SSD for the way I actually use it. Best price-per-terabyte trick I know, it's one zpool add, and it's exactly the thing I gave up when I tried btrfs in 2019 and told myself I could live without.

The NAS is TrueNAS Scale. Snapshots replicate there, and from there out to cheap S3 and Cloudflare R2. The piece that makes that chain tolerable is raw encrypted send. zfs send -w ships the still-encrypted blocks, so the cloud target holds my data without ever holding a key, and nothing gets decrypted and re-encrypted along the way. My laptop, my workstation, my NAS and my off-site copies all speak the same commands.

That's the context for everything below. ZFS isn't a preference I hold. It's the substrate the rest of my computing sits on.

Then I switched to Omarchy

I got to Omarchy sideways, through my own software. I build Voxtype, a dictation tool for Linux, and Carmine Paolino asked me for a few Omarchy-friendly features. I'm a Rails developer, so I knew DHH was building a distribution. I just hadn't gotten around to trying it. That request was the nudge. November of last year I finally installed it.

Here's the part I like telling. I installed Omarchy on its own ZFS dataset and booted it with ZFSBootMenu. No repartitioning, no dual boot in the traditional sense, no risk to my working machine. I made a boot environment, installed a distribution into it, and picked it from a menu at power on. CachyOS stayed my daily driver the whole time. If Omarchy hadn't worked out, cleanup would have been one zfs destroy.

So the first thing ZFS ever did for Omarchy in my life was let me try Omarchy at all. That's the same thing this package hands everybody else now, and it's why I keep saying boot environments are the point rather than a nice extra.

I ran it that way for months. What moved me in the end was people. I decided the Omarchy conference was worth going to so I could meet other users in person, and Ryan Hughes talked me into switching wholesale while I was there. I did. Never looked back, never regretted it, which after a dozen-plus distros is not a sentence I hand out often.

It helped that Omarchy was already standing where I'd parked. Fifteen years of tiling window managers had landed me on Hyprland on my own. Omarchy ships Hyprland, configured by somebody with taste, wired into a coherent set of everything else. Short distance to travel.

Because here's the thing. Omarchy is good because it's opinionated. DHH picked a coherent set of choices and made them work together, and the result feels designed instead of assembled. I spent years maintaining my dotfiles as a personal art project. Omarchy is better than my art project and it took an afternoon instead of a decade.

Opinionated means the opinions are not decoration. And there was one I couldn't take: btrfs.

You can see why from the last few sections. Partly the scar tissue. Mostly that my storage world already runs on ZFS, and I didn't want two mental models of snapshots, encryption and replication depending on which machine I was sitting at. I want whole-pool native encryption instead of a filesystem stacked on LUKS. I want zfs send to my NAS. I want one toolset from the laptop to the off-site copy.

There's a portability argument too, and it's worth stating narrowly, because the sloppy version of it is wrong. ZFS is a first-class filesystem on Linux, FreeBSD and illumos, sharing one on-disk format and one set of feature flags, so you can export a pool on one, carry the disks to another, and import it. Past those there are real community ports. OpenZFS on macOS is at 2.3.1 and supports Apple Silicon as well as Intel. OpenZFS on Windows exists but is still shipping release candidates, so I wouldn't trust it with anything I cared about yet.

btrfs is Linux-only in practice, though not for want of trying, and I'd rather be accurate than score points. WinBtrfs is an impressive clean-room read-write driver for Windows, signed, actively maintained, good enough that ReactOS ships it. What btrfs doesn't have is a macOS story beyond a virtual machine or a microVM-and-NFS shim, or any other operating system that treats it as native.

I don't use macOS or Windows. I still like knowing my disks would be readable if I had to.

That's a real requirement. It's also a minority requirement. Both of those being true at once is the whole story of this project.

The pull request I didn't open

My first instinct was the obvious one. Teach Omarchy to install on ZFS, open a PR, feel useful.

So why didn't I? Four reasons.

It wasn't a bug, it was a product decision. Omarchy's installer, its snapshot story and its boot flow are built around btrfs on purpose. Asking for ZFS support isn't asking for a fix. It's asking somebody else to adopt a second filesystem, permanently.

A big PR for one person's use case is a tax on everybody else. The code is the cheap part. What I'd really be proposing is a second path that has to be tested on every release, forever, by people who don't run it. That's not a gift. Maintainers who accept that kind of contribution end up maintaining your hobby.

Reviewers can't validate what they can't run. Root-on-ZFS with ZFSBootMenu touches partitioning, initramfs generation, out-of-tree kernel modules, EFI boot entries and encryption key handling. A reviewer without a ZFS machine can't meaningfully review that. Merging it would mean trusting me, and then owning it when it broke at 2am for somebody else.

And forks rot. The other option was maintaining a fork with ZFS patched in. I tried that shape early. It's a treadmill. Every upstream release is a merge conflict, and the week you get busy is the week your users are stranded on old code.

So I sat on it. For a while the honest answer was that ZFS on Omarchy was possible if you were willing to hand-assemble it and re-check it after every update, which is a long way of saying it wasn't safe.

What Quattro changed

Omarchy 4, Quattro, ships as Arch packages from a real repository instead of a shell script that clones itself into your home directory.

That sounds like plumbing.

Why does it matter? It changed the entire shape of my problem.

Once Omarchy is a package, I don't need to modify Omarchy. I can depend on it. omarchy-zfs is a normal Arch package that lists omarchy as a dependency, adds the ZFS layer, and gets out of the way. Every file it ships is a real package-owned file. Remove it and you're left with plain, unmodified Omarchy. No fork, no patch set, no treadmill.

The interesting engineering isn't the install. It's staying installed. An omarchy update is entitled to overwrite its own files, and some of those files decide whether your machine boots. So the package leans on pacman hooks that run last in every transaction and re-assert what has to be true.

  • The zfs mkinitcpio hook. omarchy update rewrites Omarchy's mkinitcpio drop-in every run. Without a guard, the next kernel rebuild produces an initramfs with no ZFS in it, and you find that out at the worst possible moment. The hook re-derives the effective hook list and writes it into a drop-in that sorts later, so upstream's additions come along automatically and zfs always lands before filesystems.
  • Snapper configs. Omarchy's updater snapshots before it does anything, using snapper, whose config hardcodes btrfs. On ZFS that fails and the update aborts before touching a package, which leaves a machine you can't update until you fix it by hand. The package removes snapper configs pointing at something that isn't btrfs, and leaves real btrfs ones alone.
  • The EFI boot order. limine is a hard dependency of Omarchy and registers its own EFI entry, which can quietly move ahead of ZFSBootMenu. On root-on-ZFS that's a dead boot, not a cosmetic problem. A hook keeps ZFSBootMenu first, and only ever reorders. It never deletes another bootloader's entry, because that call belongs to the admin.
  • Kernel upgrades. ZFS is out of tree, so a new kernel can outrun it, and a DKMS build failure is only a pacman warning. Nothing stops you rebooting into a kernel with no zfs.ko. A pre-transaction guard blocks the upgrade instead, with a loud explanation and an escape hatch for when you know what you're doing.

None of that is glamorous. All of it is the difference between getting ZFS working once and ZFS on this machine being boring. Boring is the goal. Twenty-nine years taught me to want boring.

Upstream said no, and they were right

The ZFS request on the Omarchy ISO repo was closed in July. Not supported, not planned, a product decision rather than an oversight.

That was the right answer, and right for the same reasons I had already talked myself into. It also left me something more useful to do than argue about it. Write the thing down.

So alongside the package there are docs now, covering the three situations people actually land in. A fresh machine you want on an encrypted ZFS root. An existing Omarchy install you want to move onto ZFS, where the short answer is that no in-place btrfs to ZFS conversion exists and anything claiming otherwise is about to lose your data. And the one most people actually want, which is keeping Omarchy's btrfs root exactly as it is and putting ZFS under /home or a data pool.

They include the parts that went wrong, because that's what nobody writes down. That ZFS will cheerfully mount a dataset over a non-empty /home and make your files invisible while new writes go somewhere else. That findmnt /home answers "mounted" for a plain directory that is not one. That a missing /home makes the login screen behave exactly like it's rejecting a correct password.

What I'm actually happy about

The satisfying part isn't the ZFS support. It's that packaging turned out to be a social technology as much as a technical one.

A pull request says please carry my use case forever. A fork says I'll carry yours forever, badly. A package says I'll carry mine, you carry yours, and we agree on an interface. Nobody has to argue about taste. Upstream keeps its opinions, I keep mine, and my machine boots.

Twenty-nine years in, that feels like the actual lesson. Not a filesystem preference. A way to disagree with software you admire without asking anybody to change their mind.

Omakase

My wife orders off the menu. Then she modifies it.

Cheese on that. Sauce on the side.

Add black olives. No onions, but extra pickles, and could the dressing come separately?

Fifteen edits to a dish somebody spent a year getting right. I love her.

I also die a little every time.

Here's the thing though. None of it is an allergy.

An allergy is a constraint. A kitchen that ignores one is dangerous, and any chef worth eating from honors it without discussion.

Fifteen preferences are a different animal: a request to swap the chef's judgment for yours, one item at a time. Both are fair to want.

Only one of them obligates the kitchen.

DHH wrote this argument down fourteen years ago, and he wrote it about code. Rails is Omakase. The chef picks the courses, you eat what arrives, and the picking IS the value.

Want to order a la carte? Great.

Different restaurant.

Omarchy is that same argument pointed at a desktop. btrfs is one of the courses.

So what was I really asking for, back when I was drafting that PR in my head? Not an allergy.

I wanted the olives.

My preference is not your burden to carry

There's a habit in open source where a maintainer says no and people treat it as a moral failing. I've watched it happen to people I like, and I've felt the pull myself. You want a thing, the thing is clearly possible, somebody with commit access declined, so obviously they're being unreasonable about it.

They're usually not. A maintainer saying no to your use case is often them protecting the exact quality that made you want to use their project in the first place. Omarchy is good because somebody has taste and applies it consistently. "Support my filesystem too" is a request to dilute that, permanently, for free, on hardware they don't own, in a configuration they can't test.

Nobody owes me a filesystem.

The test I've settled on is simple. If I want something badly enough to argue for it, do I want it badly enough to carry it? Not write it once and hand it over. Carry it. Test it on every release, answer the issues, keep it working when upstream moves under me.

For ZFS on Omarchy the answer was yes, so the weight is mine. omarchy-zfs is my problem. My hooks, my guards, my 2am debugging when a kernel outruns zfs-dkms. If I get bored of it, that's a real risk to anybody depending on it, and people should know that going in instead of finding out later.

Which cuts both ways, and this is the part I didn't see coming. I'm the maintainer now. Somebody is going to ask me for per-user encrypted home datasets unlocked by PAM. It's a reasonable thing to want. I might say no. If I do, it won't be hostility, it'll be me working out what I can actually carry.

Your preference is legitimate. It's also yours.

If your storage world runs on ZFS too, it's an AUR package and an ISO away at omarchy-zfs.com. And if you hit something the docs don't cover, tell me. That's the part I want to hear about.