Personal CLI Tools
Many command-line routines begin as a handful of commands copied from terminal history. After repeating the sequence enough times, I write an alias, a shell function, or a small application for it. These personal tools form an important part of my developer experience because they encode how I prefer to work.
The cost of creating these small utilities has changed. A coding agent can turn a description of a repetitive task into a working first version in minutes. I still need to explain the behavior, inspect the generated code, and test the dangerous paths, but writing the initial implementation is rarely the obstacle it once was. This makes very specific tools worthwhile, even when their entire audience is one person.
Developer productivity is widely discussed in the literature. For example, the SPACE framework describes it through several dimensions rather than a single activity metric. An actionable framework for developer experience also examines the factors that shape how development work feels. Developer experience, or DevX describes how developers experience the tools, workflows, and systems they use to do their work.
Improve Your CLI Experience with fzf
fzf is a terminal fuzzy finder. It receives a list of lines, opens an interactive selector, and returns the chosen line. Typing a few fragments progressively filters the candidates, so I do not need to remember or type an exact name.
The basic pattern is small:
selection=$(command-that-produces-options | fzf)command-that-uses "$selection"This separates a CLI application into three parts:
- Produce the possible options.
- Let the user search and select one.
- Perform an action with the selection.
The selector can include a descriptive prompt, multiple selection, key bindings, and a preview window. The producing command can attach paths, descriptions, dates, or Git metadata to each option. The final action should validate the selected value and treat Escape as a normal cancellation.
This pattern lets me quickly provide input to my CLI scripts without having to remember the valid values or the exact syntax of each script. It also creates consistency: after learning how one fuzzy command behaves, I already understand much of the next one.
Examples from My Own Tools
config-fz
As my shell configuration grew, remembering the custom command names became its own problem. I started annotating commands with a name and short description. config-fz collects those annotations and feeds them to fzf, allowing me to search the catalog by purpose and execute the selected command.
The annotations make the collection self-documenting. The fuzzy interface means I can benefit from a rarely used helper without first remembering its exact name. Adding a new tool to the catalog requires one comment beside its implementation.
gflog
My gflog command formats the Git reflog with the commit hash, reflog position, date, and subject. Git already contains this information; the personal application chooses the compact representation I want when investigating an earlier state.
gz
gz applies the fuzzy-selection pattern to branches and remote references. It shows each reference together with its hash, author, date, and subject, passes the list through fzf, and resets the repository to the chosen target.
Look for the Script You Are Already Performing
Pay attention to moments when you copy the same commands, reconstruct the same arguments, browse the same directories, or follow the same recovery instructions. Describe one of those routines to a coding agent and ask for a small CLI application. Once it works, improve the interface with fuzzy selection, useful previews, clear prompts, safe cancellation, and confirmation where the stakes require it.
The most useful personal tools often begin with a sequence too specific to interest anyone else. That is precisely why they fit so well. If you do not have a script for a repetitive procedure, you are condemned to act like one: receiving the same inputs, following the same steps, and producing the same output over and over.