Developer Experience

Principles for improving the development process and team productivity.

If you had an opportunity to hire an intern to help you with your work, you would do this despite knowing they will require training and they will occasionally deliver less optimal output. AI Assistants are (currently) like interns, except they are incredibly fast, knowledgeable, and are always available. They are like the rubber duck that talks back. You use them responsibly to help speed up your workflow in areas where they help and develop the skill of reviewing their output for quality.

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.