For the past year, I have been working as cofounder at SkillHound working intensely on the development side. The concept of SkillHound came to be after spending a few months in 2011 reading and implementing proof of concepts data mining code to extract knowledge from git repositories.
My cofounder and myself are both (who isn’t these days among the HN crowd?) Steve Blank’s method practitioners wannabes. We couldn’t wait to get our feet wet going through the Startup Owner’s Manual’s table of contents with our very own concept.
Derek is not a developer, although he is good at screwing up the indention of my HAML files haha — jk derek! As the only developer in the team, I’m the sole responsible for the codebase’s sanity (and my own).
I’ve managed several codebases before (as pretty much every other developer out there). Coming from CVS and SVN, I learned to love and accept Git’s amazing power and minor-ux annoyances (let’s not start a flamewar here).
The experience with this startup’s codebase has been different. Very, very different. Following the Customer Discovery method, we implemented a barebones prototype of our product, not quite a full blown MVP but a Minimal Viable Demo. And all was good. We would go to what we thought might be our prospective customer, talked to them for 45 minutes, demoed for 5 minutes, and talked for another 10 minutes.
This was an extremely useful process, every single time we would finish a call or a meeting we would have ideas of what to change or what the product was. Over the course of just two or three months we had changed our target industry, shifted the target user two or three times and created what seemed (and was, for all intents and purposes) an entirely new product about 10 times. You could say that the only thing that didn’t change was name, and you would be wrong, because we changed that too after some time.
Throughout the first stage of this startup, as with most if not all startups, the priority was (as it should be) finding a market and a pain point that can be addresses within that market, then identifying what the MVP that addresses that pain point should look like. Code base stability, proper engineering and maintainability come at a distant third or fourth in the list of priorities.
Particularly in the first few months we had very drastic shifts, and each week the product would change significantly. In hindsight, perhaps a new code base would be in order on every micro pivot, leaving behind a library of common modules that were being used, but this was hard, as hardly a single method would remain unaffected. But that’s not what happened. No. As we shifted from one market to the other, from user to user, I would slowly adapt existent code in the name of speed, I would reuse code that was intended for A to be used for A’, only to realize two days later that A’ was not in our best interest, but might work well to address A”.
Over time, the codebase became chaotic, with entires modules of the architecture that remained from previous iterations, much like our arrector pili, just a vestigial trait of a predecessor of the current being.
Defaulting on technical debt — AKA “F*ck it, lets rewrite this”
Most of us, at one point or another, flirt with the idea of refactoring an entire or significant part of a codebase. Oh, the magic wand that will fix all problems in that tired codebase we inherited (from someone else or from ourselves).
As you flirt more and more with the idea it becomes ever more compelling, the mere fact of thinking about adding a new feature to the polluted codebase hurts when you compare it to the inherit beauty and simplicityof a naked canvas. As the idea starts taking shape of how you would do it right this time, how if you only had the time all problems would be fixed. This time it’ll be different. You are a different person, you know more about the product, about the technology, about the market.
And yes, in all likelyhood the product will be different. But that doesn’t mean that in five months or a year you won’t be in a similar situation, again, reaching for the blank canvas.
The reality is, rewriting a codebase is, almost always a receipe for disaster, unless your product belongs to that theoretical 1% of niches where speed, market landscape and needs don’t rapidly change, rewriting will create a significant advantage to your competitors.
git init .
I admit it I gave away to the temptation. After a couple of days of entertaining the idea of a complete rewrite, even after being burned many many years ago with one that ultimately destroyed my email client for Gnome project. I realized I was being lured in into Fuckville. 180-U-turn. Now.
Instead, I created a branch where I would start deleting code like there was no tomorrow. No. It wasn’t a rewrite, it was the ultimate axing of obsolete code. A good way to start a refactor effort that will accompany a healthy codebase throughout its lifetime.
What am I doing now that minimizes the problems related to the fast pace of a code base? What did I change from the start?
The lessons I’ve drawn from this experience have been mostly related to observe what I did and largely repeat the same behavior but with more determination. Its largely the lesson I drew from The Art of Racing in the Rain: when you anticipate chaos, don’t try to control it, rather, factor it in and accept it.
What I mean by that is, when dealing with a codebase that deals with an unknown and ambiguous problem, don’t try to tame the instability and chaotic nature of the codebase, rather accept it and visualize how you’ll get back the control of the steering wheel when time comes. Don’t try to regain control to early or to late or you’ll lose control altogether.
How do you deal with your codebase that drastically changes on a weekly basis? How about when it starts to stabilize?