31 bad programming habits that can make your code smell
Author
Bilal Azhar
Date Published
Bad habits are tough to break and much tougher if you do not realize what you are doing is endangering your own work. If you understand but do not care, that is even worse. But you are here, are not you?
Code smells — patterns in source code that indicate deeper problems — are almost always the result of repeated bad habits rather than one-off mistakes. They accumulate silently, increasing technical debt until a codebase becomes difficult to maintain, extend, or debug. Recognizing these habits is the first step toward writing cleaner, more maintainable code.
As a developer, I have seen a great deal of poor practices, not only around code, but also about teamwork abilities. I have been guilty of practicing several of those bad habits. Listed below are 31 bad programming habits that I found and most of them I practiced, arranged into four classes: code organization, teamwork, writing code, and testing and maintenance. Whether you are a junior developer or a seasoned engineer looking to hire skilled developers, understanding these anti-patterns is essential.
Code Organization
1. Saying, I will fix it later
The custom of postponing code fixes isn't only an issue of priorities. Organizing your problem tracker may generate some improvement, but in addition, you must have a means of tracking smaller problems which come up as well. Doing “To do” comments at all necessary place is a fast method of earning certain that you don't overlook anything.
2. Insisting to a one-liner solution
Being fanatical about writing effective, elegant parts of code is a frequent characteristic of developers. It is like solving a mystery --you locate a mix of routines and regular expressions which turn 20 lines of coding into 3 or 2. Regrettably, it does not always lead to readable code, and that is generally a lot more significant consequence. Make your code readable first, then smart.
3. Making pointless and unnecessary optimizations
Another location where we often misplace our efforts is optimizations. It seems fantastic to decrease the size of your site several bytes, but won't gzip compensate for it anyway? And aren't fix and features requests more important? Moving such optimizations to the end of the project when you have some free time and requirements won’t change sounds a better option
4.Making yourself believe that styling problems aren't that Significant
If I've learned anything after more than years of looking at other people's code, then it is that coping with coding style issues is what that developers are most likely to delay. Perhaps it's hard for inexperienced developers to find out the advantages of addressing such styling issues, but over time it will become clear that once code quality goes down, soon your project will become a complete mess. Make sure to stick to best practices even if it is regarding styling of code.
5. Sweeping things under the rug
Either by catching and dismissing exceptions or utilizing libraries that don't report errors (for instance, jQuery), there are numerous approaches to sweep things under the rug. But when these errors become a priority, the battle of mending it will be several times bigger, believing that you will not have any idea where to get started. A easy method to stop this is by simply logging those blown off errors so you can study them later.
6. Using names that don't add Info
Naming is tough, but there is a simple method to be certain that your variable and function names are of adequate quality. Provided that the naming adds some sort of information which the remainder of the code does not communicate, other programmers are going to have an easy time going through and getting your own code. The reason why naming is so essential is that titles/names can give an overall idea about what the code does. It requires more time if you have to dig to the calculations to determine which bit of code, but a fantastic name can help you know what the code will in minutes.
Teamwork
7. Abandoning plans too early
A cent percent sure way for creating your code unreadable and cryptic would be not to commit to a strategy. You could always say, if your code is criticized, the program is not complete. But, having half-done modules can result in tightly coupled code once you attempt to create those partially done modules work with one another. This type of complication comes up when new project leader comes in and they think having their way is more important than architectural consequences.
8. Insisting on a Strategy that has little Prospect of working
Just as if giving up a strategy very quickly can cause problems, so is the case with sticking to the strategy that does not work. That is the reason you need to discuss your thoughts with your staff to get opinions and advice if things become tricky. On occasion a different approach could make all of the difference.
9. Refusing to write bad code
There is a time in each programmer's lifetime when deadlines will make you write code that is awful, which is fine. You have attempted warning your customer or manager regarding the impacts, but they insist on adhering to this deadline, so now it is time to code. Or maybe there is an urgent bug that can not wait for one to think of a fresh solution. That is why it's essential to be flexible as a developer and also to have the ability to write bad code quite quickly in addition to great code.
10. Blaming others
Accepting responsibility for your errors is a merit which will cause you to glow among your peers. Do not be afraid to admit that you have made a mistake. As soon as you're alright with this, you'll be free to concentrate on learning the reason you made that error and how to prevent it. If you do not own it up, learning becomes impossible.
11. Not sharing with your team what you have learned
Your worth as a programmer does not only depend on the code that you write, but also on what you understand when writing/developing it. Share your own experiences, write remarks about it, let's understand why things are the way they are, and also help them understand new things about the task/project and its intricacies
12. Being Overly slow on Providing feedback to managers/clients
Being too slow on getting everyone else on the same page is an issue as well. Among the very valuable personality traits of any craftsman lies in making certain everyone is on precisely the exact same page concerning the job, as far as you can. The cause of this isn't so that your supervisor can fill spreadsheets. It is for your personal profit too: You may have fewer insecurities and decrease uncertainty about the future and lifetime of the job.
13. Not using Google enough
Every time you face a problem, make sure you just google it. There is large communities there like Stackoverflow that can quickly help you. You can also developer next to you for help, but they might be busy. So just googling for solution will save your and others time and you will find appropriate and quick solution.
14. Overvaluing your personal style
Make sure to coordinate with your working style and environment setup with your team. Ideally, everyone on your staff should be operating under similar circumstances and observing the exact same coding style. Doing things your way might be more enjoyable, but co-workers may not be employed to your programming style, and when it is odd, it is going to be more difficult for another developer to focus on what you have wrote and built.
15.Don’t be romantic about to your own code
If someone comments about your code, do not take it personally. Your code must stand on solid earth; that's, you need to be able to describe why you wrote it like that. In case it needs improvement, that is only a manifestation of this code's correctness, not yourself.
Writing Code
16. Optimizing in a wrong way or Not knowing how to optimize
A fantastic optimization strategy requires some expertise to get right. It requires exploration, investigation, and understanding each system involved with a procedure. Inform yourself about such items. Learn about algorithmic sophistication, database query analysis, protocols, and also the best way to measure performance generally.
17. Using the wrong tool for the job
Always be receptive to new languages and libraries You can just understand a lot, however the reason you need to keep learning is that each new issue attracts another circumstance and demands another instrument –more relevant to the task available. Don't make decisions based purely on what you know.
18. Not trying to master your tools and IDE
Every new shortcut or hotkey you understand while utilizing the tools that you work with each day is going to have a more favourable impact in your coding rate than you understand. It is not about saving a couple of seconds using a hotkey; it is about reducing the context switching. The longer spent on every little action, the less time you will have available to consider why you are doing it and on what comes next. Mastering shortcuts will free your brain.
19. Ignoring warnings and error messages
Don't assume that you understand what's wrong with your code before reading an error message, or that you'll figure it out fast enough. Having more information about a challenge is obviously better and taking the opportunity to gather that info will save yourself more time in the long run.
20. Ignoring configurable values and using hardcoded values
Give extra importance to configurable values. Constantly be considering what changes can come along with how to handle them. Technical debt will expand at a massive rate in the event you don't split the moving pieces from the remainder of your work. Use constants and configurations where appropriate.
21. Trying to reinvent the wheel all the time
Never reinvent the wheel. Do not write code that you don't need to. Perhaps someone else has invested a great deal of time in your own problem, and they may have a well-tested alternative that you may reuse. Save yourself some trouble.
22. Blindly copying and pasting code
Making sure you don’t blindly copy and paste code and you understand it before you use it. Sometimes you do not immediately detect what the code is doing. You'll also learn more about a problem when you take a chance to navigate the code in detail.
23. Not allotting enough time to learn how things really work
Always take the chance to broaden your knowledge by contemplating how things function and studying about their inherent issues. You may save time by not bothering currently, but everything you find out on a job will be significant in the long run.
24. Being overconfident about your own code
It is not good to assume that simply because it is something that you built or coded, it has to be great. You find out more about programming since you work on new items and gain expertise, so have a peek at your previous code from time to time and reflect on how you have improved.
25. Not giving thoughts to the trade-offs of each design, solution, or library
Everything comes with pros and cons. Every product has its fine things you'll just learn about using and assessing it. Seeing a couple of usage examples to get a library won't make you a grasp of it nor does it imply that it is the perfect match for each situation that will appear on your undertaking. Be constantly critical of all you use.
26. Not asking help when you're stuck somewhere
Asking for help does not mean that you're incompetent. It is important to keep a short feedback loop. It will make thing less painful for you. The perfect people will understand your attempt as an effort to learn more, and that is a fantastic virtue to get.
Testing and maintenance
27. Writing tests to pass and not writing the ones that will not pass
Writing unit tests, you know will pass is essential. They'll make reorganizing and refactoring a code much safer. On the reverse side, you also need to write evaluations you understand will not pass. They are important to move the project forward and keep an eye on issues.
28. Not considering performance testing important enough for critical cases
Make sure to set up an automated testing process at some time after project is started, probably at middle point of the development. It will help you know if you are having escalating performance issues.
29. Just focusing on build passing and not checking that your build works
It is not very common that every time as build passes, it getting the job done in exact way. Quickly testing and analysis every build that passes is a good habit to have.
30. Not owning code you wrote
Don’t hesitate to own your code. You are probably the only person who can better help others understand your code. You need to aim to make your code remain readable to yourself and others many years from today.
31. Disregarding and ignoring non-functional requirements
It is very probable to happen that you sometimes forget about essential requirements like performance and security when deadlines are approaching or you are trying to deliver something really quickly. Keep a checklist for those. You don't want them destroying your party since you drafted your deadlines before contemplating these non-functional requirements.
How to Build Better Programming Habits
Breaking bad habits requires more than awareness — it requires systems that make good practices the path of least resistance.
Automate what you can. Linters (ESLint, Pylint), formatters (Prettier, Black), and pre-commit hooks enforce style and catch common issues before code reaches review. When the tooling catches the easy mistakes automatically, reviewers can focus on architecture and logic.
Establish team standards. Write down your coding conventions in a shared document. Cover naming conventions, file structure, error handling patterns, and testing expectations. When standards are explicit and documented, disagreements become discussions about the standard rather than personal preferences.
Practice incremental improvement. You do not need to fix every bad habit at once. Pick one — say, writing meaningful variable names — and focus on it for two weeks until it becomes second nature. Then move to the next one. Small, consistent improvements compound over time.
Invest in learning. Allocate time for reading, pair programming, and exploring new patterns. Teams that dedicate even 10% of their time to learning and experimentation consistently produce higher-quality code than teams that spend 100% of their time on feature delivery.
Use code quality metrics. Tools like SonarQube, CodeClimate, and ESLint's complexity rules can quantify code quality over time. Track cyclomatic complexity, code duplication percentage, and test coverage. When these metrics trend in the wrong direction, it is an early signal that bad habits are creeping in — long before they become visible to managers or clients. Set team-level thresholds and review them in sprint retrospectives.
Pair programming for habit transfer. When a senior developer pairs with a junior, the junior absorbs good habits — naming conventions, debugging approaches, testing instincts — through observation and real-time feedback. Pair programming is one of the fastest ways to spread best practices across a team and break bad habits before they become entrenched. Even two hours of pairing per week can measurably improve code quality within a single sprint cycle.
Improving how you work through habits is a great way to avoid having to think a lot about each and every situation. As soon as you have assimilated a perfect method of doing something, it is going to end up effortless.
Regular code reviews are one of the most effective ways to catch bad habits before they become entrenched. Having a second pair of eyes on your code catches smells early, reinforces best practices across the team, and creates a culture of continuous improvement. If your team does not have a formal review process, establishing one should be a top priority.
The Cost of Ignoring Code Quality
Technical debt is not an abstract concept — it has a measurable cost. A study by Stripe estimated that developers spend an average of 42% of their time dealing with technical debt and bad code, costing the global economy over $85 billion annually. For a team of ten developers at an average salary of $120,000, that translates to roughly $504,000 per year spent on maintenance that could have been avoided with better habits from the start.
The compounding effect is what makes bad habits so dangerous. A single poorly named variable is trivial to fix. But when an entire codebase follows inconsistent naming conventions, has no tests, uses hardcoded values throughout, and has no documentation — refactoring becomes a multi-month project. The earlier you catch and correct bad habits, the cheaper the fix. Prevention through good practices, automated linting, and professional code reviews is always less expensive than remediation.
If you'd like to talk about some other programming customs which you consider detrimental, or you want to discuss improving your team's code quality, get in touch and let's talk. You can also explore our web development services or hire experienced developers who bring strong engineering discipline to every project.
Frequently Asked Questions
What is a code smell and how is it different from a bug?
A code smell is a surface-level indication that something in your source code may lead to deeper problems — it is not a bug itself, but a warning sign. Bugs cause incorrect behavior that users can observe, while code smells make the code harder to read, maintain, and extend over time. For example, duplicated logic across multiple files is a code smell: it works fine today, but when requirements change, you need to update every copy — and missing one creates a real bug. Addressing code smells early through refactoring and professional code reviews prevents them from evolving into costly bugs.
How do code reviews help prevent bad programming habits?
Code reviews create a feedback loop where developers learn from each other's strengths and catch each other's weaknesses. When a reviewer spots a naming issue, an unnecessary optimization, or a missing test, it creates a learning moment that prevents the same mistake from happening again. Over time, teams that practice regular code reviews develop shared standards that raise the quality floor for everyone. Studies show that code review catches 60–90% of defects before they reach production, making it one of the highest-ROI quality practices available.
What are the most common bad programming habits that lead to technical debt?
The habits that generate the most technical debt are: postponing fixes ("I'll fix it later"), skipping tests, using hardcoded values instead of configuration, naming variables poorly, and copying code instead of abstracting it. These feel like time-savers in the moment but compound rapidly. A project with heavy technical debt can spend 40–60% of development time on maintenance and bug fixes rather than new features. The most effective countermeasure is establishing coding standards, enforcing them through automated linting, and conducting regular code reviews to catch deviations before they accumulate.
Explore Related Solutions
Need Help Building Your Project?
From web apps and mobile apps to AI solutions and SaaS platforms — we ship production software for 300+ clients.
Related Articles
Landing Page Design Best Practices That Convert in 2026
Data-backed landing page design best practices that increase conversions. Covers layout, copy, CTAs, forms, social proof, mobile optimization, and A/B…
10 min readUX Design for SaaS: The Complete Guide for 2026
A comprehensive guide to UX design for SaaS products. Covers onboarding, navigation, dashboards, pricing pages, retention design, and UX metrics that…
7 min readWebsite Design Brief Template: How to Brief Your Designer in 2026
A complete web design brief template with examples. Covers brand information, goals, target audience, design preferences, content requirements, and…