Writing more readable code and setting clear expectations can help reduce cognitive load, more consistently reach flow state, and build more effective feedback loops.
Developers spend as much time reading code, if not more, as writing it. However, we often forget when coding that we're writing for other humans to read as much as we are for computers to execute. Software development isn’t just about making things work, it’s about making things that other people can work with.
As developers learn, read, and write code, all the points of friction they encounter combine to form the Developer Experience (DX). The quality of this experience can have a profound impact on technical decision making, hiring, and staff retention. Poor developer experience can cost you money, shrink your customer base, and damage your reputation.
Tooling, development processes, and human factors like having clear goals, or feeling psychologically safe on a team all impact DX. And improving DX has been shown to increase developer productivity, creativity, satisfaction, and boost engagement. It should be considered at every stage in the developer journey, not just at onboarding.
A recent whitepaper by the Association for Computing Machinery (ACM) breaks developer experience into three segments: cognitive load, flow state and feedback loops. When considered altogether, these three factors can describe the full range of friction types encountered by developers as we work. By consistently aiming for clarity in our work, we can help to improve the DX for our entire engineering organization.
Reducing cognitive load
Software development is complex. There are always new tools, languages and methods to learn. Reading, writing, and learning code all contribute to a cognitive load on your brain, straining how much brain processing is required to complete a task, and how much effort it takes to learn and remember information.
When our thinking capacity is full, we have to stop doing one task in order to start another, or we will slow down and might start making mistakes. We experience this often when multitasking, or when our cognitive capacity is reduced by being stressed or tired. To improve developer experience, we should aim to reduce cognitive load by finding ways to eliminate unnecessary hurdles in the development process.
Write clear code
A good codebase follows the default language convention of the language it is written in. Deviation from these standards, however well intentioned, will cause more cognitive load on the developer and will raise the barrier to entry when onboarding.
Consider the reader when you are writing code. There is an excellent talk by David Whitney on Intentional Code which beautifully explains how to consider your software as literature – with context, subtext, and authorial intent. Consider the following code (even if you do not write TypeScript, notice its shape and legibility):
There are many things to like here: well named, pure functions, which return early and often, no superfluous comments and no nested ifs or callbacks. However, there are a few stumbling blocks which increase cognitive load.
Starting at the first line, notice the list of imports. Each one is given a new line, which causes the developer to read each import before they have even had time to even read what this class does. They may start memorizing this information, which is only placed at the top of the page to satisfy JavaScript’s module system. If each of these imports was on one line in a comma separated list, it would lend them less significance and allow the reader to skip over them and on to the functional code.
The important code starts all the way down on line 12 – the class definition. This then flows straight into the function definitions. Conversely to the imports, this could do with a little breathing room, a new line to delineate the different concepts. Like a new paragraph in a novel.
On line 26, due to an 80 character linting tool, the albums function definition and its parameters have been split over multiple lines, not only breaking the expected mental shape of a function, but also lending significance to parameters. The developer may feel they need to grok each before reading on. Placing all of these parameters on one line would push them further out to the right of the document, allowing the reader to understand that they can look through them as and when they need, rather than head computing immediately.
On line 45 there is a comment. Comments should be used sparingly and should describe not what the code does, but why it does what it does.
And, finally, on line 51, there is an orphaned parentheses and semicolon, forced onto a new line by a maximum line length. Really, these two characters would be better placed with the statement they end.
I propose this as a far more readable, block of code:
It considers what information is important to the reader, maintains the expected shape of functions and keeps concepts grouped.
Use dev containers
We can also reduce the time that a developer takes to onboard with a codebase by using dev containers or codespaces. These are lightweight packages which contain the application code, together with its dependencies to create a full developer environment with minimal setup. They remove the need for complicated dependency installation and fears about platform compatibility. Github offers CodeSpaces that run your containers in a browser, and VSCode has a containers extension which allows you to use a container as your full time development environment, greatly reducing cognitive load on the developer.
Enable focus
You can further streamline developer workflows by minimizing context switching and allowing focus time free from email or meetings. Eliminate external noise and distractions, whether it's audible disruptions or unnecessary information in documentation. Enhance accessibility by presenting information in diverse formats, including written documentation, video content, and diagrams.
When cognitive load is well managed, developers will find it much easier to be efficient and productive, which allows them to enter a flow state. This feeling of being ‘in the zone’ is a mental disposition in which a person becomes fully immersed in the activity they are performing. It is an enjoyable, energizing feeling in which creativity, innovation, motivation, and efficiency are all enhanced.
Maximizing flow state
Being in a flow state makes learning easier, it can make us more productive and even make repetitive tasks feel gratifying. To encourage flow state, ensure that the tasks we’re expecting developers to complete balance well with their skill level. Tasks should present enough challenge that the developer is interested, engaged, and learning; not confused or frustrated. Too great a challenge can leave the developer feeling helpless or foolish, while too little challenge leaves them feeling bored and belittled. We want to create confidence in the developer that, even if a task is unexpectedly complicated, it is solvable and achievable.
Provide clear documentation
Poor documentation is an immediate way to knock a developer out of flow state. Outdated information, inconsistencies, ambiguous error messages, and absence of tutorials or code samples can all leave the developer confused and frustrated and more likely to drift away from the task at hand, or look for a different tool or product. We should be ensuring that our documentation is clear and thorough, that it covers:
- Why the project exists - what problems it solves
- How to use it - installation and setup instructions
- Workflows, configuration or processes required to run the project
- Usage examples - code snippets or working demos
- Constraints - any gotchas or design decisions that should be called out
- Versioning information
- Guidelines for collaboration and communication - allow developers to reach out with questions or improvements
Set clearly defined tasks
Completing a task fosters a sense of achievement and reward, which can motivate us to complete more tasks. We should be aiming to give developers clear requirements and goals which will allow them to feel progression and success as they work.
Automate boring tasks
Giving developers tools like dev containers to help them get quickly up and running with a codebase will allow an instant introduction to flow state. Continuous integration and automated test runners give immediate feedback on the quality of a developer’s code, allowing them to catch and fix issues early on. Getting regular feedback as they work reduces context switching and allows them to stay focused on problem solving and task completion.
Embracing feedback
Sustaining meaningful feedback loops between developer effort and impact is central to developer experience. Luckily, feedback is something developers are pretty used to. By constantly looking for ways to improve our output and reduce delays, run tests, look at burndown charts, ask for code reviews, andhold retros.
Feedback allows developers to spot mistakes, to learn, and improve, but it also fosters a feeling of visibility and recognition of performance. Those looking to improve their developer experience should be aiming to shorten their feedback loops – it is imperative that giving and receiving feedback is simple and easy.
Giving feedback
Provide feedback to developers as they work. Continuous testing tools and static analysis tools like Wallaby.js, display test execution results directly in the IDE as you type. There are also plenty of CI/CD tools to check accessibility or code quality like ESLint and Pally, warning developers when they have made a mistake. Providing slow, to no feedback can leave developers in the dark or interrupt them mid process, leading to increased cognitive load and reduced flow state.
Getting feedback
Collecting developer feedback will allow you to discover where developers are struggling, where you might be knocking them out of flow state, or where their cognitive load becomes too much. If you are collecting feedback, it is important to act on it in a timely manner so that developers know that their effort is appreciated. This will ultimately lead to you building more beloved products and processes.
Measurement
Now on to the eternal question: how do I measure this?. Unfortunately the answer is, ‘it depends’. Developer experience is multifaceted, so we must consider a combination of quantitative and qualitative metrics to get a full understanding.
Conduct surveys to collect feedback regularly
Use developer surveys to understand customer satisfaction, discover pain points, and gather suggestions for where you can improve. Use tools like NPS (net promoter score) which will tell you whether your customers would recommend you to others, or CSAT (customer satisfaction score) which tells you how your customers feel about you.
Check in regularly with your internal team to learn where improvements might be made. Keep an eye on employee turnover, which is a sad metric to track, but vital information can be gathered at exit interviews as to what is driving developers away.
Use code quality metrics
Code quality metrics could include:
- Code review feedback
- Code complexity
- Test coverage
- Number of bugs or issues reported
- Time to deployment
- Frequency of deployments
Measure these metrics over time to see if the DX changes that you are making are having the desired effect.
Track developer thriving
You can use things like KPIs, burndown charts, or number of features delivered to measure your team’s productivity and can track this over time. Consider also how frequently developers are being distracted, how many meetings they have, and how effective their communication and collaboration tools are. Keep an eye on what times of day developers are working and for how long. Working extended hours, or emails sent late at night can be an indication of stress or overwork.
Most importantly, remember that developers are humans and as such require support, collaboration, and a sense of belonging.
Final thoughts
Developer experience is a crucial aspect of software development. It encompasses the tools, processes, and culture that shape the developer journey. It can influence not only productivity and product satisfaction, but also job satisfaction and overall well being.
Prioritize improving developer experience by investing in intuitive tools, maintaining open and honest communication, and promoting learning and collaboration.