Terminal-first Mouseless Development Or How To Be A Hipster Engineer

In this article, I’m going to give you a slightly different view on
something you do on a daily basis. A philosophy that encourages you to
only use what you really need, keeps you away from being distracted,
lets you think about what your problem really involves, and trust what
your fingers have learned instead of relying on visual representation.
That is what I call terminal-first mouseless development. I’ll
try to sell it to you by giving an overview of how you can benefit from it in
real life. Apart from the theory,
we are also going to see real applications of these approaches.
In particular, we will talk about tmux
and neovim
— industry standards for becoming a real
hipster developer.
Hipster development?
We are all familiar with our IDEs, coupled with other tools for tasks like database management (DBeaver), testing APIs (Postman), and container management (Docker Desktop). Even though they provide an extensive GUI, they are also quite rich in distracting elements. Additionally, using multiple tools and navigating between them means a lot of context switching as well as having quite a loaded environment. If you say that your favorite IDE has everything built-in, then it violates the philosophy of Unix, which says that it is more idiomatic to use small tools that do one thing well rather than the opposite. Sort of a single responsibility principle.
And here comes what I call “Terminal-first development”, but it can be called by any other similar terms. Its core principle is that your terminal should be your central hub for development tasks. Instead of installing a new GUI application to solve a problem, the terminal-first approach challenges you to:
-
Decompose the problem into smaller, distinct steps.
-
Assign a small, dedicated CLI tool to each step.
-
Combine these tools, piping their outputs together, to solve the initial challenge.

As a practical example, you want to select an arbitrary table from your database, get all of the data within it, and pretty-print it as JSON. You have two options:
-
Install and use a couple hundred megabytes of “pgAdmin” that will create another distractive window in your workflow and eat your memory, blasting your brain with all the buttons and menus around its GUI.
-
Create a simple script that uses “psql” to get a list of all tables in your database, pass them to “fzf” so you could interactively select them, pass the table name again to “psql” to output data from it in JSON, and finally pass it to “jq” to pretty-print the result.
Even though I have already intentionally hated on option 1, there could be a point like: “Why would I do everything said in point 2 if I can just go to pgAdmin and press a single button or two?”. And that is valid. And here we come to one of the most important points: the approach described in option 2 is just an example of a philosophy that you can follow or not. And that is your choice. And it would not be incorrect or make you a bad developer. It is all about what you prefer (and how lazy you are :P). But if you selected option 2, then you probably prioritize:
-
Modularity & Portability
-
Better resource usage
-
Minimalistic & distraction-free workflow
-
Scriptability & Automation
-
Customisation
Another interesting thing to think about the second approach is that if you look closely, it is all about piping, or basically passing data from one function to another. And with this approach, it gives you a grounded look at something fundamental regarding software engineering in general — it is quite a lot, if not completely, about viewing, manipulating, and creating data. Actually, pretty much what our brains do.
Last but not least — such an approach really encourages learning, deeper understanding, and mastering of general software engineering skills, which eventually raises the level of craftsmanship. Personally, this philosophy is what sparks joy in my everyday work.
Another philosophy that usually goes hand in hand with the terminal-first one is mouseless or keyboard-centric development, which literally means what it says — it encourages you to prioritize the usage of a keyboard over a mouse or trackpad for writing or navigating through your code. It is important to say here that it doesn’t mean that you should never use those. Sometimes it is quite inefficient to avoid using your trackpad, but for the most part, the theory is that mostly using your keyboard makes your development faster, more efficient, and less tiring.

Why? Well, you keep your hands on the keyboard and avoid switching between it and a mouse. Additionally, you rely on muscle memory in the form of keybindings and not on visual navigation to perform actions. This way you reduce mental overhead, stay in the flow state, and perform basic actions much faster. For example, the research by SuperHuman showed that some basic operations that we perform every day can be done from 2 to 5 seconds faster if performed with a keyboard rather than a mouse. And we perform those actions a lot, so think about the amount of time you could save in a day.
But let’s not idealize things and talk about the downsides. The primary one is a steep learning curve. From my experience, following those philosophies really makes you rethink the way you approach software development. I struggle to point out the exact points, but it just feels quite different, and you really need time to get used to that new reality, and that basically means a long learning curve. The basic parts of it are memorizing all the keybinds or switching your mindset to use CLIs over graphical applications. But hey, learning all the buttons in your IDE also took time, so it is more about whether you are ready to commit to that.
Core In Practice
So now, let’s finally go from something totally metaphorical to something more practical. There isn’t a single right way to implement the philosophy that I described above. But, while finding my own way there, I could distinguish two core elements or, in fact, pieces of software, that will help you to build up a foundation.
tmux
I mentioned that with terminal-first development, your terminal becomes the “central hub” for solving software engineering tasks. When you think about a hub, you probably expect it to provide an infrastructure that you can utilize to effectively achieve your goals. The industry standard for that is called “tmux”, which is a terminal multiplexer by its definition.
It allows you to conveniently create terminal windows, splits, or even sessions for grouping. That makes it easy to organize your work between multiple projects, for example, and allows you to navigate more smoothly.
You can say, “Yeah, but my terminal emulator can do the same.” Sure, but what if the keybinds change? What if you switch to another emulator? What if you now have to use a different system? You basically need to adapt and configure this new tool for yourself. So how does using “tmux” help you? It is completely platform and terminal-emulator agnostic. Everything you have to do is to put your configuration file in the root folder and run “tmux”. This way you are completely independent of the platform that you run “tmux” on top of.

Another thing is that, at its core, “tmux” is a server, having all your terminal sessions working in the background. So this can at least save you from accidentally pressing Command + Q in your terminal and crashing out again, but what you can also do is to basically have your whole terminal session setup running, that you can SSH from any other machine and have it all there, as “tmux” itself is just a command-line tool. Combining a configuration basis and server nature, you basically become independent of a machine and/or terminal emulation tools, if you have your “tmux” server hosted somewhere.
Regarding the config, you can do quite a lot, starting from setting basic keybinds, finishing with writing custom scripts for your workflow or modifying the UI. There is even a whole ecosystem of plugins!
And if we talk about downsides, there are not that many, except for the steep learning curve, but trust me, the outcome is worth it.
neovim
I think most of you know “vi” — the editor that’s impossible to exit. One of the first text editors in existence, it relies on the keyboard only. This is because there was no mouse in the early computer days. Theoretically, you can use it to perform any tasks related to text editing and code writing. But the problem with the original “vi” is that it is as plain as possible, and when it comes to modern development, not really efficient. For example, not having the ability to autocomplete code or quickly navigate to a class definition doesn’t sound like a lot of productivity.
To solve this issue, “vim” was created — a feature-rich version of the original “vi” with things like syntax highlighting, the ability to split windows, etc. And most importantly — it provides the ability for extensive configuration, even featuring its own language — “vimscript”. That basically created the possibility to write plugins that allow you to customize your experience in “vim” however you want. As a result, the “vim” plugin ecosystem is probably one of the biggest plugin ecosystems in the world.
But this was not enough for people who considered themselves to be ultra-hipsters. This led to the creation of “Neovim” - a fork, partly rewritten in Lua. This way, significant gains were achieved in terms of extensibility and architecture. Nowadays, “Neovim” is known for its great documentation and is supported by a quite big and active community of contributors.
Ultimately, you can think of “*vim” as a constructor. Its ecosystem provides you with the bricks you can use to build a development tool to satisfy any of your needs. From the most plain text editor to an ultra-feature-rich IDE. Basically, you can completely replace whatever you are using now. Just watch out so as not to violate the Unix philosophy.
So how does switching to “*vim” feel, and what does it bring to your life? First of all, text editing starts to feel so much smoother, and the whole navigation process around the code feels really fluent. Using “*vim” really proves the benefits of trusting your muscle memory via keybinds instead of visual navigating. The overall overhead goes down, and you can also feel it when you have to work with several projects/directories. Opening a project, quickly looking for something, and editing it feels so light and easy. Using “*vim” is like dropping a huge backpack when going uphill and changing it for something small, compact, accessible, but extendable at the same time. And last but not least, making the editor behave literally however you want it to in a programmatic way is another amazing part.

But let’s not forget about the struggles you may face: “*vim” really makes you rethink the way you write your code (and using keybinds is not the only part), which will take quite some time. Another thing is configuring the thing to meet your needs. Yeah, that takes time. Initially, it took me maybe like 20+ hours, and it is also a non-stop process, but that is a fair trade-off for the extensibility you get. There is a joke in the “*vim” community about people spending more time on customizing their config than on actually using it. And another thing is that as it is community-driven, you may face things that don’t work properly. For example, in order to have all the IDE features for Java, you need to run Eclipse’s “jdtls”, a language server, which doesn’t usually perform well on a large Java codebase. But your mileage may vary.
Conclusions
My main point in this article was to provide you with a new perspective. An approach that you can incorporate in your day-to-day tasks. A philosophy that embraces you to:
-
Think more about what your task involves and what you really need to solve it
-
Maintain your workspace clean and distraction-free
-
Build a unique environment that you love working in
-
Introduce joy and creativity into your routine
And while it might feel like a step back, this philosophy is surprisingly forward-thinking. Many of today’s brand-new AI tools are designed specifically for the command line. In the end, there is no single way to do things. Technical benefits like efficiency are important, but so is finding joy and pride in your craft. Hipster engineering is something that makes me a better professional and makes me love what I do. My sincere hope is that you find your own way to do the same. Thanks for reading.
