One of the primary things shells are supposed to excel at is file system navigation and manipulation, but the experience is horrible. I can never get `cp`, `rsync`, `mv`, `find` right without looking them up, despite trying to learn. It's way too easy to mess up irreversibly and destructively.
One example is flattening a directory. You accidentally git-cloned one too deep, into `some/dir/dir/` and want to flatten contents to `some/dir/`, deleting the then-empty `some/dir/dir/`. Trivial and reversible in any file manager, needlessly difficult in a shell. I get it wrong all the time.
Similarly, iterating over a list of files (important yet trivial). `find` is arcane in its invocation, differs between Unix flavors, you will want `xargs` but `{}` substitution is also very error-prone. And don't forget `print0`! And don't you even dare `for f in *.pdf`, it will blow up in more ways than you can count. Also prepare to juggle quotes and escapes and pray you get that right. Further, bash defaults are insane (pray you don't forget `set -euo pipefail`).
How can we be failed by our tools so much, for these use cases? Why aren't these things trivial and safe?
I have trouble gauging the effects of `*`, aka "will I cp/mv the dir or all contents of the dir"? Then shell expansion getting in the way, like expanding it all ("argument list too long"). I try to use rsync when possible, where intermittent `.` in paths are relevant, as well as trailing slashes... and don't forget `-a`! Then I forget if those same things apply to cp/mv. Then I cp one directory too deep and need to undo the mess -- no CTRL+Z!
The wide-spread use of `rm -rf some-ostensibly-empty-dir/` is also super dangerous, when `rm -r` or even `rmdir` would suffice, but you need to remember those exist. I find it strange there's no widely (where applicable) available `rm-to-trash`, which would be wildly safer and is table stakes for Desktop work otherwise.
Then there's `dd`...
I use terminals a lot, but a GUI approach (potentially with feedback pre-operation) plus undo/redo functionality for file system work is just so much easier to work with. As dumb as drag-and-drop with a mouse is, a single typo can't wreck your day.
If using dd for messing with filesystems and partitions, then I don't know how much more a gui will save you. Its an inherently scary task that needs some thinking first. Personally, that stuff always scares me gui or not.
What is there to get wrong in your flattening dir example? I'd mv the internal dir as some other name to outside say dir2, them rm rf outer and mv the dir2. Unless there is something wrong in this approach.
I would agree with the rest, I always have to look up find and xargs syntax.
You've never mis-dragged something in the GUI or had a flaky mouse button which lets up randomly while you're dragging which left your folder "somewhere" that you now have to find?
Most of the commands you've mentioned have worked fairly well for me. Are you sure you're looking up cp, mv and find every time before using them? Sounds pretty weird.
LLMs make all those commands trivial to learn. Back in the day we had to study whole man pages meant as reference. Like keeping attention for minutes at a time. The horror!
Research on calculator use in early math education (notably the Hembree & Dessart meta-analysis of 79 studies) found that students given calculators performed better at math - including on paper-and-pencil tests without calculators. The hypothesis is that calculators handle computation, freeing cognitive bandwidth and time for problem-solving and conceptual understanding. Problem solving and higher level concepts matter far more than memorizing multiplication and division tables.
I think about this often when discussing AI adoption with people. It's also relevant to this VS Code discussion which is tangential to the broader AI assisted development discussion. This post conflates tool proficiency with understanding. You can deeply understand Git's DAG model while never typing git reflog. Conversely, you can memorize every terminal command and still design terrible systems.
The scarce resource for most developers isn't "knows terminal commands" - it's "can reason about complex systems under uncertainty." If a tool frees up bandwidth for that, that's a net win. Not to throw shade at hyper efficient terminal users, I live in the terminal and recommend it, but it isn't going to make you a better programmer just by using it instead of an IDE for writing code. It isn't reasoning and understanding about complex systems that you gain from living in a terminal. You gain efficiency, flexibility, and nerd cred - all valuable, but none of them are systems thinking.
The auto-complete point in the post is particularly ironic given how critical it is for terminal users and that most vim users also rely heavily on auto-complete. Auto-complete does not limit your effectiveness, it's provably the opposite.
That you for mentioning that. I have often argued with people in favour of my approach (home ed so I got to choose how to teach my kids from about 9 to 16) of not doing things like memorising times tables and learning arithmetic techniques like long division.
It's all-round horrible advice. Once you have developed an understanding of 'fundamental operations', such as code formatting and file operations — and, realistically, you will already have done so if you are doing any programming — the next step is to automate them so that they take no time or mental energy, leaving you to work on things that matter. IDEs help with that.
Incidentally, the reason the tabs vs. spaces debate has died down is the proliferation of autoformatting. It really doesn't matter once you don't have to spend your precious time manually aligning code.
It is for many problems, especially concurrency related ones, much less powerful than trace points. But the issue I have seen is that some tools like gdb have unergonomic support for tracing so there I tend to use break points or printf debugging just because the tracing support is so bad in gdb.
I'm quite surprised to see the need to debug a live server here. I'm of the belief that the need to repro a problem locally and using a debugger lead to better understanding. SSHing into boxen feels like a cowboy behaviour on a modern stack - it shouldn't be necessary with competent observability and unit tests.
Not all environments are equal. Some vendor systems have basically non-existent debugging capabilities that end up dumping you into the wild west when things go wrong.
I have worked with more than one Fintech that provides no test systems/debugging capabilities and have spent time on calls with their developers as we walk through production logs. Not fun.
Sometimes you need to debug the observability stuff a little.
As a general rule, ssh'ing into prod is a terrible idea. Getting into a pre-prod box to figure out why metrics aren't getting pushed and trying something quickly before you go back to making the changes you need to push into the repo, less so.
I see that regularly at startups or other environments where the developers aren't necessarily professional software people (especially ML people!) The update-run-debug cycle is how they think and operate, at every level including on prod servers. Moving beyond that tends to require quite a bit of knowledge and infrastructure, and which infrastructure you need also requires knowledge.
For me, the friction of VS Code is more cognitive than computational. I call it the "searching with your eyes" [0] problem. To make it clear, I've no problems with VSCode but haven't used it in a long time -- maybe it has added some keyboard-only features that makes workflow smoother.
VS Code's heavy reliance on the file explorer tree forces you to constantly visually scan nested directories to navigate. When I switched to Neovim (with Telescope/jump lists), I moved from visual scanning to mental mapping. I don't look for where a file is; I type what the file is. It sounds subtle, but removing that micro-latency of "eye-to-mouse-to-tree" keeps you in the flow state much longer.
All IDEs including VSCode have fuzzy-finding for files, and fuzzy-finding for symbols as well. Between these, I never find myself using the file tree, except when it's the best tool for the job ("what other files are in this directory?", file tree manipulation (which IDEs recognize you doing, adjusting imports for you!) etc.).
I actually notice how this pattern is very fast, but I lose a code base's mental map. Coworkers might take longer to open any individual file but have a much better idea of repo layout as a whole. That makes them effective otherwise.
I have worked in monorepos for large codebases. In those, file trees are completely useless because you can't fit the repo layout to your mind. Also, the file trees are so large that when I'd ask a coworker using VSCode to open a file, they'd usually take a few seconds trying to locate it (on remote ssh, it even takes a bit to load files to expand directory as well).
For smaller code bases, I usually read the repo first and I'm able to learn what exists while working through it.
VSCode doesn't heavily rely on the file explorer, that is personal preference. I use its jump to file far more than the explorer, both by filename, by reference jump and by "dumb" jump, a plugin that does simple reference jump with rg. That jump by reference just works now in VSCode for all the languages I use puts it ahead of neovim which requires a bit of fiddling to get going.
That exists, though it doesn't have a preview of the file. Also, jump lists to quickly take a look and ctrl+o to go back is a huge game changer for me. Not sure if VSCode supports that now, haven't used it in a long time.
Part of me thinks that in 2026 (and onwards), I should make the most of the M4 processor I have in my hands, the GPUs and superb screen I will always have access to, and have a programming environment that is absolutely dripping in luxury baubles compared to what I started out with in the 1990s.
And then I frequently throw open a terminal and start up tmux with neovim in one window and a command line for git and the like in another.
There is something about understanding the tools and the process, the author is kind of right there, but also, there is just something about the ergonomics and speed of it all. There is more flexibility to extend easily, to customise, to make my environment fit using these more "primitive" tools than there is in taking an opinionated stack somebody else has designed.
> When VS Code formats your code, you don't learn your language's style conventions
Lmao, what is this argument. `go format`, `prettier`, `ktfmt`, `ruff|black` is what you should know, not minutiae of where to put a line break.
> When it handles Git conflicts, you don't learn proper merge strategies
Such as?
> When it manages your build process, you don't learn your build tools
That's what infra team is for. I've seen "build process" written by those who "learned" their build tools – leave it to professionals.
> When it auto-imports modules, you don't learn your project's structure
???
The rest is similar bollocks. If you're at the start of the career – do not listen to advice in the article. You can do it for curiosity, but don't think it'll make you "a better programmer". And I say this as a terminal first dev who uses vi/vi-mode everywhere.
Use that VS Code, depend on that Intellij. Learn them through and through – this will make you a much better developer rather than cobbling together a thrift-store IDE.
I don't necessarily agree with your thrift store take, I understand making a great personalised ide with vim or emacs. But I do agree with you that all the other points make no sense. VSCode doesn't solve your merges for you any more than vim does, the resolve tooling is very similar. VSCode doesn't do the build for you either.
Not that the arguments are completely invalid, but they’re not particularly convincing either.
> You're letting the IDE think for you instead of building a deep understanding…
That’s not specific to VS Code, you can say that about any IDE. The headline made me expect arguments specifically against VS Code. I want my 10 minutes back.
I've moved to VS Code after almost 20 years of Emacs. Couldn't been happier.
Spent a little time hacking hotkeys to match my Emacs muscle memory and that's mostly it.
Now I have a debugger that's actually easy to use, ability to run the test case under the cursor in one click and support for Jupyter Notebooks.
However, still missing tab completion.
You can clean up git diffs a lot, I personally find them easy to ready anyway, with tools like delta[1] which make things super nice to read. Also if you use a text editor such as neovim you can integrate these things into your editor and get beautiful diffs right there.
That said I do not use neovim or delta, I just use git diffs or my language ide's diff features.
> I personally find them easy to ready anyway, with tools like delta[1] which make things super nice to read. Also if you use a text editor such as neovim you can integrate these things into your editor and get beautiful diffs right there.
All I can see here is “if I use two extra tools, I can almost have as good an experience as vscode (or IntelliJ or whatever) gives me out of the box”.
You mean adding a few lines to a config file once and never think about it again? Some people don’t want to have to deal with why they see as a load of bloated ‘features’, preferring instead to just focus on the task at hand, and that’s okay.
The article is as misguided as the snarky pushback. Let people work however they’re most comfortable and productive, why does it have to be a purity contest?
Don’t forget installing _and discovering_ those tools.
> The article is as misguided as the snarky pushback. Let people work however they’re most comfortable and productive, why does it have to be a purity contest?
Absolutely agree on it not being a purity contest. The article deserves pushback _because_ it’s arguing for purity
TL/DR: I strongly encourage you to understand the fundamentals and not view all of our tools as black boxes, but once you have an understanding of the tools and the various layers of abstraction, feel free to use them to boost your productivity and output.
---
This is equivalent to saying "to understand wood working, do not use power tools, use hand tools to understand the wood and the process."
Sure, if you want to artisan woodworking, sure skip power tools or at least try it for a while to get a deeper understanding.
It is no different than saying that programming languages hide the subtleties of the hardware and we should be using assembly.
But once you understand the fundamentals, if you want to get a lot done at low cost (e.g. a professional who delivers at scale), you definitely need to use the power tools (e.g. high level abstractions/automations) that boost productivity.
git on the command line is the power tool. The VS Code plugin is the training wheels version.
These tools the TFA discuss are powerful, but have a learning curve. VS Code has a flatter learning curve, but it's up to you to decide if they are abstracting away things you actually need to understand.
All abstractions serve a purpose, but they're also always leaky. To extend your assembler analogy: sometimes you actually do need to understand what's happening on the stack and the heap, most people never do.
Use what works for you, but don't think that abstractions will be enough for every scenario, sometimes you're going to need to get under the hood and go deep, and if all you ever do is hand-wave it away and hope your IDE/framework/chosen programming language interpreter or compiler is going to just "sort it out" for you... well, good luck with that, and I hope it works out for you. It's just not my lived experience after 30+ years in the industry.
> git on the command line is the power tool. The VS Code plugin is the training wheels version.
I don't disagree with your underlying point, but git is perhaps the worst example. It is a horrible tool in several ways. Powerful yes, but it pays too large a price in UX.
I've only ever used git through the CLI as well, but having switched to jujutsu (also CLI) I am not going back. It is quite eye-opening how much simpler git should be, for the average user (I realize "average user" is doing some heavy-lifting here -- git covers an enormous number of diverse use cases).
What jujutsu-CLI is for me (version control UX that just works) might be VSCode's GUI git integration for other people, or magit, or GitButler, or whatever other GUI or TUI.
Who cares about training wheels? If the real deal is a unicycle with one pedal and no saddle, I will keep using training wheels, thank you very much.
"You should not let your IDE do the thinking for you"
As a solo entrepreneur, if something enables me to execute faster, I'll gladly use it. Articles like this only remind me to never (again) hire expensive, pedantic, over-principled and cynical engineers.
I think they have some good points (having a deep understanding of tools you use), but I think the path they take achieve those results is misguided.
A stupid example off the top of my head: I use VSCode and often I'll use the integrated git commit feature. But if need to bisect, rebase, merge, or edit a commit, I will just use the CLI. I don't feel like using the commit GUI makes me worse at using git.
All in all, I think the author thinks that familiarity with one tool makes people worse at another similar tool, but I don't think that's the necessarily the case. At worst, memory might fade if the other tool isn't used, but that's fine, it's clearly not used often. As an analogy: if I don't speak German every day, I don't need to be fluent in German either.
Strange. Articles like this remind me never to hire vibe coding brogrammers who have no idea about basics such as cp, mv, find etc. Usually they leave behind a mess which soon breaks.
The cynical and pedantic engineers however, do excellent work, and their software never breaks. It takes longer, you pay a bit more, but it is worth every cent.
And using an IDE that enables you to work faster, doesn't mean you can't learn basic shell commands. Or learn the fundamentals behind the technology you use. Just like pedantic engineers are no guarantee for code that doesn't break.
Title is nonsense, content is weak. Many people who use VS Code (me included) probably ignore the features that are supposedly a problem, such as built-in SSH. The idea that basic autocomplete is bad for you is for the birds.
In my previous work, a few folks in my team used VSCode on a shared dev box. The box has 1TB memory, and we'd frequently OOM due to vscode servers taking up tens of GBs of memory (which adds up quickly when there are multiple vscode windows per person). Sometimes it'd eat as big as 100GB until it had to be restarted. Sure, big codebases, but that's just straight unacceptable.
C++ (clangd) and Python (pyright and ruff). But I think the excessive memory usage came from huge number of files in the code base, plus some really large files (given I ran LSP on neovim too with much smaller footprints).
VSCode over SSH is one of the best ways to develop on various SBCs. You can run the code on the SBC while having a high powered editor experience on your main machine.
The title should be more like "Juniors shouldn't rely entirely on VS Code." The author wrote:
> "I've seen countless junior developers freeze when their IDE isn't available or when they need to work on a remote server."
This is a valid point: juniors are limiting themselves if they rely on an IDE for everything, to the point of not being able to perform coding-related operations from the terminal effectively, or not even being aware of what the IDE is doing for them.
But once you have that knowledge, using an IDE tends to make a lot of sense. That also allows you to make an informed choice about which operations make sense in an IDE vs. the terminal.
Also VS Code has a good integrated terminal, so it's not an entirely either-or choice. Some of the new AI coding assistants integrate terminal operations with VS Code very well. The real advice should be learn both.
It's a code editor. It's not that much more complex than vim. It doesn't do magic to your codebase that makes development different. I've written plugins for vim, neovim and VSCode... VSCode at least has well documented interfaces for everything (edit: well ok not everything, there are some difficult gaps in the docs), and it's pretty clear how things work under the hood. Neovim is fine too, lua is nice. Vim plugins I didn't enjoy much.
IDE itself is good, "convenience" is benefit and not a sin - but performance and RAM usage needs to be better. And that is only done by throwing webstack into a dump
It's not actually that bad though. I do remember the days when VSCode would often be the problem app, but not for a couple of years now. Sometimes a plugin runs a process that causes an issue... but the same happens with neovim, its the curse of any editor with plugins.
Very weak article. I do all of these things in the terminal not because they’re better, but because of muscle memory. I’m under no illusions that me typing my git commands by hand makes me a better programmer. I didn’t become one with the machine.
For junior devs: don’t worry about which tools you use. Ultimately make sure that what you’re shipping is tested and reliable. Make sure of it before sending it for review and you’ll be fine. You don’t need to mess around in neovim to prove anything to anyone.
I've had a color scheme plugin yanked from my IDE a while back, as it went malicious (Material Theme). It's just a bunch of hex codes, how is that even possible? Baffling and disappointing indeed.
Every VSCode (Neo)Vim plugin I’ve tried (most, if not all of them) is a janky mess of random missing features and/or broken state handling. They’ve all felt like a worse experience than just doing things the ‘normal’ VSCode way.
You are trying very niche plugins then... my experience has been superb for almost 10 years now. Recently I started using LazyVim by folke which I think is a really polished experience as well. Worth trying out if you don't like the regular plugin workflow.
That name rings a bell, I recall trying it but I’ll give it another go next time I find myself opening vsc, cheers!. Most of the time I just use VSCode as a visual debugger but it’d be nice to make minor changes without making typos due to vim-brain muscle memory.
Edit: just looked up LazyVim and it seems to just be a prebuilt neovim config atop the VSCode-Neovim extension which was one of the aforementioned janky experiences (IIRC undo stack wasn’t shared with VSCode and would get out of sync). I think I tried it as a last ditch effort because someone else said that it’ll fix VSCode-Neovim plugin deficiencies but I ended up just going back to my simple but effective neovim config and using VSCode as a visual debugger. I’ll give it another go if you reckon it’s much better though.
>Look up a Git command instead of clicking a button
>You're building real, transferable skills that make you a better programmer.
I'm convinced that the only reason that people think git is complicated, is because of the incredibly widespread elitist attitudes around using a GUI for git
This is a hot take, but a GUI for git is strictly better (unless you're scripting). You can do incredibly complicated operations at the click of a button, far more safely than you can through the CLI
But even then, the idea that you actually learn anything by using the CLI is just not true. The longest running meme with git is that people just learn a few commands to copypaste in without actually remembering anything. You stick to your tiny niche because you don't know what's actually happening nor is it possible for a human being to truly remember all of the syntax: This meme exists for a reason https://xkcd.com/1597/
Git via a GUI gives you the freedom to actually use all of git. You learn how git actually works, all the power of it - how to merge complex things, and you can create really nice workflows that are powerful and easy to use. You come out of using the GUI for a while with a strong understanding of what git is, not what the git CLI is. The skill I care about is the former
The CLI teaches you nothing by virtue of it being a CLI. All you learn via the CLI specifically is the ability to type accurately without making mistakes, and gain a strong fear of hitting enter. The underlying concepts are the important skill, and you absolutely do learn those via a GUI - much more effectively without the hard wall of an archaic CLI interface in the way
I don't trust devs who can't operate outside their IDE. Maybe I'm just old fashioned, but it reminds me of useless Enterprise Java drones who are helpless without Eclipse and can't debug anything.
From the embedded systems end, VSCode really feels like the new Eclipse.
For decades embedded CPU companies would look at visual studio and say, "Boy howdee if we only had visual studio for our chips!" But they wouldn't be willing to put in the effort to do so, so they'd start with Eclipse, and the C/C++ plugin, and hack in a JTAG interface, and maybe a few code generators to pin out the hardware and say, look at us we made an IDE! And that IDE sucked, not because of eclipse, but because nobody actually put the work in to make it useful. You'd get lime breakpoints but not memory breakpoints or function breakpoints. You'd get a call stack but no way to inspect your RTOS. Every chip vendor did it themselves, so every tool was wildly different even for a big standard ARM core.
VSCode for embedded is the same thing, just in JavaScript. With AI!
While this issue is up, I've recently been looking for an alternative to vscode for personal use because it runs so slow now with a few other programs running in the background. My main requirement is copy paste needs to be ctrl+c, ctrl+v and text selection needs to be ctrl shift + arrow keys or some combination of those. Using geany for a week or so hasn't been terrible but its not great either.
No thank you...
One of the primary things shells are supposed to excel at is file system navigation and manipulation, but the experience is horrible. I can never get `cp`, `rsync`, `mv`, `find` right without looking them up, despite trying to learn. It's way too easy to mess up irreversibly and destructively.
One example is flattening a directory. You accidentally git-cloned one too deep, into `some/dir/dir/` and want to flatten contents to `some/dir/`, deleting the then-empty `some/dir/dir/`. Trivial and reversible in any file manager, needlessly difficult in a shell. I get it wrong all the time.
Similarly, iterating over a list of files (important yet trivial). `find` is arcane in its invocation, differs between Unix flavors, you will want `xargs` but `{}` substitution is also very error-prone. And don't forget `print0`! And don't you even dare `for f in *.pdf`, it will blow up in more ways than you can count. Also prepare to juggle quotes and escapes and pray you get that right. Further, bash defaults are insane (pray you don't forget `set -euo pipefail`).
How can we be failed by our tools so much, for these use cases? Why aren't these things trivial and safe?
I agree that certain commands require some effort to learn, but I would not include `cp` or `mv` in that list.
I have trouble gauging the effects of `*`, aka "will I cp/mv the dir or all contents of the dir"? Then shell expansion getting in the way, like expanding it all ("argument list too long"). I try to use rsync when possible, where intermittent `.` in paths are relevant, as well as trailing slashes... and don't forget `-a`! Then I forget if those same things apply to cp/mv. Then I cp one directory too deep and need to undo the mess -- no CTRL+Z!
The wide-spread use of `rm -rf some-ostensibly-empty-dir/` is also super dangerous, when `rm -r` or even `rmdir` would suffice, but you need to remember those exist. I find it strange there's no widely (where applicable) available `rm-to-trash`, which would be wildly safer and is table stakes for Desktop work otherwise.
Then there's `dd`...
I use terminals a lot, but a GUI approach (potentially with feedback pre-operation) plus undo/redo functionality for file system work is just so much easier to work with. As dumb as drag-and-drop with a mouse is, a single typo can't wreck your day.
If using dd for messing with filesystems and partitions, then I don't know how much more a gui will save you. Its an inherently scary task that needs some thinking first. Personally, that stuff always scares me gui or not.
What is there to get wrong in your flattening dir example? I'd mv the internal dir as some other name to outside say dir2, them rm rf outer and mv the dir2. Unless there is something wrong in this approach.
I would agree with the rest, I always have to look up find and xargs syntax.
If you make a typo, it'll go wrong. This is something that file managers fundamentally do not suffer from when trying to do that operation
You've never mis-dragged something in the GUI or had a flaky mouse button which lets up randomly while you're dragging which left your folder "somewhere" that you now have to find?
Most of the commands you've mentioned have worked fairly well for me. Are you sure you're looking up cp, mv and find every time before using them? Sounds pretty weird.
With fish, `for f in *.pdf` Just Works™.
This is also a crutch. Take the time to learn the kludgier tool. It will make you a better developer.
/s (I'm a big fan of fish)
Same with zsh
mv --interactive
cp --interactive
rm --interactive
LLMs make all those commands trivial to learn. Back in the day we had to study whole man pages meant as reference. Like keeping attention for minutes at a time. The horror!
You read the manpages once and then if you're some super elite user you create some aliases for yourself.
Or if you are me, you do `history | grep name-of-command` to find the last time you used it and edit that haha
You’re gonna love ctrl-r name-of-command
Research on calculator use in early math education (notably the Hembree & Dessart meta-analysis of 79 studies) found that students given calculators performed better at math - including on paper-and-pencil tests without calculators. The hypothesis is that calculators handle computation, freeing cognitive bandwidth and time for problem-solving and conceptual understanding. Problem solving and higher level concepts matter far more than memorizing multiplication and division tables.
I think about this often when discussing AI adoption with people. It's also relevant to this VS Code discussion which is tangential to the broader AI assisted development discussion. This post conflates tool proficiency with understanding. You can deeply understand Git's DAG model while never typing git reflog. Conversely, you can memorize every terminal command and still design terrible systems.
The scarce resource for most developers isn't "knows terminal commands" - it's "can reason about complex systems under uncertainty." If a tool frees up bandwidth for that, that's a net win. Not to throw shade at hyper efficient terminal users, I live in the terminal and recommend it, but it isn't going to make you a better programmer just by using it instead of an IDE for writing code. It isn't reasoning and understanding about complex systems that you gain from living in a terminal. You gain efficiency, flexibility, and nerd cred - all valuable, but none of them are systems thinking.
The auto-complete point in the post is particularly ironic given how critical it is for terminal users and that most vim users also rely heavily on auto-complete. Auto-complete does not limit your effectiveness, it's provably the opposite.
That you for mentioning that. I have often argued with people in favour of my approach (home ed so I got to choose how to teach my kids from about 9 to 16) of not doing things like memorising times tables and learning arithmetic techniques like long division.
This is a well-thought-out critique. Thanks for sharing your insights.
It's all-round horrible advice. Once you have developed an understanding of 'fundamental operations', such as code formatting and file operations — and, realistically, you will already have done so if you are doing any programming — the next step is to automate them so that they take no time or mental energy, leaving you to work on things that matter. IDEs help with that.
Incidentally, the reason the tabs vs. spaces debate has died down is the proliferation of autoformatting. It really doesn't matter once you don't have to spend your precious time manually aligning code.
> Try debugging without breakpoints
Why would you need to give this up? I use breakpoints with terminal debuggers all the time.
Yea this take makes no sense. What in the world is wrong with debugging with breakpoints?
It is for many problems, especially concurrency related ones, much less powerful than trace points. But the issue I have seen is that some tools like gdb have unergonomic support for tracing so there I tend to use break points or printf debugging just because the tracing support is so bad in gdb.
It’s a particular subcategory of cork sniffing where you pick the hardest, dumbest way to do things because you’re a Real Developer
It actually said
> Debug your code without visual breakpoints
With ‘visual’ being the important aspect.
There's another section below your quote where the author also wrote:
The alternative to breakpoints is to study the output logs. He wrote:Fair, I didn’t read that far as I got bored of the “thou shalt” nature of the thing.
Tbh it's the default way I start my app in, debug mode xD
I'm quite surprised to see the need to debug a live server here. I'm of the belief that the need to repro a problem locally and using a debugger lead to better understanding. SSHing into boxen feels like a cowboy behaviour on a modern stack - it shouldn't be necessary with competent observability and unit tests.
Not all environments are equal. Some vendor systems have basically non-existent debugging capabilities that end up dumping you into the wild west when things go wrong.
I have worked with more than one Fintech that provides no test systems/debugging capabilities and have spent time on calls with their developers as we walk through production logs. Not fun.
Sometimes you need to debug the observability stuff a little.
As a general rule, ssh'ing into prod is a terrible idea. Getting into a pre-prod box to figure out why metrics aren't getting pushed and trying something quickly before you go back to making the changes you need to push into the repo, less so.
I see that regularly at startups or other environments where the developers aren't necessarily professional software people (especially ML people!) The update-run-debug cycle is how they think and operate, at every level including on prod servers. Moving beyond that tends to require quite a bit of knowledge and infrastructure, and which infrastructure you need also requires knowledge.
For me, the friction of VS Code is more cognitive than computational. I call it the "searching with your eyes" [0] problem. To make it clear, I've no problems with VSCode but haven't used it in a long time -- maybe it has added some keyboard-only features that makes workflow smoother.
VS Code's heavy reliance on the file explorer tree forces you to constantly visually scan nested directories to navigate. When I switched to Neovim (with Telescope/jump lists), I moved from visual scanning to mental mapping. I don't look for where a file is; I type what the file is. It sounds subtle, but removing that micro-latency of "eye-to-mouse-to-tree" keeps you in the flow state much longer.
[0] https://barish.me/blog/stop-searching-with-your-eyes/
All IDEs including VSCode have fuzzy-finding for files, and fuzzy-finding for symbols as well. Between these, I never find myself using the file tree, except when it's the best tool for the job ("what other files are in this directory?", file tree manipulation (which IDEs recognize you doing, adjusting imports for you!) etc.).
I actually notice how this pattern is very fast, but I lose a code base's mental map. Coworkers might take longer to open any individual file but have a much better idea of repo layout as a whole. That makes them effective otherwise.
I have worked in monorepos for large codebases. In those, file trees are completely useless because you can't fit the repo layout to your mind. Also, the file trees are so large that when I'd ask a coworker using VSCode to open a file, they'd usually take a few seconds trying to locate it (on remote ssh, it even takes a bit to load files to expand directory as well).
For smaller code bases, I usually read the repo first and I'm able to learn what exists while working through it.
VSCode doesn't heavily rely on the file explorer, that is personal preference. I use its jump to file far more than the explorer, both by filename, by reference jump and by "dumb" jump, a plugin that does simple reference jump with rg. That jump by reference just works now in VSCode for all the languages I use puts it ahead of neovim which requires a bit of fiddling to get going.
Don’t you just press ctrl p and type in vscode?
That exists, though it doesn't have a preview of the file. Also, jump lists to quickly take a look and ctrl+o to go back is a huge game changer for me. Not sure if VSCode supports that now, haven't used it in a long time.
It has jump previews and yea ctrl+o works
Neat! Does it also preview files when doing fuzzy file or symbol search?
I don't believe so, built in, because I see some extensions for adding it.
in an age where junior engineers are no longer _reading code_ due to LLMs, VSCode isn't exactly the worst offender
I flip flop on this a bit.
Part of me thinks that in 2026 (and onwards), I should make the most of the M4 processor I have in my hands, the GPUs and superb screen I will always have access to, and have a programming environment that is absolutely dripping in luxury baubles compared to what I started out with in the 1990s.
And then I frequently throw open a terminal and start up tmux with neovim in one window and a command line for git and the like in another.
There is something about understanding the tools and the process, the author is kind of right there, but also, there is just something about the ergonomics and speed of it all. There is more flexibility to extend easily, to customise, to make my environment fit using these more "primitive" tools than there is in taking an opinionated stack somebody else has designed.
> This deeper understanding makes you a more capable programmer because you know exactly what's happening under the hood.
No.
> In these situations, your VS Code knowledge won't help you.
https://code.visualstudio.com/docs/remote/ssh
> When VS Code formats your code, you don't learn your language's style conventions
Lmao, what is this argument. `go format`, `prettier`, `ktfmt`, `ruff|black` is what you should know, not minutiae of where to put a line break.
> When it handles Git conflicts, you don't learn proper merge strategies
Such as?
> When it manages your build process, you don't learn your build tools
That's what infra team is for. I've seen "build process" written by those who "learned" their build tools – leave it to professionals.
> When it auto-imports modules, you don't learn your project's structure
???
The rest is similar bollocks. If you're at the start of the career – do not listen to advice in the article. You can do it for curiosity, but don't think it'll make you "a better programmer". And I say this as a terminal first dev who uses vi/vi-mode everywhere.
Use that VS Code, depend on that Intellij. Learn them through and through – this will make you a much better developer rather than cobbling together a thrift-store IDE.
I don't necessarily agree with your thrift store take, I understand making a great personalised ide with vim or emacs. But I do agree with you that all the other points make no sense. VSCode doesn't solve your merges for you any more than vim does, the resolve tooling is very similar. VSCode doesn't do the build for you either.
Not that the arguments are completely invalid, but they’re not particularly convincing either.
> You're letting the IDE think for you instead of building a deep understanding…
That’s not specific to VS Code, you can say that about any IDE. The headline made me expect arguments specifically against VS Code. I want my 10 minutes back.
I've moved to VS Code after almost 20 years of Emacs. Couldn't been happier.
Spent a little time hacking hotkeys to match my Emacs muscle memory and that's mostly it.
Now I have a debugger that's actually easy to use, ability to run the test case under the cursor in one click and support for Jupyter Notebooks. However, still missing tab completion.
I follow using Emacs, but for debug and AI.
Using both is not so bad.
The focus on VS Code is a bit confusing. The author seems to have an issue with juniors relying IDEs as a crutch in general.
Ugh a terminal purist. Just as insufferable as the ones in person at work. Yeah have fun with your gigantic unorganized git diffs I guess.
You can clean up git diffs a lot, I personally find them easy to ready anyway, with tools like delta[1] which make things super nice to read. Also if you use a text editor such as neovim you can integrate these things into your editor and get beautiful diffs right there.
That said I do not use neovim or delta, I just use git diffs or my language ide's diff features.
[1]: https://github.com/dandavison/delta
> I personally find them easy to ready anyway, with tools like delta[1] which make things super nice to read. Also if you use a text editor such as neovim you can integrate these things into your editor and get beautiful diffs right there.
All I can see here is “if I use two extra tools, I can almost have as good an experience as vscode (or IntelliJ or whatever) gives me out of the box”.
You mean adding a few lines to a config file once and never think about it again? Some people don’t want to have to deal with why they see as a load of bloated ‘features’, preferring instead to just focus on the task at hand, and that’s okay.
The article is as misguided as the snarky pushback. Let people work however they’re most comfortable and productive, why does it have to be a purity contest?
Don’t forget installing _and discovering_ those tools.
> The article is as misguided as the snarky pushback. Let people work however they’re most comfortable and productive, why does it have to be a purity contest?
Absolutely agree on it not being a purity contest. The article deserves pushback _because_ it’s arguing for purity
TL/DR: I strongly encourage you to understand the fundamentals and not view all of our tools as black boxes, but once you have an understanding of the tools and the various layers of abstraction, feel free to use them to boost your productivity and output.
---
This is equivalent to saying "to understand wood working, do not use power tools, use hand tools to understand the wood and the process."
Sure, if you want to artisan woodworking, sure skip power tools or at least try it for a while to get a deeper understanding.
It is no different than saying that programming languages hide the subtleties of the hardware and we should be using assembly.
But once you understand the fundamentals, if you want to get a lot done at low cost (e.g. a professional who delivers at scale), you definitely need to use the power tools (e.g. high level abstractions/automations) that boost productivity.
Wrong way round.
git on the command line is the power tool. The VS Code plugin is the training wheels version.
These tools the TFA discuss are powerful, but have a learning curve. VS Code has a flatter learning curve, but it's up to you to decide if they are abstracting away things you actually need to understand.
All abstractions serve a purpose, but they're also always leaky. To extend your assembler analogy: sometimes you actually do need to understand what's happening on the stack and the heap, most people never do.
Use what works for you, but don't think that abstractions will be enough for every scenario, sometimes you're going to need to get under the hood and go deep, and if all you ever do is hand-wave it away and hope your IDE/framework/chosen programming language interpreter or compiler is going to just "sort it out" for you... well, good luck with that, and I hope it works out for you. It's just not my lived experience after 30+ years in the industry.
> git on the command line is the power tool. The VS Code plugin is the training wheels version.
I don't disagree with your underlying point, but git is perhaps the worst example. It is a horrible tool in several ways. Powerful yes, but it pays too large a price in UX.
I've only ever used git through the CLI as well, but having switched to jujutsu (also CLI) I am not going back. It is quite eye-opening how much simpler git should be, for the average user (I realize "average user" is doing some heavy-lifting here -- git covers an enormous number of diverse use cases).
What jujutsu-CLI is for me (version control UX that just works) might be VSCode's GUI git integration for other people, or magit, or GitButler, or whatever other GUI or TUI.
Who cares about training wheels? If the real deal is a unicycle with one pedal and no saddle, I will keep using training wheels, thank you very much.
> well, good luck with that, and I hope it works out for you. It's just not my lived experience after 30+ years in the industry.
Same level of experience I have btw.
"You should not let your IDE do the thinking for you"
As a solo entrepreneur, if something enables me to execute faster, I'll gladly use it. Articles like this only remind me to never (again) hire expensive, pedantic, over-principled and cynical engineers.
I think they have some good points (having a deep understanding of tools you use), but I think the path they take achieve those results is misguided.
A stupid example off the top of my head: I use VSCode and often I'll use the integrated git commit feature. But if need to bisect, rebase, merge, or edit a commit, I will just use the CLI. I don't feel like using the commit GUI makes me worse at using git.
All in all, I think the author thinks that familiarity with one tool makes people worse at another similar tool, but I don't think that's the necessarily the case. At worst, memory might fade if the other tool isn't used, but that's fine, it's clearly not used often. As an analogy: if I don't speak German every day, I don't need to be fluent in German either.
This, this and this. Having a person who constantly nags juniors about "true engineering" is such a morale killer.
Strange. Articles like this remind me never to hire vibe coding brogrammers who have no idea about basics such as cp, mv, find etc. Usually they leave behind a mess which soon breaks.
The cynical and pedantic engineers however, do excellent work, and their software never breaks. It takes longer, you pay a bit more, but it is worth every cent.
Using VS Code !== Vibe coding
And using an IDE that enables you to work faster, doesn't mean you can't learn basic shell commands. Or learn the fundamentals behind the technology you use. Just like pedantic engineers are no guarantee for code that doesn't break.
Title is nonsense, content is weak. Many people who use VS Code (me included) probably ignore the features that are supposedly a problem, such as built-in SSH. The idea that basic autocomplete is bad for you is for the birds.
VSCode over SSH kinda rocks honestly. I use it with my server all the time.
In my previous work, a few folks in my team used VSCode on a shared dev box. The box has 1TB memory, and we'd frequently OOM due to vscode servers taking up tens of GBs of memory (which adds up quickly when there are multiple vscode windows per person). Sometimes it'd eat as big as 100GB until it had to be restarted. Sure, big codebases, but that's just straight unacceptable.
What are you doing such that it uses tens of GB...? Vscode is bloated, but not THAT bloated...
Which language/plugins?
C++ (clangd) and Python (pyright and ruff). But I think the excessive memory usage came from huge number of files in the code base, plus some really large files (given I ran LSP on neovim too with much smaller footprints).
VSCode over SSH is one of the best ways to develop on various SBCs. You can run the code on the SBC while having a high powered editor experience on your main machine.
It's the primary way I work on remote servers. Takes a few seconds to start up, but then it's just as if I'm working locally.
The title should be more like "Juniors shouldn't rely entirely on VS Code." The author wrote:
> "I've seen countless junior developers freeze when their IDE isn't available or when they need to work on a remote server."
This is a valid point: juniors are limiting themselves if they rely on an IDE for everything, to the point of not being able to perform coding-related operations from the terminal effectively, or not even being aware of what the IDE is doing for them.
But once you have that knowledge, using an IDE tends to make a lot of sense. That also allows you to make an informed choice about which operations make sense in an IDE vs. the terminal.
Also VS Code has a good integrated terminal, so it's not an entirely either-or choice. Some of the new AI coding assistants integrate terminal operations with VS Code very well. The real advice should be learn both.
Another blog advocate for learning how to make fire with sticks and stones.
Interesting survival skill, in case of armageddon or when camping in the wild, yet most folks will do just fine with matches and lighters.
Notepad = making fire with sticks and stones
Vim/Neovim = making fire with matches and lighters
VS Code = making fire with a magic box that weighs 60 kg, you don’t understand how it works and it could randomly stop working at any time
It's a code editor. It's not that much more complex than vim. It doesn't do magic to your codebase that makes development different. I've written plugins for vim, neovim and VSCode... VSCode at least has well documented interfaces for everything (edit: well ok not everything, there are some difficult gaps in the docs), and it's pretty clear how things work under the hood. Neovim is fine too, lua is nice. Vim plugins I didn't enjoy much.
Vim/Neovim = cutting down wood and chemistry for the matches, molding plastic and metal for the lighters.
no, we need to ditch *Javascript* in VS Code
IDE itself is good, "convenience" is benefit and not a sin - but performance and RAM usage needs to be better. And that is only done by throwing webstack into a dump
It's not actually that bad though. I do remember the days when VSCode would often be the problem app, but not for a couple of years now. Sometimes a plugin runs a process that causes an issue... but the same happens with neovim, its the curse of any editor with plugins.
Very weak article. I do all of these things in the terminal not because they’re better, but because of muscle memory. I’m under no illusions that me typing my git commands by hand makes me a better programmer. I didn’t become one with the machine.
For junior devs: don’t worry about which tools you use. Ultimately make sure that what you’re shipping is tested and reliable. Make sure of it before sending it for review and you’ll be fine. You don’t need to mess around in neovim to prove anything to anyone.
Not to mention its extremely insecure plugin architecture.
I've had a color scheme plugin yanked from my IDE a while back, as it went malicious (Material Theme). It's just a bunch of hex codes, how is that even possible? Baffling and disappointing indeed.
It gets even worse when you realize most extensions ship bundled node_modules and are a very juicy target for supply chain attacks.
Is the author aware of the vim plugin?
Every VSCode (Neo)Vim plugin I’ve tried (most, if not all of them) is a janky mess of random missing features and/or broken state handling. They’ve all felt like a worse experience than just doing things the ‘normal’ VSCode way.
You are trying very niche plugins then... my experience has been superb for almost 10 years now. Recently I started using LazyVim by folke which I think is a really polished experience as well. Worth trying out if you don't like the regular plugin workflow.
That name rings a bell, I recall trying it but I’ll give it another go next time I find myself opening vsc, cheers!. Most of the time I just use VSCode as a visual debugger but it’d be nice to make minor changes without making typos due to vim-brain muscle memory.
Edit: just looked up LazyVim and it seems to just be a prebuilt neovim config atop the VSCode-Neovim extension which was one of the aforementioned janky experiences (IIRC undo stack wasn’t shared with VSCode and would get out of sync). I think I tried it as a last ditch effort because someone else said that it’ll fix VSCode-Neovim plugin deficiencies but I ended up just going back to my simple but effective neovim config and using VSCode as a visual debugger. I’ll give it another go if you reckon it’s much better though.
>Every time you:
>Look up a Git command instead of clicking a button
>You're building real, transferable skills that make you a better programmer.
I'm convinced that the only reason that people think git is complicated, is because of the incredibly widespread elitist attitudes around using a GUI for git
This is a hot take, but a GUI for git is strictly better (unless you're scripting). You can do incredibly complicated operations at the click of a button, far more safely than you can through the CLI
But even then, the idea that you actually learn anything by using the CLI is just not true. The longest running meme with git is that people just learn a few commands to copypaste in without actually remembering anything. You stick to your tiny niche because you don't know what's actually happening nor is it possible for a human being to truly remember all of the syntax: This meme exists for a reason https://xkcd.com/1597/
Git via a GUI gives you the freedom to actually use all of git. You learn how git actually works, all the power of it - how to merge complex things, and you can create really nice workflows that are powerful and easy to use. You come out of using the GUI for a while with a strong understanding of what git is, not what the git CLI is. The skill I care about is the former
The CLI teaches you nothing by virtue of it being a CLI. All you learn via the CLI specifically is the ability to type accurately without making mistakes, and gain a strong fear of hitting enter. The underlying concepts are the important skill, and you absolutely do learn those via a GUI - much more effectively without the hard wall of an archaic CLI interface in the way
I don't trust devs who can't operate outside their IDE. Maybe I'm just old fashioned, but it reminds me of useless Enterprise Java drones who are helpless without Eclipse and can't debug anything.
From the embedded systems end, VSCode really feels like the new Eclipse.
For decades embedded CPU companies would look at visual studio and say, "Boy howdee if we only had visual studio for our chips!" But they wouldn't be willing to put in the effort to do so, so they'd start with Eclipse, and the C/C++ plugin, and hack in a JTAG interface, and maybe a few code generators to pin out the hardware and say, look at us we made an IDE! And that IDE sucked, not because of eclipse, but because nobody actually put the work in to make it useful. You'd get lime breakpoints but not memory breakpoints or function breakpoints. You'd get a call stack but no way to inspect your RTOS. Every chip vendor did it themselves, so every tool was wildly different even for a big standard ARM core.
VSCode for embedded is the same thing, just in JavaScript. With AI!
It's Intellij nowadays, gramps.
Nope, I can CTRL-Shift-P faster than anything else, Sublime Text and NP++ included.
This argument that “convenience makes you weak” can be taken all the way to “real programmers write assembly” or “binary is the one true path”.
On the other end it’s also “I’ll vibe code it bruh”.
So we land at the eternally wise YMMV.
While this issue is up, I've recently been looking for an alternative to vscode for personal use because it runs so slow now with a few other programs running in the background. My main requirement is copy paste needs to be ctrl+c, ctrl+v and text selection needs to be ctrl shift + arrow keys or some combination of those. Using geany for a week or so hasn't been terrible but its not great either.
I tried vscode and it just seemed like a crippled version of jetbrains, I don’t get it.