Wednesday, January 02, 2008

“Build It Quick” but “Make It Last” – Lessons in Software Development for Startups

I’ve often been asked what methodology and architecture works best for software development in startups. The truth of the matter is that no one methodology or architecture works best in startups – and that goes for everything from Xtreme programming to SOA to Factory design patterns. I’ve been involved with enough startups to know that you have to take a ‘zen-like’ approach – doing whatever seems right at the time, but all the while keeping an eye on where you want to go.

Given the fast pace of most startups, we don’t have the luxury of strictly following all the rules of any given methodology. I call it a luxury because every methodology has inherent built in processes and limitations - and most methodologies were built to get more reliable software for big projects – not necessarily to get a version 1.0 out the door so that the concept can be proven with customers.

Nevertheless there are some “observations” about development in startups that are worth keeping in mind. I say “keeping in mind” rather than slavishly following some set of rules because the situation might require something else, so keep an open mind. Venture funded startups tend to have more methodology and processes than bootstrapped or angel financed ventures –and for good reason – they can afford it.

So, that said, here are some of my own observations:

  • Startups are used to getting sites/products built without big teams. Startups usually have very few resources in the beginning – one or two developers write the entire site. There are usually no QA resources or dedicated product managers in the beginning. This means that:

    • Startup developers have to be more then “just developers”. They have to test their own code and make sure it works– As an example, many Facebook applications are built entirely by one developer in a short period of time without any QA resources (though they are needed as the app gets more complicated). When we started CambridgeDocs, my co-founder and I built the entire product without much QA – we used our initial beta customers to do QA. This doesn’t always mean using JUnit or even always using automated testing, though these can be quite helpful and I recommend using them. It does mean you have to have a set of “smoke tests” that you test out each time you check in your code.

    • Those building the first product need to think of themselves as users of the first product – and not just as “only developers”. This helps to guide the various minute decisions that need to be made rather than always expecting a group of “users” to tell them what to do or an “architect” to make the decisions for them. It also helps with the expanded QA role developers in early stage startups are forced to take on. And sometimes, believe it or not, you just have to play with the “whole” site or product and see if you can break it – not just the modules you’ve written - just like an end user tester would.

    • Developers need to be able to juggle multiple tasks and languages. In a startup it doesn’t work so well to say “I’m only a PHP guy I don’t do javascript or AJAX or action script” – if the application requires both you will need to do both. This means learning enough about different languages so that you can juggle them as needed. For example at CambridgeDocs we decided to do our core platform in java, but we had modules that ended up being built in all kinds of other languages - VB .NET, C, C++, C#, VBA, XSLT. That doesn’t mean that we were able to send people to courses on any of these languages – the developer had to pick up a book or do searches on-line and figure out how much of these languages they needed to know for the task at hand. Usually only a small amount of knowledge of a particular language was required in order to complete the task. In another startup the main platform was built in java, but we were able to build some perl code that did what needed to be done and the first few production clients used this perl code while we waited for the java platform to get done. This was better for the startup than telling clients to wait until it’s done.

    • Developers have a lot of leeway in the beginning. This leeway can be good or bad, depending on your disposition. Usually it means you not just have to do a development task, but have to figure out the best/most efficient way to get it done – use open source/third party tools, do it yourself, use algorithm/architecture # 1 or #2.
    • Developers need to give estimates early and refine their estimating. Developers need to give estimates as their “best guess” based on the information at hand. These estimates almost certainly will need to change as the team encounters unexpected difficulties with a particular piece of technology or third party product. Don’t be afraid to give an initial estimate and say “this is my best guess – I’ll refine it as I go” – rather than saying “I need another 2 weeks to study this problem before I can give you an estimate”. Basically you need to transition from a “CYA-perspective” (Cover-Your-Ass) of estimating (which is done in larger organizations) to a “GID-perspective” (“Get-it-Done”).

  • Startups usually prefer an iterative approach – get something up quickly, then iterate and make it better. This is crucial – what goes into a particular version or product release is debatable almost up until the time of release. In my very first startup (I wrote about this in my book, Zen Entrepreneurship) we were going to a conference in Florida the next day and the product was supposed to be release – we only had one problem – it crashed when multiple instances were running on the same machine. Now we could’ve pushed back the release, but the release date was critical for us, so we got around the bug by simply taking that feature out – it wasn’t critical especially for a first release.

  • Specifications are usually limited. Most specifications within startups are screenshots or mockups with some explanation. That doesn’t mean that there are no specifications. But it does mean that typically to specify an API you would just go ahead and write the function headers in java or whatever language you’re using. This initial cut would be the spec and then evolve into the final product. Similarly an HTML mockup of a page is the spec for what the page will look like – this HTML is then translated into PHP or java or Ruby On Rails and it morphs into the final product. Usually (fortunately or unfortunately) the initial specs are discarded and the “work in progress” becomes the working spec as the initial version is built. There usually isn't time (again fortunately or unfortunately) for workflow analysis, full UML, etc.

  • Code needs to be written “cleanly” even (especially) in prototypes. This might seem like a counter-argument to the build it fast argument. But it turns out that in a startup a prototype will almost inevitably end up as part of the production application. As an example, even before we formally started CambridgeDocs I built a prototype of an HTML parser and called it “RizHTMLParser”. I was never planning for it to be a production thing – but as often happens in startups, it was rolled in as the first version of our HTML parser. For years we had a class in our java code that was named after me personally – this happens a lot more than you would think – and our product was being used in production by many Fortune 500 companies!

    It’s better to just pick a more descriptive name for the class to begin with, even while prototyping. This doesn’t mean that you should take a lot more time to build prototypes – not at all – what it does mean is that you should take a few extra seconds and write the code cleanly and with names that make sense because it's probably going to end up in production somehow. Same goes for commenting- take a few extra seconds and write some comments. Writing “clean code” shouldn’t take much longer but it helps in maintainability down the road.

  • Startups need to think about the future, but build for the present. Flexible and scalable architectures are good – startups usually need to follow an architecture that leaves room for the future but that takes into account present needs.

    This is a delicate balance between “get it done quickly” and “build it to scale” and "build for re-use" – resulting in something that has some level of “quick and dirty” but done in a modular enough fashion so that it can later be replaced as the codebase is re-factored and the organization gets bigger.

    As an example, when we built our first Microsoft Word file reader we needed something quick – we used a bridge from our java server to Microsoft Word and used its built-in API. This solved the problem but was not a good scalable solution (it was single-threaded, and had a host of other problems) – we identified the way we’d like to do it – straight cross-platform java code which read .doc files on the server. But the amount of development required for the eventual solution was well beyond what we could afford – so we did it quick but we isolated it in a way so that it would be very easy to switch to eventual driver when it was ready. This quick and dirty driver actually worked for us for over a year and got us our first few word-related customers, at which point we had identified some clients who would provide the funding for the full development effort. We eventually re-wrote it and the scaleable re-write became one of our key pieces of differentiation.

    I like to think of this as a “Build it Quick” but “Make it Last” philosophy. Another entrepreneur I know called I the “version 1.0/ version 3.0” tradeoff –you need to get version 1.0 done, but you want to think about what version 3.0 might look like. It means you need an architecture that doesn’t follow “hard and fast rules” (i.e. this methodology or that methodology) but leaves open the possibility of pieces being written in a less than optimal manner in the beginning in order to demo something to a client and then re-factored over time.

Read more!