I’ve been working as a software engineer for some 14 years, and having taken nine months out to work on a side-project full-time, I am now looking to start PHP/web freelancing. I have an intro page for what I offer; this partner article is a rambling rendition of the how. My purpose here is to provide some insight into my working practices, both for potential clients, and anyone else interested in small-scale software development. I’d like this to be a living document; as my view of things adjust and deepen, I’ll reflect that here.
If you’re curious, my side-project is an online board for tech jobs that displays jobs on a map, and refreshes its database from the web automatically. The proof-of-concept receives job data from a custom search engine robot, which runs the background machinery to fetch data from the web and to convert it into a searchable format. As time permits, I’ll carry on with both technical and business aspects of this project – there’s plenty of business validation, market research, brand identity and UX still to do, and the ideas board is overflowing!
So, why am I entering the freelance world? One of the attractions is that there are fewer technical obstacles to getting on with meaningful work. No new computer hardware, no installations, no new accounts: my dev environment is set up optimally and is time-tested. I run Ubuntu in VirtualBox on a 13″ ultrabook, and it’s the nicest set-up I think I’ve yet used. I use Netbeans IDE, LAMP, console Git, GitHub and BitBucket, Composer and PhpMetrics.
I rather also like the freedom of working from anywhere. I don’t tend to work much from home, though the lappy will always be warm on the table whilst dinner is cooking. I work either from coffee shops, or for larger projects, sometimes a co-working space.
Requirements analysis
I think there’s some value in outlining how I approach the development of a new system. These guidelines may not apply to the developer of existing applications, and may be modified if a client already has a good workflow already in place. Nevertheless, I’ve found these ideas helpful in the past.
I start off with the recommendation that the client should create a specification of what the application should do. This does not need to conform to any particular standard of requirements analysis, and I tend to suggest that project owners should just open their word processor and start typing. Pictures should be used liberally: block diagrams, tablet/stylus sketches and scanned paper are all good. It’s worth viewing this as much about what business problems are being solved, as well as the manner in which technology is intended to solve them (is the automation of a manual process reducing time spent on labour-intensive tasks? is offering searchable product/service information via the web improving customer satisfaction? etc).
I usually take the view that this process does not need constant guidance from a developer, since bringing a developer in early will incur extra costs that may be unnecessary. That said, where a client explicitly requests extra help, I am (of course) willing to assist at this stage as much as required.
Once the document is finished, the developer should analyse it for inconsistencies or areas that lack clarity, so that development paths stemming from misunderstandings can be avoided. At this point I will often suggest changes to the UX or underlying data relationships to make it more intuitive, to perhaps make future technical changes easier. I believe it is worth explaining the system back to the client at this point, so any misunderstandings are cleared up whilst they are still low-impact. A general strategy brain-storming session can also be helpful, to try to take account of any forthcoming changes to business practices.
Whilst some thoroughness is useful here, it is also important not to get too hung up on the process; it is entirely possible to draw up an ossified document that does not yield flexibly to mutually agreed changes during the development phase. The aim should be to be clear, succinct and illustrative (an approach sometimes known as “show, don’t tell”).
Technical specification
Once a set of requirements have been captured, the developer may draw up a document detailing the technical details of their intended approach. How substantial this is varies entirely with context: the developer here should be thinking of what the next developer would need to know in order to carry on working on the project. Whilst good devs can often make do without this – we often love to dive straight into code! – if some of the original technical vision can be captured in order to save someone some effort in the future, it is time well spent.
One very useful thing that clients should ask for here is an installation guide for the software: what needs to be run to set it up for local or live? Where are the config files? How to fetch JavaScript and backend library dependencies? Do SASS/LESS/JS files need generation or minifying? How can in-house staff move the site in the event of a disk crash? How should the tests be run? Is there a build process for an empty database? Is there a deploy process?
There is also value in making some simple notes about what libraries are in use, what could do with upgrading, and where technical debt needs paying off. These elements of a project are best captured by the original engineer, rather than leaving subsequent devs to guess. Of course, if they are placed on an agile board (e.g. Trello) then it is sufficient to ensure the product owner has access to this at the end of the project.
Development phase
The key to a healthy development process is regular communication, usually at a rate agreed with the client. Daily is a good starting point: even for longer projects, the report need not take more than 5-10 minutes to write, and doing so encourages the client to remain involved and hands-on. I like using visual tools like Trello, or a ticket-based system like Redmine or Trac, to note progress and to ask for clarifications as appropriate. This feedback loop can help detect any mis-communications that were not filtered out in an earlier stage – gremlins do get through.
During the day, code should be committed to a local distributed repository (e.g. Git) and then periodically pushed to an external server (e.g. BitBucket). This approach tries to insulate against local disk failure: if the dev machine fails, no more than a day’s worth of work will be lost. Once a codebase contains substantial items of functionality, I like to push it to a password-protected internet-based server to show. It’s the most visual mode of feedback there is!
One of the most difficult questions to answer is how long development will take: it’s a hard problem that millions of project managers and devs will continue to argue about enthusiastically for years to come. It partly depends on how the work is being charged. If it’s a fixed cost project, the developer must accept cost over-runs as a business loss, whilst striving to avoid shortcuts that may harm product quality. On the other hand, if the development is billed on a daily rate, then the opposite is true: more work may increase quality metrics, but not all improved metrics will necessarily represent good value.
It’s worth both parties setting up an expectation about a project deadline: if a piece of work is estimated to take ten days, it is a good idea not to set a hard limit of ten days hence. Slippage can occur on both sides: freelancer illness, or client unavailability for milestone sign-off, or business strategy changes, are but a few examples. The critical approach here is to develop a flexible and understanding approach in both directions, and to keep communicating.
Managing changes
They say that with all things, the only constant is change. In the context of software projects, change may come from new business requirements, misunderstood or underspecified requirements, or technical difficulties occurring during implementation. Prior to embarking on a project together, the freelancer-client partnership would do well to set out how this will be managed if it arises. Of course, trust going both ways is essential: with the best will in the world, clients sometimes omit a critical requirements detail, or a developer encounters an unforeseen technical difficulty that causes a critical project path to slip.
Where change becomes necessary, it is best tackled immediately and head-on: a requirements change is easier for everyone if it is discussed on day three, rather than day 23, in the development phase, since the amount of potential re-work is likely to be smaller. The same goes for significant technical problems: they should be declared, along with a plan to resolve them, at the earliest opportunity. The client may be wise to set aside a budget for changes arriving from their own side, just as the freelance engineer should be willing to accept some loss if the technical difficulties resulted from their insufficient initial research.
Let us take the example of a change arising from a new client requirement. If the development phase is in an early stage, it may be that it does not impact on the work done thus far. However, if this would incur significant extra person-hours, the developer should draw up an Impact Analysis to show the cost/time implications of the new item of work. A discussion can then be had to make a cost-benefit comparison of the new plan against the old one, and then either switch to the new plan (with appropriate contract modifications) or stay on the old course (leaving the change to a separate phase of work).
Charging
Setting out a clear mechanism for payment that is fair to both parties is essential, for obvious reasons, not least because terms that are excessively onerous for one side may result in the work not going ahead at all. For larger or overseas projects, I favour a small number of clearly defined milestones, which are signed off and paid in sequence. Smaller projects in the UK can usually be started simply after the contracts have been signed.
Whilst clients may request that an escrow service is used, some freelancers suggest that milestones work well enough on their own:
One approach that I’ve seen used by a few companies is to work from a shared Github repository, where the code I’ve worked on gets pushed up as soon as it’s complete, and then once they’ve paid the related invoice, we continue with the next feature. [source]
(Last updated July 2015)