Skip to main content
Select a theme to activate music mode, and use your keyboard to play a tune.

The Burden of Stylistic Decisions

I started my new role as a Senior Software Engineer at GitHub a couple of weeks ago. There's been a fair bit of onboarding before I was let loose on the code, but last week I pleased to receive my first issue to work on in the Primer Brand repo.

The issue itself couldn't have been simpler. There was an undocumented prop on a component which needed documenting and testing, and the styles needed checking to make sure they aligned with the designs. If I'd been handed this task in my last job I'd have blasted through it in no time at all; I know the tools, the processes, the code standards, and the task itself isn't a complex one.

In my new role, however, all this context is missing. Each decision needs to be actively considered and, oftentimes, researched in the codebase to make sure the code that's being written is consistent with the code which already exists. If the existing code surprises you in some way, you have to understand why that is, and why it's done that way compared to the way you'd expected.

When I was working on this issue — you're welcome to look at the PR as it's on an open source project — I found myself asking dozens of questions for every line of code I wrote, regardless of how simple the code was.

"What do our tests looks like? Oh, we're using Testing Library, cool! That's a lot of cases of getByTestId() though, why do we rely on it so heavily when getByRole() would work just as well here? I need to write a new test, so shall I use getByTestId() to keep things consistent, or getByRole() as that's generally the preferred query? Oh, there's a for-loop in this test, that's interesting. Is there a reason we don't use it.each()? It would simplify the test and make its intention more immediately obvious, right? Well I need to loop in my test, so should I use a for-loop for consistency or use it.each() as is my preference?"

All of those questions and decisions require time and mental energy to make when both writing the code, and when justifying it during PR review. In all, my relatively simple change took 2 days to implement and merge, primarily due to the number of stylistic decisions that had to be made due to the unfamiliarity with the new codebase. These decisions exist completely separately from the functional knowledge which is carried over from job to job.

Assistance making these decisions — or ways to negate the need for them to be made at all — would drastically speed up onboarding into a new organisation, or even just a new codebase. I'd have been able to jump in, make the changes I knew needed to be made, and not worry about the specifics of the code. Rather, I could just focus on the core problem that I was tasked with solving.

I'd be interested to see what tooling emerges in the coming years to help reduce the number of stylistic decisions that we need to make when writing code. We already have tools like ESLint and Prettier which do a lot of heavy lifting, but there's a limit on how far rule-based tools can go.

I foresee tools like Copilot evolving to give general advice and feedback on your code as you're writing it, much like a real-time PR review. How cool would it be to have it point out in real-time that getByTestId() isn't necessary in this case and getByRole() would work just as well. Or that the convention in the codebase is to use for-loops over it.each() in tests, along with the pros and cons of each approach and a button to open an issue with your colleagues to discuss further.

It's entirely possible that Copilot — or some other AI coding tool — can do this already and I just don't know about it. If you know that to be the case, then my very long and complex search query has been successful, so please let me know how I can offload my stylistic decisions to the robots!