Developer Experience

Principles for improving the development process and team productivity.

The landscape of developer tools changes on a regular basis. A productive engineer keeps on the lookout for tools that will help them become more productive. Identifying tools and workflow changes that actually make you more productive can be a challenge and weighing the value of the tool against the cost of onboarding is an important skill. It's easy to spend far too much time working on your development environment ("What theme and font is that!?") so avoid spinning your wheels on this. But it's an important skill to continue to stay relevant in the field by adapting to and adopting more productive tools and workflows.

Code comments explain the 'why.' Variables/function names explain the 'what.' Code flow explains the 'how.' Documenting public functions and properties (via jsdoc for example) can be extremely helpful. Sometimes you need to go beyond the code and explain overarching patterns and architectural structure and decisions. This is where decision documents and project-level documentation can come in handy. Keeping this documentation up-to-date over time is challenging, but important for projects which are intended for long-term maintenance and work from a team. Keep the documentation as close to the code as possible to make it easier.

When you can develop offline, it enables you to tighten your feedback loop, iterate faster, and deliver more value. Not because you regularly work without a network connection (though you can), but because it forces you to be more thoughtful about the services upon which you depend and the challenge of setting those things up locally. This also helps your tests be more reliable and issues more reproducible.

Your primary branch should be deployable at all times. This requires all validation checks (tests, linting, type checking) to pass before a commit makes it into the main branch. This also typically means when changes are merged, they either bring in a set of commits which can each be deployable on their own or are squashed into a single commit. Having this kind of discipline makes it easier to rollback to any point in time, perform a bisect when trying to identify when a bug was introduced, and understand the evolution of the codebase.

Maintaining a branch with many changes over a long period of time is cumbersome and error prone. Even the best reviewers get tired and confused and will miss important changes in large merge requests. Use of feature flags can help ensure a feature can be merged before being complete while still enabling the commit to be deployable.

In the process of shipping software, you often get things working and then move on to the next step. When you're ready to increase your velocity, you dive into the abstractions you use to understand how they work so you can use them more effectively.