Write really simple code. Simple does not mean short. Sometimes it's better to be more verbose and lay out the steps and variable names clearly. In other words it's not simple to write simple code. I also write incrementally, making sure everything works solidly as I go. I also try to keep dependencies inside the code at a minimum, and expose various low-level functionality, so that I can test and experiment and get a better understanding of what is happening. A debugger can help too. What I don't like about a debugger is that it's like being on tracks and only being able to go forward. At one of my jobs I got into arguments with another developer because he followed the philosophy that "everything must be private" (except what needs to be used). I follow a different philosophy to make my software easier to diagnose. Formal testing is good. However quick and dirty assertions can also do the job in some cases. Despite that, sometimes I run into hard-to-track bugs. They are often caused by complexity in whatever the code is interfacing with, for example, the DOM. My philosophy is about keeping complexity under control - keeping things simple and transparent. That includes minimizing side effects. Side effect are evil. We have many of these in CSS (eg: oveflow:hidden affects floats and sticky positioning). I guess that pushes me towards functional programming.