To plan their features professional teams use processes with multiple roles involved. They ideate, design, plan, estimate, and prioritize features before they start the implementation. They split large features into small chunks that can be tackled by multiple devs in parallel.
Sounds reasonable. But without job experience, you probably don’t have a clue what that looks like in real life. The goal of this article is to expose you to a typical feature planning process. One that you’ll likely encounter on your first job.
- First, we’ll cover a bit of theory about a typical product team and the planning process.
- Later we’ll apply the learnings to two examples. At least the parts that you’ll likely be involved in as a Junior developer.
The examples are based on user stories and designs. This way you can see the process applied in a realistic scenario and practice it yourself.
My advice is to read at least the theory part on this page before watching the video below. The explanations here are admittedly better than in the video.
If you want to get hands-on practice in a professional environment sign up for the upcoming React Job Simulator.
- A Typical Product Team
- The Feature Planning Process
- Example 1: Planning a simple Sidebar Navigation
Example 2: Planning a complex interactive page
- User Story
- Technical Planning
Note: The descriptions here are based on my experience working with a handful of teams. The exact process and responsibilities differ from team to team. But the overall picture should be similar in many companies.
Before we dive into the planning process we should understand what a typical product team looks like. What kind of roles are involved? What are their responsibilities?
These are the people that a frontend developer works with on a daily basis:
Note: this is written from the perspective of a developer. Some things are simplified and technically not accurate (e.g. Product Manager and Product Owner may not be the same role). There might also be other roles involved like QA engineers. Still this should paint a similar picture to what a new developer encounters in their first job.
The Product Manager (or Product Owner in Scrum terminology): there’s typically one PM for a team of developers. They basically ensure that the devs have something to work on (apart from refactoring the codebase).
- They gather feature requests and requirements.
- They write tasks in the form of user stories (more on that later).
- They prioritize features and tasks together with upper management.
In essence, Product Managers are the bridge between the outer world (e.g. upper management or other departments) and the developers.
The Designer: there’s typically one designer for a team of developers. Often they even work with multiple teams. Their responsibilities are creating UI designs (obviously) but they might also be involved in user research (e.g. as UX designers).
The Developers: for every Product Manager or Designer there are typically multiple developers. In most cases, the development is the bottleneck of building a product. Their responsibility is to implement new features, fix bugs, maintain and improve the system, but also to participate in plannings and estimations of upcoming features.
Which leads us to the next chapter.
Here is a bit of background information about how a feature makes its way from ideation to being deployed to production. This is a bit theoretical but we’ll see two hands-on examples later on.
The whole process starts with a request for a new feature. This request might come from within the team, the business people, another department (like the marketing department), or the company’s users.
The Product Manager gathers the requirements for the feature, works with the designer to create the UI, and writes user stories. Often one or more developers are also involved in this process to understand technical feasibility early on.
A User Story is a type of task that describes (part of a) feature from the perspective of a user. It doesn’t contain much technical information but explains the purpose of the ticket. Multiple stories might be grouped together as an Epic which describes the complete feature.
A common template for a user story is this: “As a ... I want ... so that ...”
An example: “As a user I want to use a navigation bar so that I can easily visit all the important parts of the application”.
Once the Product Manager decides that the feature and user stories are in a presentable state they discuss them with the developers in a so-called backlog refinement or backlog grooming.
This is a meeting where the whole team meets and everyone has a chance to ask questions and raise concerns about potential implementation issues. For example, a part of the feature might look simple but could be very complicated to implement. Often the PM and designer aren’t aware of that. The team can discuss the issue and either find a simpler solution or split the story into smaller chunks.
Once all questions are cleared it’s time to estimate the effort.
Management needs to make projections. When will a feature be ready? When should our customers expect it? What does our roadmap look like? Usually, estimations are used to make these projections. And the easiest and most obvious way to estimate is to ask a developer: “How long does it take to build this?”
Nothing a developer hates more...
Experience shows, that this leads to vastly underestimated timelines. So smart people tried to decouple estimates from time by assigning complexity points to stories. Developers basically say: “This task sounds complicated. I give it an 8.” or “This is simple. It’s a 1”.
These numbers are called Storypoints.
They don’t have any inherent meaning but over time the team usually aligns on what each number represents.
The idea is that you can observe how many points a team can accomplish in a certain timeframe (often a 2-week Sprint). This is called velocity. And the average velocity over a couple of Sprints can then be used by management to get a time estimate for a feature.
Many teams use numbers from the Fibonacci series (1, 2, 3, 5, 8, 13, 21...). The theory is that the more complex a task the more inaccurate its estimate. The increasing gaps between the Storypoints represent this inaccuracy.
Now, this sounds all great in theory. But the numeric nature of Storypoints often leads to misuse. Typical signs are:
- The Storypoint estimate is transformed into a time estimate. Example: “This story has 1 point so it should take half a day.”
- Storypoint estimates are turned against the dev team: “You gave this feature 60 points in total so you have a deadline of 4 weeks” or “This team needs to increase its velocity.” or worse “Team A is much more performant than Team B because of its higher velocity.”
Most importantly though, research shows that you can simply count the number of stories instead of the Storypoints and basically get the same estimate. So the whole estimation effort might be a waste of time.
Nevertheless, most teams make use of Storypoint estimations. So if you want to start a career as a developer you’re likely to encounter them sooner rather than later.
This meeting is optional. It might also take place before the estimations.
Once the user stories are estimated the developers gather again to discuss the technical details. Remember, a user story is written from the user’s perspective and typically doesn’t contain a lot of technical information.
Much of the technical discussion should already have happened before the estimation. So if required the devs simply break each user story into multiple technical tasks that make sense from their perspective. These could include things like adding a column to a Database table, updating the API, or adding a component to the UI library.
At this point, the user stories are ready for development. The developers pick them up one by one and implement them. Somebody tests the implementation. Ideally, the feature is covered with automated tests to prevent future regressions. And finally, the feature is deployed to production so the users can benefit from it.
We won’t go into details here since this article focuses on the planning process.
All the tasks are visualized on a board. Below is an example of a Kanban-style board with multiple columns. The user stories start at the very left in the backlog. Once they are refined and estimated they can be moved to the Todo column. Now developers can pick a task and move it to the next columns depending on its implementation status.
All this theory can be a bit boring and hard to understand. So let’s continue with two hands-on examples. We’ll start with a simple component.
I don't usually suggest to view the blog on my website. But if you want to practice the process you will have a better experience there since the solutions are hidden initially. Click here to jump to this section on my website.
The first user story of the upcoming React Job Simulator is the sidebar navigation. Here is a screenshot of the ticket from the board above:
You can see the actual User Story, the design, and a list of Acceptance Criteria (also AC). The exact ticket format varies from team to team. The AC don’t include many technical details but describe the functionality from the perspective of a user. Here they basically describe the behavior of the design in words.
During the refinement session, the team goes through the User Story, the design, and the proposed Acceptance Criteria.
Please have a look yourself. Are there inconsistencies in the design? Anything unclear from the ticket description? Anything wrong or missing from the AC? Anything you’d like to change?
Here is what I found:
The refinement of this ticket reveals two smaller problems:
- The last acceptance criterion contains a mistake: the navigation bar shouldn’t slide out to the right but to the left.
- The current page is highlighted in the menu (the “Issues” page in the design). This is missing from the acceptance criteria.
The Product Manager agrees and updates the AC:
The user story is pretty clear so we move on to estimate the user story. As a reminder, every developer picks a number of the Fibonacci series (1, 2, 3, 5, 8, 13, 21) where 1 is a very simple task. Let’s say changing a text or color could be a 1.
Here is a chance for you to practice: Think of a number that represents the complexity of this user story before you read on. No worries, there’s no right or wrong at this point.
My estimate and explanation:
As I said, there’s no right or wrong in this answer. Over time our understanding of these estimates would more and more align.
Assuming that you said something different we could agree on one of the estimates (often the higher one just to be safe). Or we discuss our reasons. This can be very valuable when there are big differences in estimates because it often shows a need for clarification of the user story.
So let me explain why I picked a 3: The sidebar navigation doesn’t look overly complex. It’s a simple UI component without API calls or so involved. But there is a bit of interactivity:
- The sidebar on desktop is collapsible so we need some kind of state.
- The current element is highlighted. This shouldn’t be hard using the URL but it adds some complexity.
- The mobile design behaves differently from the desktop version.
From my perspective, we don’t need to split this user story into multiple technical tasks. We might create a task each for desktop and mobile design due to the different behavior. But I’d leave it as a single user story.
The sidebar navigation was pretty straightforward. Now let’s have a look at a more complex user story from my upcoming React Job Simulator. Here is a screenshot of the issues page design:
Alright, there are a lot more complex components and interactive elements in this design. A look at the board shows that the Product Manager created two user stories:
Let’s take the “Issue List” as an example here.
Here is a screenshot of the user story:
Again, please have a look yourself. Are there inconsistencies in the design? Anything unclear from the ticket description? Anything wrong or missing from the AC? Anything you’d like to change?
Here is what I found:
You can see the complexity of this user story from the acceptance criteria alone. When we have a closer look there are a few things to note:
- The name of the column “Level” in the original design is “Status” in the user story. The design in the user story is just a screenshot of the real design in Figma. And it seems outdated. So never rely on the screenshots in the description of a task.
- The pagination buttons don’t behave as expected in the design. On the first page, the “Previous” button should be disabled. On the last page, the “Next” button should be disabled. This should also be reflected in the AC.
- A large chunk of the acceptance criteria is about the checkboxes and the related “Resolve selected issues” button on top of the table. While it might make sense to include this in the story from the Product Manager’s perspective, we as developers know that there’s a lot going on behind the scenes. The behavior of the checkboxes is already somewhat complex. And a click on the button triggers an API request which includes error handling and the update of the issue list. The suggestion here is to move this to a separate user story “Resolve Issues”.
Luckily, the Product Manager doesn’t put up a fight. They create a separate user story (we’ll ignore that here) and update the AC according to our feedback:
As you can see, the refinement session helped to keep the user story concise and uncovered some cases that weren’t yet mentioned in the acceptance criteria. Especially getting the input of multiple developers can be illuminating here.
It’s time for the estimation. Pick a Storypoint (1, 2, 3, 5, 8, 13, or 21) where 1 is a simple task like changing a text or color.
Here is mine:
Again, it’s expected that we picked different Storypoints. No right or wrong here. But let me explain my decision:
- The table row itself is pretty straightforward (assuming that we get a list of issues with the required data). But the graph could become a bit more complex. We probably should use a chart library and need to compare different options. There’s always a risk that the library doesn’t really fit all requirements like the rounded bars or the gap between bars.
- The pagination adds some complexity. I’m assuming here that the API supports proper pagination. In any case, we need to trigger new API calls whenever one of the buttons is clicked and handle the state of the buttons according to the current page.
- Remember the original design? On desktop, we have a table. On mobile, each issue is rendered as a card though. I’m not sure how complicated this will be from the top of my head. I guess it should be possible with a CSS grid or so. Still, from my perspective, this adds to the story’s complexity.
This user story is obviously a bit more complex. I’d say it makes sense to split it into multiple tasks for the developers. There are some advantages to having multiple smaller tasks:
- The Pull Requests don’t become that big and thus are easier to review.
- Multiple developers can start implementing the feature in parallel (if the tasks don’t depend on each other too much).
So let’s start breaking the user story up. As a reminder here are the design and the acceptance criteria from the story:
Think about the different tasks that you would create. How can you split the story into small self-contained tasks? How can you allow multiple devs to work in parallel?
Here are the tasks that I created
- The “Create Issue Row” task is a simple UI component excluding the graph. We can build this with the help of Storybook. This should be tackled first.
- The “Create Table Task” contains the API call and rendering of the items in a table. It depends on the “Create Issue Row” task but a developer could start already to implement the API call.
- The “Create Mobile Design” task can be started as soon as the first task is done. I’m honestly not sure if this should be a separate task or not. Making this a separate task could lead the developer to forget about the differences between the desktop and mobile design. But that would make a great exercise for the React Job Simulator.
- The “Implement Pagination” task can be started as soon as the “Create Issue Table” task is done. It’s very independent of the other tasks otherwise.
- Finally, the “Create Graph” task is about the column showing the graph. Since this adds a bit of complexity to the user story it makes sense to extract it into a separate task. This way the Product Manager can de-prioritize the graph if there’s a pressing deadline or the team concludes that the effort is not justifiable at this moment.