Are you a junior developer?

This post is a detailed look at the junior developer level, following on from the high level descriptions you’ll find here. This discussion focuses on the ability levels, growth patterns, and common pitfalls of the junior developer level.

The key hallmark of juniority is the quest for clarity. To use the language of my homeland, junior developers don’t know their asses from a hole in the ground. Everything is a mystery. Why your Git repository has been decapitated is a mystery. Why your code, which you carefully copied and pasted from several highly voted Stack Overflow answers, still isn’t working is a mystery. Why your code, after random permutations, has begun working — just as mysterious. The junior developer arrives starry-eyed in a world of chaos. What she lacks most of all, usually, is a sense of her place in it all. What does “good” look like? Who should be a role model? Is my workload appropriate for my abilities? Is my tech lead giving me good code review and useful feedback?

This level is fraught with so many pitfalls, it’s honestly shocking we don’t churn more coders out of the industry entirely. (Maybe we do and we just don’t know it? Hard to measure the absence of something… .) Anyway, it’s very easy to learn the wrong things. Or follow the wrong role models. For example, I was recently in a conversation with a junior coder whose tech lead was encouraging her to become a scrum master because it would give her opportunities for “leadership.” This junior developer is still learning the basics of programming itself. How could learning “leadership” be the most important thing?

On top of that, thinking of the scrum master role as “leadership” is laughable. In my career, I’ve interviewed at least a hundred people with significant “scrum master” experience. What they all had in common is that they sucked at actually writing code. In the case of this junior developer, it showed me that her tech lead doesn’t actually know what it takes to be technically senior, not really. But how could this junior developer know that she was being misled? Super dicey situation.

The thing junior developers actually need most is lots of coding tasks — each sized just a smidgeon above their ability level — and high quality code review. If you want to transition out of being a junior developer quickly, the One True Way™ is learning to write good code and to write it fast. People management is not The One True Way™. Project management is damn sure not The One True Way™. If you’re early in your career, your path upward is purely about hard skills.

The reason for this is that as you progress up the ladder of engineering, you need real problem solving skills. The problems only get harder, more ambiguous, and more complex. If you derail into things like process before you acquire significant skill at the core craft of programming, you’re putting a glass ceiling on your own career trajectory. How can you become a good tech lead and mentor if you haven’t learned your own craft deeply? How can you evaluate candidates you need to hire into your team if you have only a shaky understanding of the fundamentals? How you can break down big, complex, company-level problems into coherent parts if you don’t really understand your core tech stack and tools? The short answer is: you can’t.

Oh, you can cheat. You can learn… other… skills. You can learn to be a scrum master. There’s loads of jobs out there for “senior” people with erstwhile coding skills who spend their lives chasing the actual developers about Jira ticket “t-shirt sizes” and sending invites to retrospectives. Hey, if that’s your jam, by all means, be my guest. But the hard truth is that every minute you spend mastering the process of software development before you’ve achieved significant skill in the craft of software development is a minute you’ve lost. Just be aware that your technical problem solving abilities stopped growing as soon as you put on your ceremonial scrum master fez and stoll (or whatever they wear).

Another common pitfall of the junior developer is over reliance on tools. I often find when I interact with junior folks that they’re using VS Code with AI-assisted code completion turned on. That they’re using Git UI tools like GitKraken or similar. On the surface, these tools seem to help out the junior developer by giving her something to start with. She begins to have little internal conversations like, “Hm… what were the arguments of Array.slice again? Oh wait… was it actually Array.splice? Ah, well, VS Code will tell me.” Or maybe something like, “Did I have a branch for this work already created? Am I out of sync with origin/master ? Ah, my git tool will tell me.”

The problem is that the developer begins to rely on the tools to be able to produce any work at all. Take away the tool and suddenly the developer is lost. She doesn’t remember how to do a for-loop from i back down to 0. She just hits Tab when VS Code suggests the right one. What this means practically is that when the junior developer has to dive into a new codebase, she doesn’t actually know how to read the code thoroughly. Or when she’s being tasked with code review from someone doing something a bit tricky, she can’t really make sense of the code. Because she wasn’t practicing the craft of software engineering all along. Instead, she was practicing the craft of picking the right answer from a list of suggestions. Many junior engineers struggle in interviews and have much more limited impact on their teams because they’re only able to produce code when their tool nudges them in the right direction. Moreover, sometimes that nudge is actually wrong, but the developer doesn’t catch it because she’s not reading the code carefully. She’s hitting Tab when it feels like the right code. Strong advice here: If you want to level up out of juniority, do not use auto-complete IDE integrations.

The junior developer starts to come out of the wilderness of juniority when she starts to have a clear picture in her mind about what code to write as soon as she hears a task description. When she begins catching herself making the same old mistakes in her code before sending it out for code review. When her questions transition from “what is this mysterious async keyword?” to “I wonder if there’s a way to parallelise all these calls in a single await statement…?” When she starts to understand what task she’ll take on next based on the task she just finished.

In other words, the junior developer’s life is marked by the constant state of taking in new information. Hard facts. Pointers about code structure. Little gems of wisdom and command line wizardry. A junior developer’s life is a daily influx of new knowledge balanced with a daily outflow of new-to-her code that solves very specific problems.

The sort of tasks I’d expect a junior to be able to handle

  • Fix a data-layer bug causing an occasional error on this screen of the app
  • Extend an existing feature by adding a new piece of UI and querying the database to populate it
  • Refactor these files of older-style syntax into our new, modern coding style

The junior’s tasks are atomic (write some specific code to solve some specific problem). They’re clear and well-scoped. They’re focused on specific outcomes that are already known to someone more senior than them. This is important, because junior folks get lost. They get confused. They make messes of things. Because of this, they need tasks that already have clear paths to success. Their day-to-day conversations with more senior team members ought to be things like, “I’m trying to finish <some specific task> but I’m getting a weird error that I don’t know what to do with.” Which is typically followed by a senior team member looking at the error, thinking of how it must have come to exist, and suggesting remediation steps. In the best case, offering the junior a mini lesson in whatever just went wrong.

The sort of tasks I’d expect a junior not to be able to handle

  • Figure out if a new feature is possible by looking at the data schema and figuring out query performance constraints
  • Work with a product manager and designer to come up with a new application feature
  • Select and adopt a new abstraction to replace an old one that is causing the team headaches

The key distinction between tasks that are good for junior developers and tasks that aren’t is the scope of ambiguity. Junior folks are in deep, deep ambiguity just learning their craft. They’re working hard everyday to learn the nuances of the programming languages they’re working in. Git is an abyss. Command line tools are a quagmire. Code review is a constant game of whack-a-mole where the junior coder’s code is the mole and senior developers’ hard-won coding experience is the mallet.

In other words, a task that is a stretch to a junior developer is one in which they need to learn something new just to complete it. For a mid-level or senior developer that same task would just be a matter of time, not learning, because they’ve already hit those milestones.

On the Cusp of Mid-Level

As junior developers transition toward mid-level, several things change. First and foremost, their pace of work goes up. Way up in some cases. Where true junior devs spend most of their brain time just figuring out how to use their tools to solve specific problems, mid-level engineers have some real skill with those same tools.

One key consequence is that they get a bunch of brainpower back. They can now spend more of their mental energy thinking about how to solve higher-order problems. They’re encountering completely new things less frequently. They have learned lots and lots of coding patterns and key lessons. It’s a bit like gaining “muscle memory”, but for your brain. This translates directly into speed. Mid-level engineers can typically take any junior developer’s task and rip through it in a tiny fraction of the time that it would take a true junior developer. When you start knowing everything required to complete a task, your speed of work becomes bounded only by the time it takes you to understand the task, type the code, test that it works, and get it committed. You’re not mired in seemingly endless documentation or asking for help from senior people as often.

Importantly, junior developers trending toward mid-level will start to understand not just the task they’re working on, but the shape of the whole project they’re working on. The level of ambiguity they’re taking on shifts to bigger, more important things like how to solve more of the problem with less work.