The tldr on everything that follows is this first rule:

Do not start writing code before you know what the code needs to accomplish

Breaking down this directive in reverse order:

Functional Requirements: What the Code needs to Accomplish

Functional requirements define the expectations of the client.

The client will vary based on what your project is doing. It could be someone else in your company, it could be someone who is paying you money in exchange for writing their application, or it could be the CEO who is defining the vision for what the application needs to do.

The functional requirements define the actions of the application that are important to the client. This will include things like:

What actions specific pages and components should perform from the user perspective, including (but not limited to) the layout of important components, user workflow between different sections of the application, etc.

Business logic and rules for how data should be processed, saved, validated, etc

Security rules governing access to functions

Definitions of rules governing specific edge cases in the required business logic

Functional requirements do not necessarily need to include:

The layout of every page/view (just the things that are really important to the client)

All of the on-screen copy, messaging, etc

Anything about the business logic that the client doesn’t really care about

Most importantly, the functional requirements do not include plans for technical implementation.

It is not necessary to know how you are going to implement everything at this point. Getting caught in the technical details before all of the functional requirements are locked down can often be just a big waste of time, as it is impossible to make accurate technical plans before you know exactly what you need to implement. That said, if there are any absolute technical requirements that need to be met for one reason or another — for example, a specific technology must be used, or the product must be able to interface with a given API, this is information that should be disclosed during the functional planning stage, as this can have influence on some of the functional requirements.

I need to write something other than Code?

Ideally: No, the developer would not be the primary author of any functional spec. That is the job of the PM (Project/Product Manager). The PM should be the person who deals with the clients (internal or external), figures out how to translate their requests into a set of functional requirements, and writes it all up in an organized fashion.

If you are fortunate enough to be in this situation, then while you do not have to write the functional spec, you do have to review it very closely. As the developer, you are the person who bridges the gap between functional requirements and technical implementation. It is up to you to poke holes in incompletely defined functions, push on missing items, find edge cases and the uncover self-contradictions and security holes that are inevitably present in the first draft of any functional spec. This is an important process to go through while things are still only written in words and not in code — it will never be cheaper to change a requirement (and it will be exponentially more expensive to change things once code has been written).

And if you have not been blessed with adequate PM support then sorry, this is not a step that you can skip. Well, you can skip it, but you will pay for it later. If you don’t have a PM to interface with clients, organize requirements and write some semblance of a functional spec, then you will need to step up and perform these functions. As painful as these things can be (for someone who would rather just be coding), you will pay the price later on if you start writing code before you know and have received confirmation from the client that you are writing the code that they want.

What if it’s Impossible to Fully Define ALL Functional Requirements Before Starting?

You are in good company — many projects are like this. It is rare that you will have a complete functional spec for a large project ready before you start. But this is no excuse for writing code before you know what it is supposed to do.

You can start work on a section of a project where not everything is defined. But take care that the sections that you are going to start have been fully defined. Or as I wrote above: Do not start writing code before you know what the code needs to accomplish.

Taking a step back though, the more that you know about a project’s overall requirements at the outset, the better. However, at a bare minimum, you need to know the following in order to start on anything:

What problem are you solving? What is the overall goal of the project? (Without this you can do nothing) What is the general outline of the solution that is needed? (Without this it is not clear where you can start)

Armed with this information, you can determine what section you will need to work on first. And before starting, make sure that this section has complete functional requirements. And if this section has a direct dependency on the requirements of another section (or vice versa), make sure that this is understood and taken into account.

But What About my Waterfall?

So how does this approach work with a scrum/waterfall/iterative approach that many of us are used to? Well, there is no reason why it cannot work hand in hand. Knowing what you are going to work on (with some level of confidence that it is what the client wants to have built) is something that is important no matter what you are working on, no matter how often you are going to show a new version to users, and no matter how often you meet with your team or organize your individual tasks. Go ahead and do what works for you (though I definitely have my own opinions on this). Just make sure that when you are going to start working on a new task (or sprint or iteration) that you are clear on the functional requirements ahead of time.

That said, there are situations where a large spec up front may not be the best idea. For example: you are developing a feature where you are not really sure what approach will be best with the end users, and the only way to really tell will be to get something in front of the user and see what works. So writing an end-to-end spec that covers all of the functionality that is to be built will be in some ways a waste of time, since it will describe many things that may not even be built in the end. So in this case you shouldn’t write a huge spec that covers everything. But what you should do is to write or work with a smaller functional document that makes clear the functional goals of every experiment being performed. The goal of “know what you are building” applies here. Maybe your foreknowledge will be looking at a smaller scope of time in the future, but it is still an important thing to do.

Now BREAK IT DOWN!

Once you know what you need to deliver (functional requirements), you still don’t just start down and write code. Your job as the developer (whether you are the author or only the consumer of the functional documentation) is to translate the functional requirements into a working technical plan for implementing all of these requirements.

Here is how you do it:

Go through a small section of the functional requirements Make sure that all of your questions have been answered, edge cases defined. If not, then poke until they are. Think about what you need to do in order to accomplish that piece of functionality. This will include things like: create a page/component, make database modifications, implement pieces of business logic, add unit tests, graphical elements, etc. Write down all of these steps somewhere. Break down the functional goals into all of the individual technical steps that you will need to complete in order to deliver the functionality. Start working, using your plan as the guide. If questions come up about edge cases or unanticipated functional changes, be sure to stop and ask them before proceeding (and if needed, rewrite the spec as needed to adjust the functional requirements). And keep your breakdown up to date.

In terms of tools for breakdowns, I personally like to use Trello for this. I set up a Board for the project, lists for each step in the process (Long Term, Dev Queue, In Progress, Complete & Needs Testing, Released), cards for each manageable chunk of work (specific page, process, etc) and checklists on the cards for each granular item that needs to be done (each checkbox being 15 minutes to an hour or two).

Or use some other system for planning out the granular levels of implementation (word/google doc, post-it notes, some other online or custom tool). But it is important that this technical break down be public and that it is your companion throughout the development process. Using the Trello method, as you work on new features, move the Card to the appropriate list, and check off boxes as you finish items. Others working on the project (other developers, PM’s, stakeholders) can see at a glance what you are up to, what you are working on, and (if you are good with updating things) when you get stuck (if you haven’t checked any boxes in a few days, it should be a worrying sign). Lather, rinse, repeat.

(This breakdown is a prerequisite to making an accurate estimate and completing a project on schedule, something that will hopefully be the subject of a future post).

Wrapping It Up

There is more to finishing up the project than just this. But following these guidelines can hopefully help you to: