Josh Scalisi

Software I use

Below is a list of software I use on my personal laptop in 2026. I'm excluding software I use on my phone because I don't use it much.

I prefer software that is open source, has trustworthy non-pseudonymous maintainers who prioritize security (especially supply chain security), is mature, has been reviewed and packaged by the maintainers of multiple reputable package repositories (such as Debian and Fedora maintainers), has relatively few dependencies (smaller attack surface), runs daemons only if needed, has relatively low CPU and memory usage (like this), has low input latency, is adequately configurable, 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

I use Fedora Linux on my personal laptop. I like that Fedora developers prioritize security, including hardening the Linux kernel, enabling SELinux by default and writing security patches when needed (such as UnZip patches that were added to some other operating systems much later).

Fedora's package repositories have recent versions of nearly all the software I want. This helps me avoid installing software from source to get newer versions (which I used to do when my desktop operating system was Debian Stable) and allows me to 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 always use the second-newest release of Fedora, not the latest, because I assume this helps limit my exposure to supply chain attacks.

I use the Fedora Everything installer to perform minimal installations of Fedora that exclude GUI software, such as a desktop environment. After installing Fedora, I run 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. Third, the more software that is installed, the larger the attack surface. Lastly, the desktop environments I've evaluated have too many daemons; for example, my personal laptop with Fedora 42 and no desktop environment has only XX userspace processes after running startx with my xinit config, while a virtual machine I created with Fedora 42 and GNOME had 114 userspace processes by default.

Window manager

I use an X 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 great and it's highly configurable.

Openbox is a stacking window manager. I use a stacking window manager instead of a tiling window manager because I prefer to maximize all windows and switch between them using Alt+Tab. This simple setup works well for me because I usually have a small number of windows to switch between (for example, Emacs, QEMU, a web browser and a few terminals). I'll reevaluate tiling window management if I upgrade my primary monitor from 27" 5K to 32" 6K or larger.

I haven't fully evaluated any Wayland compositor as an alternative to Openbox (such as labwc or Wayfire, which both support stacking window management) because Emacs has performance issues on Wayland.

Taskbar

I don't use a taskbar (a.k.a. status bar) because I think they're unnecessary. When I want to see a list of open windows (which most taskbars include), I press Alt+Tab. When I want to see other information that is commonly displayed on taskbars, I use a key binding specified in my Openbox config to run my shell script named status, which displays the time, date, CPU usage and memory usage as a desktop notification.

Interestingly, it was the creator of a taskbar who inspired me to stop using taskbars. In 2012, the creator of the i3status taskbar wrote, "If you need to look at some kind of information more than once in a while […] you are probably better off with a script doing that, which pops up."

Desktop notifications

I use a desktop notification daemon named Dunst. I've used Dunst for many years and it's always worked perfectly.

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 GUI 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 some of the systems I use include Bash and will never include Zsh or fish, and I'd rather use Bash on every system than frequently switch between different shells.

Also, there is an excellent linter for shell scripts named ShellCheck that supports Bash scripts but not Zsh scripts and not fish scripts. I strongly prefer Bash scripting with ShellCheck for system administration tasks compared to the alternatives I've tried, such as POSIX shell scripting, Perl, Python (with or without sh, Plumbum, zxpy, etc.), Ruby (with or without Shell) and JavaScript (with zx, ShellJS, Execa, Dax or Bun Shell). I still need to try fish scripting with the fish-lsp language server, which apparently supports linting.

Another reason I don't use Zsh or fish is that their main benefits include history and completion features I don't need. For example, I don't need advanced history features because I save useful commands with custom descriptions in a text file named selectcmd.dat, from which I select commands using a fuzzy finder named fzf via my shell function named _selectcmd, which I execute using a Readline key binding. Also, I don't need advanced features for completing command options because I select option-heavy commands using _selectcmd. And I don't need advanced features for completing paths because I select most paths using fzf.

One other reason I use Bash is that it's adequately configurable. 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.

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 shell scripts (such as remove and relocate) as well as functions in my Bash config (such as _cdls).

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

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 popular among Mac users. 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.

Virtualization

I create KVM-based VMs using a type 2 hypervisor named QEMU (pronounced quem-you by Peter Maydell). I use VMs to build sandboxed development environments, play with operating systems, evaluate programs and their dependencies on clean systems, and test my system configuration script.

Password manager

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

Another command-line password manager I've evaluated is gopass, which fell short because of breaking changes (see here, here and here) and a concerning lack of users (compare this and this).

File manager

I use an Emacs-based file manager named Dired. I mostly use Dired for batch renaming via a special mode named named Wdired. Dired lists the contents of a directory in a buffer, and Wdired makes the buffer editable like a text file. This allows files to be renamed with a regex search and replace that can be easily undone.

Using Dired and Wdired for batch renaming is similar to using the Go program named mmv (not to be confused with the C program named mmv).

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 shell scripts that need to find files and performance isn't a factor, I use GNU find or GNU grep because I try to use the default utilities of Fedora and Debian as much as possible when writing shell 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.

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

When I need to find and replace text in one or more files on a dev VM (such as during a build process), I use GNU sed or sd. I prefer sd for multiline replacements on dev VMs.

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, version control, programming, web authoring, batch renaming and more.

Many people assume the only reason Emacs users choose Emacs for non-programming activities 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.

A major benefit of Emacs is that it helps me pursue my goal of maximizing the amount of my data that is stored in text files, which is one of my highest priorities in the context of computing. For example, I use Emacs to create plain text spreadsheets.

Note-taking

The software I use for note-taking is Emacs with an Emacs package named Org (a.k.a. Org mode and org-mode). Org files are text files written using a lightweight markup language that is similar to Markdown but with a lot more features (see here and here). 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 software 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 my personal spreadsheets is Emacs with Org. Org spreadsheets are plain text, and so 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 create spreadsheets in 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 references to spreadsheet files in my notes.

Calculator

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

Task management

The software I use for personal 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 recurring task a specified amount of days after the day that the task was done (not the day it was scheduled to be done, which is what many task management apps are limited to doing).

Calendar

The software I use for my personal calendar is Emacs with Org. Org 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 personal 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 client

The email client I use is an Emacs package named mu4e. I like that mu4e uses maildir, my favorite email storage format. Each message in a maildir directory is stored in its own text file, and I strongly 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. 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. My preferred solution is to configure mu4e to allow lines in emails to be up to 998 characters, which is longer than any paragraph I would write.

Mail retrieval agent

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.

Programming

I write code using Emacs. Most of my personal code is shell scripts and Emacs Lisp. I lint my Emacs Lisp code using Flymake, and I lint my shell scripts using ShellCheck via Flymake.

I don't use an AI coding agent to write my personal code, but I do use Claude Code to review my code as well as other people's Emacs Lisp code that I want to add to my Emacs config.

I experimented with formatting my shell scripts using shfmt, which seems to be the most popular shell script formatter. I stopped using it because comment alignment can't be disabled (see example). Automatic comment alignment is problematic because it can cause lines to be much longer than 80 characters, which is my preferred maximum line length for shell scripts.

Web authoring

I'm using the term web authoring instead of web development because my personal websites have simple static pages that don't include any JavaScript. I create my sites using Org files (such as uses/index.org), shell scripts (such as mkindex) and plain old HTML files.

I use Emacs to write HTML and CSS, which are formatted by Prettier via an Emacs package named prettier-js. I like that Prettier has zero dependencies, unlike most other Node.js packages I've used. Prettier is one of only three Node.js packages I'm willing to run outside of a dev VM. (The others are pnpm and typescript-language-server. And I remove pnpm immediately after using it to install the other two.)

I lint my YAML (such as pnpm-workspace.yaml) using yamllint via Flymake and a Flymake backend named flymake-yamllint.

I lint my CSS using Stylelint. Unfortunately, like many other Node.js packages, Stylelint has too many dependencies. As a result, I'm unwilling to install it outside of a dev VM and integrate it into Emacs like I do with Prettier and yamllint.

I minify my HTML using a Go program named minify, and I minify my CSS using 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, I won't use minify-html because it can produce invalid HTML, and I stopped using html-minifier and its forks because most of their minification features are disabled by default, which resulted in me having to specify 19 options in each of my build scripts.

I validate my minified HTML using vnu (a.k.a. Nu HTML Checker), which is the only HTML5 validator recommended by the WHATWG and W3C. vnu supports CSS too, but I use it only for HTML because it doesn't recognize certain valid CSS, such as nested CSS.

Web browsers

For web browsing, I use Chrome, Chromium and Firefox. I use three browsers because I want three profiles. The reason I don't use three profiles in one browser is that it's easier for me to Alt+Tab to a specific profile when each profile has a different app icon.

I don't use third-party derivatives of Chromium or Firefox because of security concerns. For example, some Chromium derivatives, such as Vivaldi, are based on extended stable Chromium, which is not recommended if security is a primary concern. And some derivatives, such as Helium, LibreWolf, ungoogled-chromium and Zen, have pseudonymous maintainers who tend to have young accounts at GitHub, social networks, etc. Unsurprisingly, none of the aforementioned derivatives were in the package repositories of Fedora or Debian when I checked.

I've used many browser extensions over the years, including some I thought were essential, such as Tree Style Tab and Session Manager. But I eventually decided to limit the number of extensions I use to avoid security and performance issues. The only extensions I currently use on my personal devices are uBlock Origin and uBlock Origin Lite.

I used to write my own extensions, but nowadays I only write browser-related shell scripts, such as import-search-shortcuts.

Chatbots

Screenshots

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

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 for Linux.

Image editors

For personal image editing, I use ImageMagick and GIMP. If my edits can be done with ImageMagick, that's what I use; otherwise, I use GIMP. I prefer ImageMagick because I save my ImageMagick commands in shell scripts alongside my images and this allows me to easily re-edit an image later (sometimes years later) by tweaking and rerunning the associated script.

A commonly recommended alternative to ImageMagick is libvips. Unfortunately, the libvips CLI is really basic and requires the use of intermediate files.

Image viewers

I've tested 27 image viewers for Linux and my favorites are feh and imv (not to be confused with the renameutils tool named imv). I like that feh and imv start quickly, they switch images quickly, they have plain text config files and they can bind keys to shell commands.

feh's advantages over imv include lower memory usage and support for XCF (when using the -⁠-⁠conversion-timeout option). imv's advantages over feh include support for PSD and animated GIFs.

My only real compaint about feh and imv is that passing them a directory (my typical usage) causes their overlays to display the total number of files in the directory, not the total number of images. My solution is two shell scripts I wrote named fehdir and imvdir, which help ensure that only images are added to the file lists of feh and imv.

Media player

I use a command-line media player named ffplay, which is included with FFmpeg. I like that ffplay has low CPU usage, especially because I use it all the time to listen to my favorite white noise audio file, which I play and stop using my shell script named toggle and an associated key binding specified in my Openbox config.

My only complaint is that the ffplay window doesn't display the duration when I play a video. My solution is an ffplay wrapper I wrote named play, which prints the duration in the terminal before starting ffplay.

A media player with even lower CPU and memory usage is mpg123, which is written in assembly. I used mpg123 for many years, but unfortunately, it supports MP3 only, which is why I now play audio files using ffplay.

PDF viewer

I use a PDF viewer named Evince. I like that Evince provides an interactive list of search results, which is a must-have feature that's missing in nearly all other PDF viewers for Linux.

My only complaint is that Evince needs GVfs to remember the last viewed page of each PDF. I'm unwilling to install GVfs because it requires multiple daemons. Fortunately, I don't really need Evince to remember pages.

Evince was the default PDF viewer in GNOME until 2025, when it was replaced by an Evince fork named Papers. I don't use GNOME, but I tried Papers and I disliked how its list of search results had excessive line height that resulted in 34% fewer search results being displayed per screen compared to Evince.

I wanted to switch to an Emacs-based PDF viewer named pdf-tools because it provides an interactive list of search results and I love using Emacs. Unfortunately, when I browsed a PDF using pdf-tools, CPU usage was high and memory usage of Emacs increased by more than 6GB.

Printing

The software I use for printing is CUPS. It works great and my only complaint is that installing CUPS on Fedora automatically enables a CUPS service, which is undesirable because I rarely use my printer and I prefer that software only runs when needed. So I disabled the CUPS service and wrote a shell script named cups that I use to start and stop the CUPS service on demand.

Backups