Skip to content
fuad-daoudPublic

About

Terminal UI that lists every package installed on your machine — pacman/AUR, apt, Homebrew, Flatpak, Snap, npm, pip and Go — in one fuzzy-searchable table.

Topics

Resources

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Repository files navigation

pkgmate

Build Release CodeQL Security Scan Publish APT

Demo

A fast, cross-platform Terminal User Interface (TUI) for browsing the packages installed through multiple package managers, in one unified, responsive interface.

What it does / does not do yet

pkgmate is a viewer today. It does:

  • List installed packages from every supported source that is present on the machine, in five tabs: direct, dependency, all and orphan packages, plus duplicates.
  • Mark packages that are frozen (held or pinned) and packages with a newer version available. For pacman, the newer version of AUR packages is looked up from the AUR.
  • Search the list with live fuzzy matching.

pkgmate does not yet install, remove or upgrade packages.

Duplicates

  • A duplicate is the same application installed through two or more different package managers, with at least one of the copies installed explicitly. pacman and its AUR packages count as one manager, and so do brew formulae and casks.
  • The Duplicates tab lists the copies of the same app on adjacent rows, the group with the largest combined size first. In the other tabs, the Package Manager cell of a grouped package names the other managers in its group, for example pacman (+flatpak), and the footer reports how many apps are installed more than once.
  • Names are matched with a small set of per-ecosystem rules:
    • names are compared lowercase, with _ treated as -;
    • Python packages match across pip, pipx, pacman python-* and apt python3-*;
    • a trailing -bin, -git or -appimage is ignored on pacman names;
    • Go binaries match by their file name (the command you run, e.g. gopls), not by the module they were built from;
    • Flatpak apps match by the last part of their application ID, with a small built-in alias list for well-known apps whose ID does not normalise to their common name;
    • npm global packages are matched by name alone, so an unrelated package that happens to share a name can be reported.
  • pkgmate only reports duplicates. It never removes anything.

Features

  • ⚡ Fast startup - Direct file parsing and efficient CLI wrapping
  • 🔍 Telescope-style search - Live fuzzy search through packages
  • 📦 Multi-backend support - pacman/AUR, dpkg/apt, Homebrew, Flatpak, Snap, npm, pip/pipx, Go
  • 🔒 Security-first - GPG signing, automated vulnerability scanning
  • 📊 Clean interface - Table view with virtual scrolling, visual indicators for available updates and frozen packages, plus orphan and duplicates tabs
  • 🎨 Command palette - Quick access to all features (Ctrl+k or Ctrl+p)

Supported Sources

A source is used when it is detected on the machine at startup. Sources that are not detected are left out silently.

Source Lists Detected when Build tag
pacman/AUR Arch Linux packages, AUR packages marked pacman/AUR /var/lib/pacman exists and pacman is on PATH pacman
dpkg/apt Debian/Ubuntu packages /var/lib/dpkg/status exists and apt or apt-get is on PATH none, always built
Homebrew Formulae and casks, on macOS or Linux brew is on PATH brew
Flatpak Linux Flatpak applications flatpak is on PATH flatpak
Snap Linux Snap packages snap is on PATH none, always built
npm Global npm packages npm is on PATH npm
pip pip and pipx packages in site-packages pip3 or pip is on PATH and can list packages pip
Go Binaries installed with go install, read from $GOBIN, $GOPATH/bin or ~/go/bin go is on PATH golang

Release binaries are built with all of these. See From Source to build a smaller binary.

Installation

Arch Linux

Via AUR:

yay -S pkgmate-bin
# or
paru -S pkgmate-bin

Manual:

curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate-linux-amd64.tar.gz
tar -xzf pkgmate-linux-amd64.tar.gz
sudo install -m 755 pkgmate /usr/local/bin/

Debian/Ubuntu

Via APT repository:

# Add repository
curl -fsSL https://fuad-daoud.github.io/pkgmate/public-key.asc | sudo gpg --dearmor -o /usr/share/keyrings/pkgmate.gpg
echo "deb [signed-by=/usr/share/keyrings/pkgmate.gpg] https://fuad-daoud.github.io/pkgmate/ stable main" | sudo tee /etc/apt/sources.list.d/pkgmate.list

# Install
sudo apt update
sudo apt install pkgmate

Manual .deb:

curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate_linux_amd64.deb
sudo dpkg -i pkgmate_*_linux_amd64.deb

macOS

Via Homebrew:

brew tap fuad-daoud/pkgmate
brew install pkgmate

Manual:

curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate-darwin-universal.tar.gz
tar -xzf pkgmate-darwin-universal.tar.gz
sudo install -m 755 pkgmate /usr/local/bin/

From Source

Requirements: Go 1.25+, build tools (base-devel on Arch, build-essential on Debian)

git clone https://github.com/fuad-daoud/pkgmate.git
cd pkgmate

# Build with every backend, as release builds do
go build -tags=all_backends -o pkgmate ./main

sudo install -m 755 pkgmate /usr/local/bin/

Build tags: which backends are compiled in is decided at build time.

  • all_backends - every backend below. Release builds use -tags=all_backends with CGO_ENABLED=0.
  • pacman, brew, flatpak, npm, pip, golang - one tag per backend, combinable, e.g. -tags=pacman,npm.
  • No tag - only the dpkg/apt and Snap backends, which have no tag of their own and are always built.
  • dummy - registers a placeholder backend for UI development. It does not compile against the current backend interface, so it is not usable at the moment.
# Only the backends you use
go build -tags=pacman,pip -o pkgmate ./main

Usage

# Launch pkgmate
pkgmate

# Show version
pkgmate --version

Keyboard shortcuts:

  • / or Ctrl+F - Search packages
  • Tab / Shift+Tab - Switch between tabs
  • ↑↓ or j/k - Navigate packages
  • Ctrl+P or Ctrl+k - Command palette
  • Ctrl+C - Quit

Security model

pkgmate only reads. It refuses to start as root, it never calls sudo or pkexec, and every external command is run as argv with no shell.

These are the queries it runs, all as your user. The Network column says whether the query uses the network.

Source Queries Network
pacman pacman -Qi, -Qeq, -Qmq, -Qu, -Qtdq; reads /etc/pacman.conf; checkupdates --nocolor when installed (pacman-contrib) checkupdates syncs a private copy of the sync databases under $TMPDIR/checkup-db-$UID with fakeroot; the system databases are not touched. The AUR RPC (https://aur.archlinux.org/rpc/v5/info) is an HTTPS lookup for AUR versions.
dpkg/apt dpkg --get-selections, apt list --upgradable, apt-get --simulate autoremove; reads /var/lib/dpkg/status none
Homebrew brew --cellar, brew --prefix, brew outdated --json=v2, brew autoremove --dry-run
Flatpak flatpak list --app [--columns=…]
Snap snap list, snap refresh --list snap refresh --list asks snapd and the store; it does not refresh
npm npm root -g, npm list -g --json --depth=0
pip pip/pip3 list --format=json, pip show pip, pip list --outdated --format=json, pipx list [--json] pip list --outdated queries the package index
Go reads build info of binaries in $GOBIN, $GOPATH/bin or ~/go/bin; no command

The crash screen can also pipe the report to pbcopy, wl-copy, xclip or xsel when you ask it to.

Verifying Downloads

All releases are GPG signed:

# Download release and signature
curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate-linux-amd64.tar.gz
curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate-linux-amd64.tar.gz.sig

# Import public key
curl https://raw.githubusercontent.com/fuad-daoud/pkgmate/main/public-key.asc | gpg --import

# Verify signature
gpg --verify pkgmate-linux-amd64.tar.gz.sig pkgmate-linux-amd64.tar.gz

macOS Code Signature Verification

macOS binaries are signed with Apple Developer ID and notarized:

curl -LO https://github.com/fuad-daoud/pkgmate/releases/latest/download/pkgmate-darwin-universal.tar.gz
tar -xzf pkgmate-darwin-universal.tar.gz

# Verify code signature
codesign --verify --verbose pkgmate
# Check notarization and Gatekeeper approval
spctl -a -vv -t install pkgmate
# View signing details
codesign -dvvv pkgmate

Expected output:

pkgmate: valid on disk
pkgmate: satisfies its Designated Requirement
pkgmate: accepted
source=Notarized Developer ID

Recording Demo

The demo GIF is created using VHS:

# Install VHS
go install github.com/charmbracelet/vhs@latest

# Record demo (writes demo.gif)
vhs demo.tape

Development

Run the tests with every backend compiled in:

go test -tags=all_backends ./...

Try a snapshot build in a container, with the binary mounted at /pkgmate:

make arch    # Arch Linux container
make debian  # Debian container
make brew    # Homebrew container

# Build snapshot binaries with goreleaser only
make build

Security

All releases undergo automated security scanning with CodeQL, gosec, and govulncheck. View scan results in Security Monitoring.

Report security issues via GitHub Security Advisories.

License

MIT License - see LICENSE for details.

About

Terminal UI that lists every package installed on your machine — pacman/AUR, apt, Homebrew, Flatpak, Snap, npm, pip and Go — in one fuzzy-searchable table.

Topics

Resources

Security policy

Stars

10 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages