Software I use
Below is a list of software I use in 2025. This list excludes software I use only for professional work.
I prefer software that is highly customizable, uses plain text files for configuration and data storage, is open source, has relatively few dependencies, has low CPU and memory usage, and runs daemons only if necessary.
Overview
- Operating system: Fedora
- Display manager: none
- Desktop environment: none
- Window manager: Openbox
- Desktop notifications: Dunst
- Taskbar: none
- Terminal emulator: xterm
- Command shell: Bash
- File manager: none
- POSIX utilities: GNU coreutils, etc.
- File search: fd, ripgrep, etc.
- Search and replace: ripgrep
- Backups: rsync, xorriso
- File watcher: inotifywait
- Process viewer: top
- Application launcher: none
- Text editor: Emacs
- Note-taking: Emacs with Org
- Spreadsheets: Emacs with Org
- Task management: Emacs with Org
- Calendar: Emacs with Org
- Email: Emacs with mu4e
- Calculator: Emacs Calc
- Batch renaming: Emacs with Wdired
- Version control: Git, Magit
- Web development: Emacs, etc.
- Web browser: Firefox
- Password manager: pass
- Audio player: mpg123
- Video player: mpv
- Color picker: Gpick
- Image editors: GIMP, ImageMagick
- Image viewer: gThumb
- PDF viewers: zathura, Evince
- Printing: CUPS
- Hypervisor: QEMU
Operating system
The desktop operating system I use is Fedora Linux. I like Fedora because its developers prioritize security (e.g., SELinux by default) and its package repository has recent versions of nearly all of the software I want.
Fedora's large repository of recently released software allows me to avoid installing software from source to the extent I did in the past (e.g., when I used Debian Stable) and avoid less secure packages I might be tempted to install if I were to use a different operating system (e.g., AUR packages, Debian backports, Homebrew packages, Nix packages, PPA packages, Ubuntu universe packages, and unverified Flatpaks).
I perform minimal installations of Fedora (e.g., no desktop environment) using the Fedora Everything installer. Afterward, I run an idempotent system configuration script I wrote named configure, which I run daily.
If I weren't using Fedora, I'd probably use openSUSE Tumbleweed, which is a rolling release Linux distribution whose package repository has recent versions of the software I want and whose developers prioritize security (e.g., SELinux by default). I prefer Fedora to Tumbleweed mostly because I like the stability of Fedora's semi-annual releases.
Display manager
I don't use a display manager (a.k.a. login manager) because I think they're unnecessary. Instead, after my system boots, I log in via the Linux console and run startx to start the window manager specified in my xinit config.
Desktop environment
I don't use a desktop environment because I use very few GUI apps and I don't need the developers of desktop environments to choose apps for me.
Also, the desktop environments I've evaluated have too many daemons. For example, after I installed Fedora 41 with GNOME on a virtual machine, there were <X userspace processes>, which is far more than the <Y userspace processes> that run after I boot my system and start my window manager.
Window manager
I use a stacking window manager named Openbox. It hasn't been updated since 2015, but it does everything I need it to do, it works perfectly, and it's highly configurable (see my Openbox config).
I prefer stacking window managers to tiling window managers because I usually have no more than four GUI apps running – mlterm, Emacs, Firefox, and Chromium – and all of them benefit from being maximized to full screen. For example, I use mlterm (a terminal emulator) to run multiple shells in a split window, I use Emacs to edit tabular data with many columns, and I configured Firefox and Chromium to each display their dev tools in a 50%-wide pane.
I haven't fully evaluated any Wayland compositors that support stacking window management (e.g., labwc, Wayfire, and hikari) because I'm so satisfied with Openbox.
Desktop notifications
I use a desktop notification daemon named Dunst. It works great and it's adequately configurable (see my Dunst config).
Taskbar
I don't use a taskbar because I think they're unnecessary and a poor use of screen real estate.
When I want to view a list of open windows, I do so by pressing Alt+Tab, which is bound to Openbox's window switcher via my Openbox config.
When I want to view other information that is commonly displayed on taskbars, I use a key binding specified in my Openbox config to run my Bash script named status, which displays the time, date, CPU usage, and memory usage as a desktop notification.
Terminal emulator
The terminal emulator I use is xterm. I like that xterm has lower input latency than other terminal emulators (see benchmarks here, here, and here). I configure xterm by loading my X resources using xrdb via my xinit config.
I've used many other terminal emulators, and the only ones I've been tempted to switch to are those that offer features to help manage multiple terminals (e.g., terminal emulators with tabs and Emacs-based terminal emulators with terminal buffers). I always stick with xterm because when I have multiple terminals, all but one of them are running ongoing processes, and I simply minimize those terminals, which moves them to the end of my Alt+Tab list, out of the way but still easily accessible.
If I were to switch from X11 to Wayland, I'd probably replace xterm with foot.
Command shell
The command shell I use is Bash. The main reason I use Bash instead of Zsh or Fish (which seem to be the most popular alternatives) is that there is an excellent linter for shell scripts named ShellCheck that supports Bash scripts but not Zsh scripts and not Fish scripts. I would hate to write my shell scripts without a linter (or using a more verbose language like Python), and I dislike switching between one shell for interactive use and a different shell for scripting.
A second reason I don't use Zsh or Fish is that many people seem to prefer those shells for their history and completion functionality, and I don't need those features. For example, I don't need advanced history features because I save useful commands to a text file named selectcmd.dat from which I select commands using my Bash function named _selectcmd (defined in my Bash config), which I execute via a Readline key binding. Also, I don't need advanced features for completing command options because I select option-heavy commands using _selectcmd. Lastly, I don't need advanced features for completing paths because I select most paths using a fuzzy finder named fzf.
Another reason I use Bash is that it's adequately configurable (see my Bash config). In comparison, Fish's docs state that configurability is the root of all evil, and Fish's autosuggestions couldn't be disabled until 2021, over nine years after they were introduced.
File manager
I don't use a file manager because I think they're unnecessary. Instead, I manage files using command-line tools.
POSIX utilities
I use implementations of POSIX utilities that are installed by default on Fedora, including GNU coreutils, Bash builtins, etc.
When I run POSIX utilities interactively, there are certain options I always want to use and I specify them in my command aliases.
Sometimes I extend the functionality of POSIX utilities by writing Bash scripts (e.g., relocate and remove).
Occasionally I use alternatives to POSIX utilities (see next section). I don't use alternatives whose primary purpose seems to be adding more colors to output (e.g., bat and eza) because I prefer fewer colors (e.g., I think syntax highlighting is unimportant).
File search
I search for files using GNU find, GNU grep, fd, ripgrep, pdfgrep, and fzf.
I use GNU find and GNU grep in my Bash scripts when performance isn't a factor (e.g., searching among a small amount of files) because I try to use standard commands as much as possible when writing Bash scripts.
But when I search interactively, or when performance is otherwise a factor, I use fd and ripgrep because they're faster than GNU find and GNU grep (see benchmarks in fd's docs and ripgrep's docs). Another benefit of fd and ripgrep is that they both exclude files listed in .ignore files (see fd's docs and ripgrep's docs).
When I use fd interactively, I mostly use it via fzf and an fzf-powered Emacs package named fzf.el.
Search and replace
I find and replace text using GNU grep, GNU sed, and ripgrep.
I use GNU grep and GNU sed in my Bash scripts when performance isn't a factor (e.g., finding and replacing text in strings) because, as I mentioned in the previous section, I try to use standard commands as much as possible when writing Bash scripts.
But when I search and replace interactively (using my Bash script named replace), or when performance is otherwise a factor, I use ripgrep because it's faster than GNU grep. Other reasons why I use ripgrep for replacing text include GNU sed's regular expressions requiring more escaping and GNU sed's support for multiline replacements being worse.
File watcher
I use an inotify-based file watcher named inotifywait, which is included with inotify-tools. inotifywait is the most lightweight file watcher I've used, and it works well.
Process viewer
The process viewer I use is procps top (not to be confused with the original top by William LeFebvre or other implementations).
A popular alternative to top is htop, which I used for several years mostly because it seemed that everyone was using it (e.g., htop supports macOS and procps doesn't). I stopped using htop because top does everything I need it to do, it's installed by default on Fedora, and it's lightweight while being adequately configurable (see my top config).
Application launcher
I don't use an application launcher because I think they're unnecessary. Instead, I run GUI apps using key bindings specified in my Openbox config or using aliases specified in my Bash config. My aliases run GUI apps as background processes using my Bash script named background.
Text editor
The text editor I use is Emacs. I love how customizable Emacs is (see my Emacs config).
Not only is Emacs my favorite text editor; it's my all-time favorite app. I use Emacs for note-taking, spreadsheets, to-do lists, calendar, email, calculations, batch renaming, version control, static site generation, programming, and more.
Some people assume the only reason Emacs users choose Emacs for non-programming activitites is because we already use it for programming. But as I mention in the next section, I started using Emacs for note-taking, not programming.
Note-taking
The software I use for note-taking is Emacs with an Emacs package named Org (a.k.a. Org mode). Org files are plain text and are written using a feature-rich lightweight markup language that is much more powerful than Markdown. For example, as I mention in the next section, Org supports plain text spreadsheets, which is a great feature.
My dissatisfaction with other note-taking solutions is what caused me to start using Emacs and Org years ago. I now have several thousand Org files (e.g., uses/index.org).
Spreadsheets
The software I use for spreadsheets is Emacs with Org. Org spreadsheets are plain text and lack many features of other spreadsheet formats, but my personal spreadsheets include small data sets on which I perform basic calculations, and Org is perfect for such spreadsheets.
I love that Org allows me to insert spreadsheets into my Org files that also include my notes. Before I started using Org, I had to keep my notes and spreadsheets in separate files, edit those files using different apps, and include refererences to spreadsheet files in my notes.
Task management
The software I use for task management is Emacs with Org. Org to-do lists are plain text and yet Org has every task management feature I want.
One feature I use a lot is the .+ repeater, which repeats a task a specified amount of time after it was completed (not scheduled to be completed). Surprisingly, very few of the task management apps I've evaluated have this feature.
I use an Emacs package named org-wild-notifier to get task notifications. I prefer it to the package org-alert because the latter sent notifications nonstop for day-wide tasks until such tasks were marked as completed, which is crazy.
Calendar
The software I use for my calendar is Org. It collects the scheduled tasks from the to-do lists in a user's Org files and displays the scheduled tasks in an agenda view that is like a calendar.
I love using Org for my calendar and to-do lists because it allows me to manage my scheduled and unscheduled tasks together in the same files using the same software.
The email client I use is an Emacs package named mu4e. Like most Emacs packages, mu4e is satisfyingly configurable (see my mu4e config).
Another benefit of mu4e is that it uses maildir, my favorite email storage format. Each message in a maildir directory is stored in its own file, and I prefer this because my favorite solution for local backups is rsync with hard links for file deduplication, which doesn't work well with large, frequently modified files like mbox files.
I send plain text emails, and most email clients insert newlines into plain text emails before sending them to prevent lines from being longer than 78 characters. Such newlines cause undesirable line wrapping on screens that are too narrow for 78-character lines. One solution is format=flowed (see RFC 3676). Unfortunately, format=flowed is supported by only a few email clients. The solution I use is to configure mu4e to allow lines in emails to be up to 998 characters, which is longer than any paragraph I would write.
Batch renaming
The software I use for batch file renaming is Emacs with a mode named Wdired, which I strongly prefer to the dedicated batch renamers I've used.
Version control
I use Git via an Emacs package named Magit. I'm a command-line enthusiast, but I prefer Magit to the Git CLI because it's much easier to stage and unstage hunks using Magit.
I wasn't satisfied with Magit's performance out of the box, but it's worked great after I added performance-related settings to my Magit config.
Web development
I create personal websites using the best tools for each site, which might be Bash scripts (e.g., mkindex), Org files (e.g., uses/index.org), non-Org static site generators (e.g., Astro), or plain old HTML files.
I format my HTML, CSS, and JavaScript using Prettier via an Emacs package named format-all, which integrates code formatters into Emacs. I like that Prettier has zero dependencies, unlike nearly every other Node.js package I've used.
I lint my CSS and JavaScript using Stylelint and ESLint via an Emacs package named Flycheck, which integrates linters into Emacs.
I don't lint my HTML in Emacs, but I do validate it during the build process using Nu HTML Checker, the only HTML5 validator recommended by WHATWG and W3C. Nu HTML Checker supports CSS too, but I use it only for HTML because it doesn't recognize certain valid CSS like nested CSS and the oklch() function.
I minify my HTML and CSS using Minify and Lightning CSS respectively. Minify supports CSS too, but not as well as Lightning CSS does. For example, Minify doesn't concatenate imported stylesheets like Lightning CSS does, and Minify doesn't support nested CSS. But Minify is great for HTML, and I prefer it to other command-line HTML minifiers I've used. For example, minify-html can produce invalid HTML, and html-minifier-terser has most of its options disabled by default, which required me to specify a whopping 19 options in every build script in which I used it.
I deploy personal sites to Cloudflare Pages. Cloudflare has a command-line tool named Wrangler that provides a dev server for local development, but the dev server can use hundreds of megabytes of memory because Wrangler is written in TypeScript. So instead of using Wrangler, I use a web server named darkhttpd, which is very lightweight and meets my requirements (e.g., specify a default MIME type and disable caching) with only a few command-line arguments, not a whole config file like most web servers I've used.
Web browser
I use multiple web browsers while developing web apps, but when I browse the web, I use Firefox. It has great privacy features like Total Cookie Protection, it supports uBlock Origin (not the inferior uBlock Origin Lite), and it's highly configurable (e.g., Chrome and Chromium don't even allow users to remove the "Close tab" button).
I configure Firefox primarily using my user.js, userChrome.css, and userContent.css files. I use the settings panels only when necessary.
I try to minimize the number of browser extensions I use to avoid issues relating to security, privacy, and performance. The only extensions I currently use are uBlock Origin and Return YouTube Dislike. I was a long-time user of the extensions Tree Style Tab and Auto Tab Discard, as well as session management extensions like Session Manager and Tab Session Manager. I stopped using those extensions because they contributed to me having hundreds of tabs open whenever I immersed myself in a subject.
Audio player
I rarely listen to music because it hinders my concentration, but I do listen to my favorite white noise MP3 using a command-line audio player named mpg123. I start and stop mpg123 using my Bash script named toggle, which I run via a key binding specified in my Openbox config.
Color picker
The color picker I use is Gpick. I like that Gpick includes a magnifier that can be moved with a keyboard, which makes it easy to select the color of a line that's only 1px wide. This feature is missing in other color pickers I've evaluated, such as Gcolor2, Gcolor3, KColorChooser, and xcolor.
Image editors
For professional work, I use whichever image editors my coworkers use, but for personal tasks, I use GIMP and ImageMagick.
Most of my personal image editing involves prototyping modifications to photos and screenshots in GIMP and then reimplementing and finalizing my changes using ImageMagick commands in Bash scripts. Using scripts for image editing allows me to easily tweak an image later (e.g., years later) by quickly editing and rerunning the associated script.
One area where GIMP and ImageMagick are lacking is ICO files, which are image containers that are commonly used to store PNGs (e.g., favicons). ICOs created by GIMP are too large because GIMP doesn't compress PNGs well, and ICOs created by ImageMagick are even larger because ImageMagick converts PNGs to BMPs. So instead of using GIMP or ImageMagick to create an ICO containing my PNGs, I run one or more optimizers on my PNGs and then create an ICO using a dedicated ICO creator. Of the six PNG optimizers I've tried, the best are Oxipng (lossless) and pngquant (lossy). And of the 24 command-line ICO creators I've evaluated, the best are go-png2ico, icopack, icoutil, and pngs-to-ico.py, which create equally small ICOs.
Image viewer
The image viewer I use is gThumb, an app from the GNOME community. gThumb is adequately configurable (see my gThumb config) and this surprised me because none of the GNOME apps I've used are adequately configurable. I later read that gThumb is not an official GNOME app. That explains it!
I also like the image viewer XnView MP, which is the only closed-source software I've included on this page. XnView MP supports tabs, a nice feature that gThumb lacks. But XnView MP's support for AVIF was broken on Linux when I last checked, and AVIF support is more important to me than tabs.
PDF viewers
I read PDFs using zathura. It makes maximum use of screen real estate by not having a menu bar or toolbar, it remembers the last viewed page of each PDF (unlike some PDF viewers I've tried), and it has a plain text config file (see my zathura config).
I use a PDF viewer named Evince to search in PDFs because it provides a clickable list of search results, a great feature that's missing in zathura and most PDF viewers I've used. I don't use Evince for reading because it needs GVfs to remember the last viewed page of each PDF, and unfortunately, GVfs requires multiple daemons.
I wanted to use an Emacs-based PDF viewer named pdf-tools because I love using Emacs, but memory usage was far too high (e.g., 2GB).
Hypervisor
I use a command-line hypervisor named QEMU. I mostly use QEMU when I'm evaluating software or testing my system configuration script.