Skip to content

Developer Tooling That Compounds Over a Career

The tools, shell setup, editor configuration and workflow automations that compound over a career — and how to build a setup that gets out of your way.

3 min read
Chart contrasting a flat line of one-off tools with a steep compounding curve, above tiles for format-on-save, git aliases, pre-commit hooks and scaffolding.

The Tooling Multiplier

Every developer has a setup that's either working for them or against them. The compounding effect of good tooling is dramatic over a career — if your tools save you 30 minutes per day, that's 120 hours per year. More importantly, reduced friction keeps you in flow states longer.

This is not about chasing the latest tools. It's about investing once in things that pay back every day.

Terminal: The Foundation

Your terminal is your command center. Time spent here is time multiplied.

Shell Configuration That Stays Out of Your Way

shbash
# .zshrc — the essentials
# Better history search
bindkey '^R' history-incremental-search-backward
 
# Fuzzy file finder — changes how you navigate
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
 
# Smarter cd — jumps to frecent directories
eval "$(zoxide init zsh)"
# z myproject  → jumps to ~/code/projects/myproject
 
# Aliases that earn their keep
alias g='git'
alias gs='git status'
alias gl='git log --oneline --graph --decorate -20'
alias gco='git checkout'
alias gcob='git checkout -b'
alias gd='git diff'
alias gds='git diff --staged'
alias ..='cd ..'
alias ...='cd ../..'
alias ll='ls -la'

Git Aliases for Daily Operations

shbash
# ~/.gitconfig
[alias]
  st = status
  co = checkout
  br = branch
  ci = commit
  unstage = reset HEAD --
  last = log -1 HEAD
  visual = !gitk
 
  # Undo last commit, keep changes staged
  undo = reset --soft HEAD^
 
  # Show files changed in last commit
  show-files = diff-tree --no-commit-id -r --name-only -r HEAD
 
  # Clean up merged branches
  cleanup = "!git branch --merged | grep -v '\\*\\|master\\|main\\|develop' | xargs -n 1 git branch -d"
 
  # Pretty log
  lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

Editor: VS Code Configuration That Scales

The editor is where you spend most of your time. A well-configured editor removes constant tiny frictions.

jsonjson
// .vscode/settings.json — project-level settings committed to the repo
{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.tabSize": 2,
  "editor.rulers": [100],
  "editor.minimap.enabled": false,
  "editor.bracketPairColorization.enabled": true,
  "editor.inlineSuggest.enabled": true,
  "files.trimTrailingWhitespace": true,
  "typescript.preferences.importModuleSpecifier": "non-relative",
  "typescript.updateImportsOnFileMove.enabled": "always",
  "search.exclude": {
    "**/node_modules": true,
    "**/.next": true,
    "**/dist": true,
    "**/.git": true
  }
}

Extensions Worth Installing

For a TypeScript/React stack, these are the ones I reinstall on every machine:

ESLint                    — inline linting in the editor
Prettier                  — auto-formatting on save
GitLens                   — git blame, history, and diff in the editor
Error Lens                — surfaces errors inline instead of on hover
Import Cost               — shows bundle size of each import
Tailwind CSS IntelliSense — autocomplete for Tailwind classes
Thunder Client            — lightweight API testing (replaces Postman for quick checks)

The Project Scaffold That Saves Hours

Every new project starts from scratch differently. A personal scaffold or template repository eliminates the "setup hour" at the start of every project.

shbash
# package.json scripts that the whole team uses
{
  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "lint": "eslint . --max-warnings 0",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "type-check": "tsc --noEmit",
    "test": "jest",
    "test:watch": "jest --watch",
    "check": "npm run type-check && npm run lint && npm run format:check",
    "prepare": "husky"
  }
}
shbash
# .husky/pre-commit — catch issues before they reach CI
#!/bin/sh
npx lint-staged
jsonjson
// lint-staged.config.js — run only on changed files
{
  "*.{ts,tsx}": ["eslint --fix", "prettier --write"],
  "*.{css,md,json}": ["prettier --write"]
}

Automation: The Things You Should Never Do Manually Twice

shbash
#!/bin/bash
# scripts/new-feature.sh — start a feature branch with all setup done
 
BRANCH_NAME="feat/$1"
 
git checkout main
git pull origin main
git checkout -b "$BRANCH_NAME"
 
echo "Branch $BRANCH_NAME created and ready"
echo "Remember to: create a draft PR early, enable CI"
tstypescript
// scripts/check-env.ts — validate env vars at startup
const required = ["DATABASE_URL", "NEXTAUTH_SECRET", "NEXTAUTH_URL"] as const;
 
const missing = required.filter((key) => !process.env[key]);
 
if (missing.length > 0) {
  console.error(
    `Missing required environment variables: ${missing.join(", ")}`,
  );
  console.error("Copy .env.example to .env.local and fill in the values");
  process.exit(1);
}

The Compounding Habit

The best tooling improvements compound because they change behavior:

  • Format on save eliminates formatting discussions from code review
  • Pre-commit hooks eliminate lint failures from CI
  • Good git aliases make branching feel effortless — so you branch more freely
  • A fast terminal makes you more comfortable in the command line

Invest one afternoon setting up your environment properly. Then invest another whenever you catch yourself doing something manual that feels repetitive. Over a year, the accumulated return on that time is enormous.

The goal isn't the fanciest setup — it's a setup where the tools are invisible and you're thinking only about the problem.

Wilfredo Rujel

Wilfredo Rujel

Full Stack Software Engineer

Share this postX