Developer Productivity Tools I Use Every Day
As a solo developer working on multiple projects, productivity is not optional — it is survival. I do not have a team to pick up slack, so every tool and workflow I adopt needs to earn its place. Over the past few years, I have refined my setup to a point where I feel genuinely efficient. Here is everything I use daily and why.
Code Editor: VS Code
I have tried Neovim, Sublime Text, JetBrains IDEs, and Zed. I keep coming back to VS Code. It is not the fastest or the most powerful in any single dimension, but the combination of speed, extensibility, and ecosystem is unmatched for my workflow.
Extensions That Matter
I am deliberate about extensions — each one adds startup time and cognitive overhead. Here are the ones that have survived my regular pruning:
ESLint and Prettier. These two handle code quality and formatting automatically. I configure them to run on save so I never think about formatting. The key is to set them up once in your project configuration and forget about them.
GitLens. Inline git blame, file history, and comparison views. When I need to understand why a line of code exists, GitLens tells me who wrote it, when, and in which commit. The inline blame alone saves me dozens of context switches per day.
Error Lens. Displays errors and warnings inline, right next to the problematic code. No more squinting at the problems panel or hovering over squiggly lines. Errors are immediately visible where they occur.
Todo Tree. Scans your codebase for TODO, FIXME, and HACK comments and presents them in a tree view. I use TODO comments liberally during development as breadcrumbs for unfinished work, and Todo Tree ensures I never lose track of them.
Thunder Client. A lightweight REST API client built into VS Code. For quick API testing during development, it is faster than switching to Postman. I use it for testing my backend endpoints without leaving the editor.
Auto Rename Tag. When you rename an HTML/JSX opening tag, it automatically renames the closing tag. A tiny quality-of-life improvement that prevents a surprisingly common category of errors.
VS Code Settings I Swear By
{
"editor.formatOnSave": true,
"editor.bracketPairColorization.enabled": true,
"editor.guides.bracketPairs": true,
"editor.minimap.enabled": false,
"editor.wordWrap": "on",
"editor.fontSize": 14,
"editor.tabSize": 2,
"files.autoSave": "onFocusChange",
"explorer.confirmDelete": false,
"workbench.startupEditor": "none"
}
Disabling the minimap and startup editor removes visual noise. Auto-save on focus change means I never lose work when switching between editor and browser. Bracket pair colorization makes nested code structures readable at a glance.
Terminal Setup
I spend a significant amount of time in the terminal, so investing in a good setup pays off handsomely.
Zsh with Oh My Zsh. Zsh is now the default shell on macOS, and Oh My Zsh adds sensible defaults, plugins, and themes. I use the git plugin (short aliases like gst for git status), the z plugin (jump to frequently used directories), and the zsh-autosuggestions plugin (suggests commands based on history).
Starship prompt. A fast, customizable prompt that shows useful context: current git branch, Node.js version, whether there are uncommitted changes, and command execution time. It is written in Rust and noticeably faster than prompt themes written in shell script.
tmux. Terminal multiplexer that lets me maintain persistent sessions with multiple panes and windows. I typically have three panes: editor, dev server, and a general-purpose shell. Even if my terminal crashes, tmux sessions survive.
fzf. Fuzzy finder for the command line. I use it for searching command history (Ctrl+R), finding files, and filtering any list of items. Once you start using fzf, going back to regular shell history search feels painful.
bat. A cat replacement with syntax highlighting and line numbers. When I need to quickly view a file in the terminal, bat makes it readable.
ripgrep (rg). A faster grep replacement. When I need to search across a large codebase from the terminal, ripgrep returns results almost instantly.
Git Workflow
Git is the backbone of my development workflow, and I have specific practices that keep things clean.
Conventional commits. I follow the conventional commits specification: feat:, fix:, docs:, refactor:, test:, chore:. This makes git history scannable and enables automated changelog generation if I ever need it.
Small, focused commits. Each commit should represent one logical change. If I am fixing a bug and notice an unrelated style issue, those are two separate commits. This makes git bisect useful and code review (even self-review) practical.
Branch naming. I use a consistent pattern: feature/description, fix/description, refactor/description. For solo projects, I often work directly on a development branch and merge to main when stable.
Git aliases. A few aliases that save keystrokes daily:
git config --global alias.lg "log --oneline --graph --decorate -20"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.last "log -1 HEAD --stat"
The lg alias gives me a compact, visual overview of recent history that is far more useful than the default git log output.
Project Management: Obsidian
For project management and note-taking, I use Obsidian. It stores everything as plain Markdown files on your local filesystem, which means no vendor lock-in, no subscription required, and full control over your data.
My vault structure for project management:
Tasks/
칸반 보드.md # Kanban board (To Do / In Progress / Done)
daily-tasks.md # Daily task tracking
Templates/
daily-template.md # Template for daily notes
Research/
monetization.md # Revenue research
competitor-analysis.md
I use the Kanban plugin to maintain a visual task board and the Tasks plugin to query tasks across all files. The combination gives me the benefits of a project management tool without the overhead.
Why not Notion? Notion is excellent for teams, but for solo work, I find the overhead of a cloud-based tool unnecessary. Obsidian is faster, works offline, and my notes are just files I can version control.
Design: Figma
Even as a developer, I use Figma for UI work. Not for polished mockups, but for quick wireframes and component exploration. Before writing any UI code, I sketch the layout in Figma to make decisions about spacing, hierarchy, and flow.
For indie developers, Figma's free tier is more than sufficient. I use it for:
- Wireframing new features before implementation
- Creating app store screenshots and promotional graphics
- Designing icons and simple illustrations
- Iterating on color palettes and typography
Figma tip for developers: Use Auto Layout extensively. It mirrors how CSS Flexbox works, so designs built with Auto Layout translate naturally to code.
Browser DevTools
Chrome DevTools is a full debugging environment that most developers underutilize. Here are the features I use beyond the basics:
Performance profiling. The Performance tab records a flame chart of your application's activity. I use it to identify slow renders, excessive re-renders in React, and layout thrashing. Run a profile, look for long tasks (anything over 50ms), and optimize those hot paths.
Network throttling. Testing your app on a slow network reveals problems that are invisible on fast connections. I regularly test with "Slow 3G" throttling to catch missing loading states, excessive bundle sizes, and unoptimized images.
Lighthouse. Built-in performance, accessibility, SEO, and best practices audit. I run Lighthouse on every page of my apps and aim for scores above 90 across all categories. It catches issues like missing meta tags, poor contrast ratios, and render-blocking resources.
Device emulation. The responsive design mode lets you test on different screen sizes, but also lets you emulate touch events, device pixel ratios, and even geolocation. I test every feature on at least three viewport sizes: mobile (375px), tablet (768px), and desktop (1440px).
Console utilities. console.table() for array/object data, console.time() and console.timeEnd() for measuring execution time, and console.group() for organizing related logs.
CI/CD
Even for solo projects, automated CI/CD saves time and prevents mistakes.
GitHub Actions is my CI/CD platform. For every project, I have at minimum:
- Lint and type check on push. Catches errors before they reach production.
- Run tests on pull request. Ensures new code does not break existing functionality.
- Automated deployment on merge to main. Removes the friction of manual deployment.
A basic GitHub Actions workflow for a Next.js project:
name: CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm run type-check
- run: npm test
This takes five minutes to set up and catches problems automatically from that point forward.
Package Managers
I use pnpm for all JavaScript/TypeScript projects. It is faster than npm, uses less disk space through content-addressable storage, and has stricter dependency resolution that prevents phantom dependency issues.
For Flutter projects, pub (Dart's built-in package manager) is the only option, and it works well enough.
Lock files are non-negotiable. Always commit your lock file (pnpm-lock.yaml, package-lock.json, pubspec.lock). This ensures everyone (and every CI runner) uses the exact same dependency versions.
Debugging
Beyond print statements and console.log, here are debugging techniques I use regularly:
VS Code debugger. Setting breakpoints and stepping through code in VS Code is more efficient than adding console.log statements. For Node.js and browser JavaScript, the built-in debugger works excellently with minimal configuration.
React DevTools. The Components tab shows your component tree with current props and state. The Profiler tab records renders and shows why each component re-rendered. This is indispensable for diagnosing performance issues in React apps.
Network tab debugging. For API-related bugs, the Network tab in DevTools is your first stop. Check request headers, response bodies, and timing. The ability to copy requests as cURL commands and replay them in the terminal is invaluable.
Time Management
Tools are only half the equation. How you manage your time determines how much you actually get done.
Time blocking. I dedicate specific hours to specific types of work. Morning for deep coding work, afternoon for administrative tasks and communication, evening for learning and experimentation. Context switching is expensive, and time blocking minimizes it.
The two-minute rule. If a task takes less than two minutes, do it immediately instead of adding it to your task list. This prevents small tasks from accumulating into a daunting backlog.
Weekly review. Every Friday, I review what I accomplished, what I did not get to, and what I want to focus on next week. This keeps my projects moving forward with intention rather than just reacting to whatever feels urgent.
Pomodoro technique (modified). I work in 45-minute focused blocks followed by 10-minute breaks. The standard 25-minute Pomodoro is too short for deep programming work — by the time I am in flow, the timer goes off. Forty-five minutes lets me achieve depth while still forcing regular breaks.
The best productivity system is one you actually use. I have tried elaborate setups with multiple apps and complex workflows, and I always gravitate back to simple tools used consistently. A text editor, a terminal, a task board, and focused time — that is what actually moves projects forward.