C.W.K.
Stream
Lesson 03 of 03 · published

When to Use Vim+Tmux vs a Full IDE

~11 min · vim, tmux, ide, tradeoffs

Level 0Trapped
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

The honest answer: it depends

Anyone who tells you Vim+tmux is always better — or that JetBrains is always better — is selling something. Both stacks are world-class at different things. The mature take is to know what each excels at and pick deliberately. Most senior engineers use both, sometimes in the same week.

Where Vim+tmux dominates

  • Remote development. SSH into anything; your editor and workspace come with you. No "Remote Development" extension required, no second daemon, no GUI lag.
  • Polyglot daily work. Same editor, same key bindings whether you're touching Python, TypeScript, Lua, shell, or YAML. No language-specific IDE switch.
  • Speed and latency. Sub-millisecond response time on basically any hardware. JetBrains can't match terminal latency.
  • Customization. Every keystroke and behavior is configurable. Your editor truly fits your hands after a few months.
  • Resource use. Runs in 50MB on a Raspberry Pi. JetBrains needs 2GB just to open.
  • Text-processing power. Macros, regex, shell integration for bulk edits — Vim is the sharpest knife in the drawer.
  • Pair programming. Shared tmux sessions = real-time collaboration with no extra tools.

Where a full IDE wins

  • Heavy refactoring with strong types. JetBrains' Java / Kotlin / C# refactor tools are decades ahead of any LSP. Rename across types, extract interface, move method between classes — IntelliJ's accuracy is unmatched.
  • Visual debugging. Graphical breakpoint managers, variable inspectors, call-stack visualizers, time-travel debuggers. nvim-dap exists but is a step behind for complex debug sessions.
  • Learning a new language. Auto-complete plus inline docs plus example-search inside the IDE accelerates the first month with an unfamiliar API.
  • GUI-heavy work. Designing UI layouts, database GUIs, integrated profilers, visual diff tools.

The hybrid pattern most people land on

  1. Default editor: Neovim+tmux for everything routine.
  2. Reach for a JetBrains IDE when the day's task is heavy refactor, complex debug, or new-API exploration.
  3. Use Vim bindings inside the IDE (IdeaVim plugin) so motion muscle memory transfers.

A lean starter config — both files in one place

By the end of this quest you have an opinionated config that fits in two short files. The .tmux.conf from Track 6 and the init.lua from Track 4. Below is the absolute minimum-viable both — pin this somewhere as a starting point for any new machine.

Configurability is a means, not the end. The point of Vim+tmux isn't "infinitely customizable." The point is "the editor feels like your hand by year two." That happens only if you start small and let the config grow with felt needs. People who treat it as a configuration sport burn out; people who treat it as a tool that adapts to them stay forever.

Code

Minimum-viable ~/.tmux.conf — keep it short·tmux
unbind C-b
set -g prefix C-a
bind C-a send-prefix

set -g mouse on
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -sg escape-time 0
set -g history-limit 50000
setw -g mode-keys vi
set -g focus-events on
set -g default-terminal "tmux-256color"
set -ag terminal-overrides ",xterm-256color:RGB"

bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind r source-file ~/.tmux.conf \; display "Reloaded"

bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
Minimum-viable init.lua — pair with the tmux above·lua
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
  vim.fn.system({ "git", "clone", "--filter=blob:none",
    "https://github.com/folke/lazy.nvim.git", "--branch=stable", lazypath })
end
vim.opt.rtp:prepend(lazypath)
vim.g.mapleader = " "

-- Settings
local opt = vim.opt
opt.number = true; opt.relativenumber = true; opt.cursorline = true
opt.signcolumn = "yes"; opt.scrolloff = 8; opt.termguicolors = true
opt.expandtab = true; opt.tabstop = 4; opt.shiftwidth = 4
opt.ignorecase = true; opt.smartcase = true; opt.incsearch = true; opt.hlsearch = true
opt.mouse = "a"; opt.clipboard = "unnamedplus"; opt.undofile = true
opt.splitright = true; opt.splitbelow = true; opt.updatetime = 250

-- A few keymaps
local map = vim.keymap.set
map("i", "jk", "<Esc>")
map("n", "<Esc>", "<cmd>nohlsearch<CR>")
map("n", "<leader>w", "<cmd>w<CR>")

-- Plugins
require("lazy").setup({
  { "nvim-treesitter/nvim-treesitter", build = ":TSUpdate",
    opts = { highlight = { enable = true } } },
  { "nvim-telescope/telescope.nvim",
    dependencies = { "nvim-lua/plenary.nvim" },
    keys = {
      { "<leader>ff", "<cmd>Telescope find_files<CR>" },
      { "<leader>fg", "<cmd>Telescope live_grep<CR>" },
    } },
  { "folke/which-key.nvim", event = "VeryLazy", opts = {} },
  { "christoomey/vim-tmux-navigator", lazy = false },
})

External links

Exercise

Make an honest list. For each project you currently touch, decide: is it a Vim+tmux project, an IDE project, or either-fine? You're not picking favorites — you're noticing where each tool genuinely earns its place. Write the answer next to the project name in your notes. Revisit in three months and see which decisions you'd flip. Real fluency is knowing which knife to grab; this exercise is the first step.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.