We all have coding habits we would never recommend in a code review.
You know exactly what I'm talking about. It's the thing you do at 4:00 PM on a Friday when the ticket needs to be closed, and nobody is looking.
As developers, we love to talk about "best practices." We write articles about clean architecture, test-driven development, and the perfect folder structure.
But the reality of shipping software is often a lot messier.
Today, I’m going to fall on the sword. I’m going to confess the shortcuts I take that would make a Senior Architect cry. And I have a feeling I’m not the only one.
My Deepest Darkest Shortcuts
1. The TypeScript Mute Button (// @ts-ignore)
I love TypeScript. I really do. But sometimes, the type definitions get so complex that I spend two hours trying to satisfy the compiler for a function that will only ever be called in one place.
So, what do I do?
I type // @ts-ignore.
I don't fix the type. I don't write a generic. I just slap a piece of duct tape on the compiler and move on. It’s the coding equivalent of shoving your mess into the closet right before guests arrive.
2. The console.log Archaeology
Yes, I know about breakpoints. Yes, I know about the VSCode debugger.
But nothing beats the sheer primal instinct of scattering console.log("here 1"), console.log("here 2"), and console.log("why is this undefined???") throughout a file.
It’s dirty. It’s inefficient. But it works, and it makes me feel like a detective finding clues in the terminal.
3. The Copy-Paste Architecture
We all do it. You find a snippet on Stack Overflow that solves your exact problem. You paste it in. Does it use a library you’ve never heard of? Maybe. Does it use a deprecated React hook? Possibly.
Do you care? Not today. It compiled on the first try, and that is a win.
4. The CSS !important Battering Ram
When the flexbox layout isn't behaving and the padding isn't applying, and I've spent 20 minutes inspecting the DOM... I just bring out the !important.
It’s the "because I said so" of CSS. It solves the symptom but leaves a trail of chaos for whoever touches the file next.
Why Do We Do This? (And Don't Say Laziness)
It’s easy to look at these shortcuts and say, "That's just bad engineering."
But the truth is, we don't take shortcuts because we are lazy. We take them because we are managing cognitive load.
When you have a Jira board full of tickets, a Slack channel blowing up, and a deployment at 5 PM, your brain is looking for the path of least resistance. The shortcut isn't a failure of skill; it's a survival mechanism.
We prioritize shipping over perfection because perfection doesn't pay the bills.
However, there is a very thin line between a "clever shortcut" and "massive technical debt."
The trick is to be honest with yourself. If you use // @ts-ignore on a Friday afternoon, make sure you open a tech debt ticket on Monday morning. If you !important your way through a layout, make sure you refactor it when you have breathing room.
The goal isn't to write perfect code every single day. The goal is to write code that works today, and can still be fixed tomorrow.
The Confession Booth
I have shown you mine. Now, it's your turn.
I know for a fact that every developer reading this has at least one habit they hide from their team. Maybe you use git push --force on your own branches. Maybe you name your variables data, temp, and obj2. Maybe you haven't written a test in three months.
This is a safe space. No judgment, just solidarity.
What is the one coding shortcut you take that you would never put in a pull request?
Drop it in the comments below. I promise I won't tell your tech lead.
Top comments (12)
Nice one, this is a fun topic!
Yeah,
console.logfor me too - and I'm not even ashamed to admit it, because in many scenarios it's just the easiest way to find out what's going on ...Funny how, with a 'synchronous' language like PHP, I love using the debugger - but with JS/TS, not really ...
And
!important, yeah that's also one of my sins - but I'm less proud of that, and would not generally recommend it when there's a better way! ;-)Haha welcome to the confession booth, Leob! 🙌 Your point about PHP vs JS/TS is fascinating, and honestly so true. Stepping through synchronous PHP code is a breeze, but the moment you introduce the JS event loop async/await, and callbacks, the debugger suddenly feels like navigating a maze blindfolded. console.log just feels safer and more predictable in JS!
And don't worry about the !important we've all committed that sin. At least you feel guilty about it, which means your CSS soul is still intact! 😂
Thanks for sharing your shortcuts!
Yeah the sync/async thing is why people aren't in love with using the JS/TS debugger - maybe there's a "proper" way to do it, but I haven't discovered it yet ...
you're not alone in that! The proper way to debug async JS feels like an urban legend for most of us.
The moment breakpoints start jumping between microtasks and the event loop, console.log is the only friend we have left. If you ever discover the magic secret, please let me know too! 😂
Right ... that being the case, I don't really understand why so many people keep hammering the point (in blog posts, etc):
"use the JS debugger, don't use console.log !"
I've never understood that - does not seem rooted in reality ...
You are 100% right. I think the use the debugger not console.log advice comes from an era of simpler, synchronous codebases.
In a modern app with layers of async/await promises and React re-renders, pausing the debugger often breaks the very timing issue you're trying to catch. console.log doesn't block the event loop. It's basically non-blocking telemetry for our brains.
The debugger-only purists need to try stepping through a complex async race condition and see how long they last before going back to console.log. 😂 It's not a shortcut, it's just the right tool for modern JS!
Yeah maybe the debugger does work 'okay-ish' for backend JS code (node.js), but for frontend code (React etc) I think it's pretty much a nightmare, lol ;-)
spot on React's re-renders make the debugger completely useless. console.log is the only way to survive the frontend. Great chatting with you Leob! 👋
Yeah we're on the same wavelength on this one - it has always mystified me why people are adamant about "don't use console.log, use the debugger!" ;-)
Haha totally agree Sometimes best practices are just written by people who haven't debugged a React component recently. 😂 Have a great one, Leob!
The most expensive "temporary" shortcut I routinely see in post-mortems is the raw synchronous polling loop or unbounded in-memory hashmap duct-taped together to bypass standing up a proper state machine or message broker. When teams slap a 100ms
while(true)poll across 50 container instances to avoid integrating webhook or event drivers, the infrastructure tax hits immediately: 35–45% of cluster CPU cycles wasted purely on idle context switching, connection pool starvation, and p99 tail latencies spiking from a clean 8ms to over 220ms under baseline load.Replacing those hacky spin-locks with kernel-level primitives (
epoll/eventfd), Unix domain sockets, or an ultra-low-footprint broker like NATS drops background CPU burn to near-zero while keeping memory allocations deterministic. We’ve all bypassed architectural standards to beat a launch deadline—what’s the dirtiest duct-tape solution you quietly slipped past code review, and what operational trade-off did your production fleet pay for it later?Bohdan Hordii // bohdanhordii.dev
Bohdan this gave me anxiety just reading it A 100ms while(true) poll across 50 containers is a special kind of evil. Watching p99 latency spike from 8ms to 220ms must have been a terrifying PagerDuty alert. And you're right hacking around a message broker always ends up costing 10x more in infra bills than just setting up NATS would have.
To answer your question: my worst production duct-tape wasn't at the kernel level. It was an unbounded SELECT on a table that we assumed would stay small. I bypassed pagination on an admin dashboard because it's only 10,000 rows right now we'll fix it later. Two months later, that table had 2 million rows, and the database CPU hit 100% every time someone opened the page. The trade-off? A weekend of emergency indexing and rewriting the query while the site was on fire.
It always starts with we'll fix it later doesn't it? Thanks for sharing this war story, it makes my SQL mistake feel a bit less lonely!