For years, developers are often told that complex IDEs with dozens of running extensions are mandatory to build modern software. But as backend systems grow to encompass multiple microservices, background queues, and containerized databases, heavyweight desktop tooling can become a distraction.
Here is a look into my daily development environment and why terminal-centric tooling keeps my workflow fast and reproducible.
The Operating System Foundation
I primarily run Arch Linux and Ubuntu Server across my workstations and headless nodes. The reasons come down to three core tenets:
- Kernel Consistency: Deploying to Linux production servers feels seamless when your local kernel, filesystem semantics, and networking match production 1:1.
- Resource Efficiency: Without background telemetry and resource-hungry GUI layers, the entire operating system idles under 800 MB of RAM, leaving full system horsepower for compiling, test suites, and Docker containers.
- Reproducibility: System configuration lives in declarative dotfiles version-controlled via Git.
Process Supervision: Systemd over Screen/Tmux
When managing local services (like local gateways, bots, or development proxies), many developers rely on detached terminal sessions (tmux, screen, or nohup). This often leads to orphaned processes that silently crash when an unhandled exception occurs.
Instead, I configure user-level or system systemd services:
# Easy management commands
sudo systemctl restart s4way.service
sudo systemctl status shiesuta.service
journalctl -u shiesuta -f -n 50 Systemd provides built-in exponential backoff restarts, centralized journal logging, and clean shutdown signals (SIGTERM) without writing boilerplate daemon scripts.
The Editor: Zed & Neovim
While VS Code remains capable, Zed has become my primary editor for writing TypeScript, Rust, and Go. Written in Rust with GPU-accelerated rendering, it opens files instantaneously and handles large codebases without stuttering.
For rapid terminal edits over SSH, Neovim remains unmatched.
Container Orchestration with Docker Compose
Running multiple versions of MySQL, Redis, and Lavalink directly on the host machine pollutes the operating system with conflicting dependencies.
Every service has an isolated docker-compose.yml:
services:
redis:
image: redis:alpine
container_name: cache-redis
ports:
- "127.0.0.1:6379:6379"
volumes:
- redis_data:/data
restart: unless-stopped
volumes:
redis_data: Binding ports strictly to 127.0.0.1 ensures test databases are never exposed on public interfaces while keeping cleanup as simple as docker compose down -v.
A minimal, terminal-driven environment removes friction and lets you focus entirely on shipping reliable software.