Josh Scalisi

Software I use

Below is a list of desktop software I use in 2025. This list excludes software I use only for professional work.

I prefer software that is free and open source, has trustworthy non-pseudonymous maintainers, has been reviewed and packaged by the developers of multiple reputable operating systems, has effective supply chain security, has relatively few dependencies, runs daemons only if necessary, has relatively low CPU and memory usage (like this), has low input latency, is highly customizable (such as command-line software with many options), and uses plain text files for configuration and data storage.

My favorite sites for finding software are ArchWiki, suckless.org/⁠rocks, and Debian Popularity Contest. ArchWiki has comprehensive lists of software that don't include a lot of questionable programs like some large software directories do, and I like how most of the lists are split into command-line and GUI software because I usually want the former. suckless.org/⁠rocks has the highest signal-to-noise ratio of any software directory I've used. Debian Popularity Contest provides helpful statistics, especially the statistics for the main subsections sorted by the "vote" field.

Overview

Operating system

The desktop operating system I use is Fedora Linux. I like that Fedora developers prioritize security, such as enabling SELinux by default and writing security patches when necessary (patches that other operating systems benefit from, but sometimes months later).

Fedora's package repository has recent versions of nearly all of the software I want, which allows me to avoid installing software from source to the extent I did in the past and avoid less secure packages I might be tempted to install if I were to use a different operating system, such as AUR packages, Homebrew packages, Nix packages, PPA packages, Ubuntu universe packages, Debian backports, and unverified Flatpaks.

I use the Fedora Everything installer to perform minimal installations of Fedora that exclude a desktop environment and other GUI software. Afterward, I configure my system and install packages using an idempotent system configuration script I wrote named configure, which I run daily.

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 for a few reasons. First, desktop environments include a lot of GUI software, while I mostly use command-line software and Emacs. Second, I enjoy seeking out optimal software, so I'm not interested in collections of GUI software chosen by other people. Lastly, the desktop environments I've evaluated have too many daemons; for example, my PC with Fedora 42 and no desktop environment had only XX userspace processes after running startx with my xinit config, while a virtual machine I created with Fedora 42 and GNOME had a whopping 114 userspace processes by default.

Window manager

I use an X11 window manager named Openbox. The last time Openbox had a stable release was in 2015, but it does everything I need it to do, it works perfectly, and it's highly configurable (see my Openbox config).

Openbox is a stacking window manager. I prefer stacking window managers to tiling window managers because I usually have only three GUI apps running — a terminal emulator, text editor, and web browser — and all three benefit from being maximized to full screen. For example, I like having a wide tab bar in my web browser, and I frequently use my terminal emulator and text editor to display files with long lines, such as log files and plain text spreadsheets.

I haven't fully evaluated any Wayland compositors that support stacking window management (such as labwc, Wayfire, and hikari) because I'm so satisfied with Openbox.

Taskbar

I don't use a taskbar (a.k.a. status bar) 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.

Desktop notifications

I use a desktop notification daemon named Dunst. It works great and it's adequately configurable (see my Dunst config).

Application launcher

I don't use an application launcher because I think they're unnecessary. Instead, I start GUI apps using key bindings specified in my Openbox config and using aliases specified in my Bash config.

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).

Also, I like that xterm has low memory usage because I always have multiple instances running. I prefer to have multiple terminal windows rather than use a tabbed terminal emulator because I usually have only a few apps running and it's quicker for me to Alt+Tab to a specific terminal window than it is to Alt+Tab to a tabbed terminal emulator and select a specific tab.

I configure xterm using my X resources, which are loaded by xrdb via my xinit config.

If I were to switch from Openbox to a Wayland compositor, I'd probably replace xterm with foot.

Command shell

The command shell I use is Bash. The main reason I use Bash instead of an alternative like Zsh or Fish 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 ShellCheck (or using a more verbose language like Python), and I dislike having to mentally compartmentalize the features of multiple shells when 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.

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. For example, htop is used by macOS users and procps top isn'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.

POSIX utilities

I use implementations of POSIX utilities that are installed by default on Fedora, including GNU coreutils and Bash builtins.

Occasionally I extend the functionality of POSIX utilities by writing Bash scripts, such as relocate and remove.

Sometimes I use alternatives to POSIX utilities (see file search). I don't use alternatives whose primary purpose seems to be outputting more colors (such as bat, eza, and LSD) because I prefer fewer colors.

File manager

I don't use a file manager because I think they're unnecessary. Instead, I manage files using command-line tools.

File watcher

I use a file watcher named inotifywait, which is from a set of inotify-based utilities named inotify-tools. I like that inotifywait can execute shell functions (not just programs) in response to file changes, which is a feature that some file watchers lack.

When I write a Bash script that needs to find one or more files, and performance isn't a factor, I use GNU find or GNU grep because I try to use standard utilities as much as possible when writing Bash scripts.

When I search for files interactively, or when performance is otherwise a factor, I use fd or 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 a fuzzy finder named fzf. And when I use fzf in Emacs, I do so using a package named fzf.el.

When I search for PDFs, I sometimes use pdfgrep.

Search and replace

When I need to find and replace text in multiple files, I use ripgrep via my Bash script named replace. My script previously used GNU grep for searching and GNU sed for replacing. I switched to ripgrep because GNU grep is slower, GNU sed's multiline replacements are less ergonomic, and GNU sed's regular expressions require more escaping.

When I need to find and replace text in only one file, I use Emacs.

Text editor

The text editor I use is Emacs. It's my all-time favorite app. I use Emacs for note-taking, spreadsheets, calculations, to-do lists, calendar, email, batch renaming, version control, static site generation, programming, and, most importantly, tweaking my Emacs config.

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 text files written using a feature-rich lightweight markup language that is similar to Markdown but much more powerful. For example, as I mention in the next section, Org supports plain text spreadsheets, which is an awesome 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 (such as uses/index.org).

Spreadsheets

The software I use for spreadsheets is Emacs with Org. Org spreadsheets are plain text, and as a result, they 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 like 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.

Calculator

The calculator I use is an Emacs package named Calc (not to be confused with calc by Landon Curt Noll).

Task management

The software I use for task management is Emacs with Org. Org to-do lists are plain text, and yet Org supports 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 org-wild-notifier to the similar package named org-alert because the latter sends notifications nonstop for day-wide tasks until such tasks are 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.

Email

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 text file, and I prefer this because my favorite solution for local backups is rsync with hard links for deduplication, which doesn't work well with large, frequently modified files, such as 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 web pages using Org files (such as uses/index.org), Bash scripts (such as mkindex), and plain old HTML files.

I format my HTML and CSS using a Node.js package named Prettier via an Emacs package named format-all that 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 using a Node.js package named Stylelint via an Emacs package named Flycheck that integrates linters into Emacs.

I don't lint my HTML in Emacs, but I do validate it during the build process using a Java program named Nu HTML Checker (a.k.a. v.Nu and vnu), which is the only HTML5 validator recommended by the WHATWG and W3C. Nu HTML Checker supports CSS too, but I use it only for HTML because it doesn't recognize certain valid CSS, such as nested CSS and the oklch() function.

I minify my HTML using a Go program named minify, and I minify my CSS using a Node.js package named Lightning CSS. 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 HTML minifiers I've used. For example, the Rust program minify-html can produce invalid HTML, and the Node.js package html-minifier-terser has most of its features disabled by default, which required me to specify a whopping 19 options in every build script in which I used it.

I deploy personal web pages to Cloudflare Pages. Cloudflare has a command-line tool named Wrangler that provides a dev server for local development. Unfortunately, the dev server can use hundreds of megabytes of memory because Wrangler is written in TypeScript. Instead of using Wrangler, I use a web server written in C named darkhttpd, which is very lightweight and meets my dev server requirements (such as caching being disabled) with only a few command-line arguments, not a whole config file like most web servers I've used.

Web browser

The main web browser I use is Firefox. It has great privacy features, such as Strict Enhanced Tracking Protection; it supports uBlock Origin (not the inferior uBlock Origin Lite); and it's more customizable than other browsers, including Chrome and Chromium, which don't even allow users to remove the "Close tab" button.

I configure Firefox primarily via the files user.js, userChrome.css, and userContent.css. I configure Firefox via its GUI only when necessary.

I've used dozens of browser extensions over the years, including some I thought were essential, such as Tree Style Tab, Tab Session Manager, and Auto Tab Discard. But I now try to minimize the number of extensions I use to avoid issues relating to security, privacy, and performance. The only extension I currently use is uBlock Origin.

Password manager

I use a command-line password manager named pass. It stores passwords in text files that are encrypted by GnuPG. I run pass via my Bash scripts pass-generate, pass-show, pass-edit, and pass-use.

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.

Video player

I rarely download video files, but when I do, I play them using a command-line video player named mpv. I like that mpv has a seekbar, unlike other command-line video players I've used, such as MPlayer and ffplay.

Screenshots

The screenshot software I use includes Firefox's screenshot feature and a command-line tool named scrot.

Image editors

The image editors I use are GIMP and ImageMagick. Most of my 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 — sometimes years later — by quickly editing and rerunning the associated script.

Image viewer

I tested 27 image viewers that support Linux and my favorite is feh. I like that feh can bind keys to shell commands, it supports XCF files, it has low memory usage, and it uses plain text config files (see my feh config).

PDF viewers

I read PDFs using zathura. I like that zathura 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 a surprising number of PDF viewers I've used; and it uses 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 in order for it to remember the last viewed page of each PDF, it needs GVfs, which I avoid installing because it requires multiple daemons. An Evince fork named Papers is planned to replace Evince, but I currently prefer Evince because Papers uses 100-200% more memory and its search results have excessive line height resulting in 34% fewer results being displayed before scrolling.

I wanted to use an Emacs-based PDF viewer named pdf-tools because I love using Emacs, but memory usage was far too high.

Printing

CUPS

Backups

rsync with hard links for file deduplication

xorriso

Hypervisor

I use a command-line hypervisor named QEMU. I use QEMU to play with operation systems; evaluate programs and review their dependencies on a clean system; and test my system configuration script.