App packaging - another thing developers must care about

App packaging - another thing developers must care about

Developers must own their packages - Debian, Ubuntu, Red Hat, Alpine, Arch AUR, Homebrew, Nix, Flatpak, Snap - otherwise someone else will, and that is not a good situation.

We only include the very best devtools in the Console weekly newsletter. This means every week I try out a lot of tools!

If it's a CLI then I usually install it locally on my Mac. That tends to be via Homebrew, or sometimes as an installable app. It might be in Apple's Universal binary format, a DMG, via npm, or maybe an installer. But sometimes there is no Apple Silicon support, so it gets cross-compiled by Rosetta 2 on my M1 MacBook Air. I've seen a few libraries break when dependencies aren't available compiled to the right target.

iTerm window showing homebrew packages on macOS.

I prefer not to install things on my real computer, so I'll often spin up a GitHub Codespace which runs Linux in a container, is nicely isolated, and means I can test it on some real code (where relevant). In these situations, the app may be an npm, or a Debian repo, sometimes it's an x86_64 binary. When I'm done I can destroy the environment.

In rarer cases I need a full VM - I did then when writing the server monitoring tools review. I like Azure's interface the best, so I will spin up their cheapest Linux image and then run the installer there.

I also have a Linux laptop. I have recently been distro-hopping between Debian, Alpine, ElementaryOS, Ubuntu, and Manjaro. Each has its own approach to packaging (with ElementaryOS and Ubuntu sharing the underlying Debian packaging system and Ubuntu also supporting PPAs), and all of them support Flatpak and Snap. Nix is another thing I've been playing with.

Alternatively, I might use the container distribution. This is usually via Docker Hub, so I can run it locally using Docker Desktop, but I also have Nomad running on a Raspberry Pi which might be a better deployment target. Then the image needs to be available for arm64. I run everything using an Alpine Linux host, which uses the apk repos.

apk on Alpine Linux running on my Raspberry Pi 4.

I'm more reluctant to use this because I run some "production" side projects on my Raspberry Pi and it's a pain to deploy new containers outside of the Waypoint deployment framework I use.

That's a lot of environments! If you count up all the different packaging options, I regularly use: Homebrew, Alpine APK, DockerHub, Flatpak, Debian APT, Ubuntu PPA, Arch AUR, Nix, npm.

But it really makes a difference to how easy it is to try things. When there is an easy, native package I can use, I know the app will be installed properly with all dependencies...and it is easy to keep up to date, or remove later.

Syncthing provides release binaries for a lot of platforms.

Developers must own their packages

I might be unusual in how many different systems I use but if packages aren't available for the common platforms then potential users may just skip your release. Not having packages for common platforms is often a reason to mark down a review when considering it for the Console newsletter.

It is a lot of work for developers, but it is crucial. If you don't own at least the key packages, someone else will likely create it for you. That's worse because then the package lags behind the official release. And if that person stops maintaining it for any reason, you're stuck with an official-looking package for a platform you have no control over. This adds to your support burden.

At a minimum, I recommend developers always aim to own the following (where relevant for the target/supported platforms):

  • Compiled binaries for mainstream platforms: aarch64/arm64 macOS, Linux, Windows, x86_64 macOS, Linux, Windows.
  • Major Linux package managers: Debian/Ubuntu (.deb), Red Hat / Fedora / CentOS (.rpm), Alpine, Arch AUR.
  • Popular package managers: Homebrew and Nix. The former is widely used by developers on macOS (and can distribute your compiled binary), but Nix is increasingly being adopted by developers.
  • Linux desktop: If relevant, providing Flatpak and Snap packages can also help reach Linux desktop users, but generally I prefer the native package managers e.g. Debian. The benefit of Flatpak and Snap is the nice marketplace GUI.

Luckily, many of these can be automated through CI/CD, particularly using GitHub Actions. For example, Rust has great support for building on GitHub Actions and Gox or Goreleaser work well for Golang. Investing in release automation is time well spent.

Discover the best tools for developers

Console Newsletter - A free weekly email digest of the best tools and beta releases for developers. Every Thursday. See the latest email.