Every dev picks up a pile of rules early on. Write tests first. Never commit to main. Keep functions under 20 lines. DRY everything. Comment your code. 100% coverage or it doesn't count.
Some of those rules stuck. Others got quietly dropped somewhere along the way, usually after a project where following them made things worse.
I'm curious about the ones you dropped.
- What was the rule?
- What happened that made you stop?
- What do you do instead now?
Bonus points if you still follow it sometimes and can explain when.
Two small ground rules so this stays useful:
- be specific (a real situation beats "it depends"), and if you disagree with someone's answer, reply and say why. The arguments in threads like this are usually the best part 😄
I'll go first in the comments.

Top comments (17)
Coding by hand which is seems long long time to a best practice to make a program, right now I can vibe code near anything.
The next best practice is the UI and mouse intensive application. I moved to the terminal handler direction, so my frequently used IDE is pure VIM. I can work in my MacBookPro terminal or my 6 years old company windows11 laptop,
wsl install ubuntu|> ubuntu console ( technically windows CMD program )React |> no framework |> do not care of which programming langague are using - even I completly not familiar of them like a Go or Rust
OOP |> functional programming |> minimal functional programming
The problem with OOP is to tigh linked the data and the code. Functional programming can be unreadable very sortly like using of ramda. The big question is who would like to code by hand, I am very advice to do that at least hobby level. On your work you can use as many AI as would like to help your project.
Care about money |> My advice is: don't need to care too much, the life is important!
Mine's "make it reusable from the start."
I build the specific thing first and let it be a little messy. With Mochi, my Linux desktop pet, I got one actual pet working (its animations, moods, and little behaviors) before thinking about reuse at all.
Once it worked, I pulled the systems that had proven themselves out into their own runtime, Deskling: animation, the state machine, the event bus, movement and boundaries, dragging, scheduling. I didn't rewrite any of it from scratch. I extracted code that already worked, and by then I knew which parts deserved to be reusable because Mochi was already using them.
Where I do design for reuse now is Deskling itself, since the whole point is letting other people make pets. Community pets ship as data-only
.desklingpackages with no arbitrary code, so "reusable" there means "safe for strangers to share." That's a much more specific problem than "maybe I'll need this someday."Curious if anyone went the other way and got burned by NOT abstracting early.
Never commit to main. Working solo, a branch per change was a review step with nobody on the other side, so small changes go straight to main now, one commit each.
I still branch for anything that stays half-built for days. A paywall experiment and guest accounts both lived on their own branch until they were ready, so main stayed shippable the whole time.
100% aligned with this
I was looking at some parsing logic in a codebase for a simple custom format. I wanted to understand how it worked, so I decided to implement it myself.
I wrote my own version, found a few bugs, fixed them, and eventually got it working. It behaved exactly like the original, and I even tested it against the real code.
The original implementation used some efficient looping techniques. Mine was simpler, and it was actually the first time I had written something like that. Even though it worked, I kept doubting myself: Is my approach really as efficient as the original?
So I gave both versions to AI. It brutally told me that mine wasn't good practice.
I spent an entire day trying to prove that my version worked the same way. Finally, I asked the AI to compare both implementations line by line and loop by loop, with actual data.
In the end, they were doing the same thing.
That whole experience taught me something: sometimes, just because code looks different from an experienced developer's code doesn't mean it's less efficient.
Great Article!
I’m new to Dev.to and have recently started writing about data pipelines and AI. I’ve published a few blogs so far. If you have a moment, please take a look I’d really appreciate your feedback! 😊
Abstracting everything just because it makes the code look “cleaner,” even when the abstraction adds nothing to functionality or improves the overall developer experience.
One I quietly stopped following is “abstract it early so it can be reused later.”
I used to see two similar pieces of code and immediately think they should become a shared service or utility. The problem is that similar code doesn’t always mean the same concept. I’ve had cases where two API flows looked almost identical at first, then their validation and error handling started evolving differently. The shared abstraction ended up needing flags and special cases just to keep both behaviors alive.
Now I’m fine with a little duplication until I see the same rule changing for the same reason. For example, if two endpoints both calculate pricing but one is for checkout and the other is for internal reporting, I’d rather keep them separate until the domain relationship is actually proven.
For me, DRY became less about removing repeated code and more about avoiding duplicated knowledge. The abstraction should earn its place in the architecture, not get promoted because two functions happen to look alike.
I stopped following even 2 in fact:
Two small ground rules so this stays useful.
1) I am as general as possible.
2) I disagree with everything in your post.
-2147483648) Less talking, more raiding
"Reproduce it Locally First" A crash minidump from the customer's machine, loaded with matching symbols, usually tells me more in ten minutes than days of trying to reproduce it.
"Ship it raw and grow from feedback"
Some comments may only be visible to logged-in visitors. Sign in to view all comments.