DNF UI is a graphical frontend for Fedora's DNF (Dandified YUM) package manager, inspired by Synaptic. It is built with GTK 4 and libdnf5 and aims to provide a fast and dependable package management workflow for Fedora.
DNF UI is in early development. The project is active and progressing quickly, but it is not yet a stable replacement for existing package management tools. Interfaces, behavior, and features may change while the application is being stabilized.
- User experience first
- Stability, reliability and predictability
- Strong focus on code quality and maintainability
- No unnecessary complexity or bloat
DNF UI is a package manager frontend, NOT an app store.
It focuses on fast package search, package details, installed package inspection, explicit transaction review, and applying DNF package transactions through Polkit.
DNF UI does NOT aim to manage Flatpaks, firmware updates, ratings, featured applications, or software-center discovery workflows.
- Search repo packages together with installed-only local RPMs
- List installed packages or browse the merged package view
- View package details, files, dependencies, and changelog information
- Mark packages for install, reinstall, and removal
- Review a transaction summary before applying changes
- Apply transactions through a privileged system service with Polkit authorization
- Cancel long-running package queries
- Show search history
- Hide or show the history and information panes
The main browse and search views keep one visible row per package name and
architecture. Repo candidates stay visible as usual, and locally installed RPMs
that are not present in enabled repositories are merged in as Installed (local only) entries instead of being hidden.
I started DNF UI because I am not satisfied with the current graphical package management options on Fedora. I want a package manager frontend that feels fast, reliable, and easy to understand in daily use.
This project is also a practical way for me to learn more about libdnf5, GTK 4, and building a maintainable desktop application. The goal is not to experiment for its own sake, but to build something genuinely useful for me and others.
Build dependencies:
- meson
- ninja-build
- libdnf5-devel
- gtk4-devel
- polkit
- polkit-devel
Meson handles the real build and install logic.
The Makefile is a thin task runner for the common developer commands.
Build and run:
make && ./dnfuiBuild final and run:
FINAL=y make && ./dnfuiRun the Meson setup directly:
meson setup build/debug --prefix /usr --libexecdir libexec
meson compile -C build/debug
./build/debug/src/dnfuiDNF UI uses a small privileged transaction service for package apply operations.
The GUI runs as the regular desktop user, while the service runs on D-Bus and is responsible for the privileged transaction step.
Polkit is used only for the apply step:
- Transaction preview is prepared through the service
- The GUI shows the summary dialog
- Apply is authorized by Polkit on the native system bus
This keeps the main application unprivileged while still allowing normal desktop authentication when a transaction is applied.
For native Polkit testing from the source tree, install the service files with:
make
sudo make serviceinstallThen run the app as a regular desktop user:
./dnfuiWhen you apply a transaction, the desktop Polkit prompt should appear.
Remove the development service install with:
sudo make serviceuninstallNOTE:
serviceinstallis a development helper, not the final packaging flow- Choose a non critical installed package for native apply tests
sudo make serviceinstallinstalls the already built Meson service files from the current build tree and does not rebuild
Test dependencies:
- gio-2.0
- catch-devel on Fedora, which provides
pkgconfig(catch2-with-main)
Run the test suite:
make testRun the full native test matrix, including transaction service smoke tests:
SERVICE_TEST_INSTALL_SPEC=cowsay make nativetestsRun a quick smoke test under Valgrind Memcheck:
make memcheckRun the automated test binary under Valgrind Memcheck:
make memcheck-testsmake memory-check currently runs the full automated Memcheck target.
Run the desktop app under Valgrind Memcheck:
make memcheck-appMemcheck logs are written under build/memcheck/.
The default Memcheck setup fails on definite and indirect leaks from this
project. Reachable and possible leak noise from GLib, GTK, DNF, and related
libraries is suppressed in utils/valgrind-dnfui.supp.
Useful options:
MEMCHECK_SMOKE_FILTER="Transaction request validation rejects an empty request" make memcheck
MEMCHECK_SMOKE_TIMEOUT=5m make memcheck
MEMCHECK_TEST_FILTER="Search returns empty for impossible package name" make memcheck-tests
MEMCHECK_TEST_TIMEOUT=10m make memcheck-tests
MEMCHECK_TRACK_FDS=yes make memcheck-tests
MEMCHECK_GEN_SUPPRESSIONS=yes make memcheck-testsDocker is the default container runtime. The container targets also support
Podman by setting CONTAINER_RUNTIME=podman; the target names stay unchanged
for compatibility.
Build the development image:
make dockersetupBuild the development image with Podman:
CONTAINER_RUNTIME=podman make dockersetupRun the application:
make dockerrunRun the application in Docker with networking disabled:
make dockerrunofflineRun the application in Docker with networking disabled and an empty repo cache:
make dockerruncoldofflineRun the system bus service smoke tests in Docker:
make dockerservicesystemtest
make dockerservicesystemapplytestRun the test suite in Docker:
make dockertestPrime repo metadata online, then rerun the offline-tagged tests in Docker with networking disabled:
make dockerofflinetestRun the Docker app path with networking disabled:
DOCKER_NETWORK_MODE=none make dockerrunRun the full Docker-backed test matrix:
make dockertestsRun the same matrix with Podman:
CONTAINER_RUNTIME=podman make dockertestsDocker notes:
make dockerrunuses the session bus service path for convenience- Use the
dockerservicesystem*targets to test the real system bus authorization flow - Use native Fedora to test the real desktop Polkit prompt
Fedora RPM packaging is included in this repository.
Build a source RPM from the current tracked working tree:
make srpmBuild binary and source RPMs locally:
make rpmBuild a source RPM in Docker:
make dockersrpmBuild binary and source RPMs in Docker:
make dockerrpmArtifacts are written under ./rpmbuild/.
Notes:
- The RPM build uses Meson directly, not the development
Makefile installflow - The source tarball generated by
make srpmis built from the current tracked working tree - The Docker RPM targets use the existing Fedora development image and write artifacts into the same
./rpmbuild/tree - To test the package in a clean Fedora build environment, rebuild the generated SRPM with
mock

