The Pyramid of Learning to Code

There are three levels of understanding coding we must achieve to become effective developers: Language, where we understand the fundamental parts of the language we are working with; theory, where we understand the why and how of structuring our code, using patterns, and de-complecting codebases; and testing, where we understand how to write automated tests and use test-first practices, known as test-driven development, to build the most maintainable application we can make.

Although the foundation for learning theory is the language and the foundation for learning testing is theory + language, we don’t necessarily have to learn them in this order.

What many new developers fail to see is the big picture. Fresh entrants see only the language part of the ladder and thus focus too much attention on mastering the language, all the things you can do with it, and all the ways you can use the language to write fancy code.

That is wrong.

It’s wrong because of the “sophomore” effect of learning anything: While at first, you have low competence and low confidence, as you start learning your ego believes you to be a rockstar. Too often we see people at the low end of the competence spectrum with an outsized sense of confidence. This is called the Dunning-Kruger Effect.

Because the programming industry grew the way it did, many people do not realize or understand the magnitude of this effect or how significant the extent of it has been on our industry.

The Pyramid of Learning to Code is a model to understand not only the whole mountain of what you need to learn but also gain an insight into how you need to go about learning to code.

Although starting with language fundamentals is important, too much attention paid to language and algorithms will make you a sophomore coder — a wise fool who writes smart, “clever” code that isn’t very good at all. That’s because good code is loosely coupled to the other parts of the system, and “clever” code is challenging to understand.

The most experienced coders — the ones who’ve made it over the “Peak of Mt. Stupid,” through the valley of despair, and up the slope of enlightenment— understand that application development isn’t about being clever. It isn’t about algorithms or what you learn on LeetCode (although that can help you in some professions in the industry, most application developers will never need to write or know any serious algorithms).


Automated testing and TDD are the only answer to this problem. Not only is automated testing the absolute pinnacle of good application development, but testing, when used as a design exercise, will help you make your code less clever and more loosely coupled to the components around it.

I believe that while learning language fundamentals (Typescript, Ruby, Swift, etc) is important, it’s equally if not more important to know application development theory and also testing at the same time. While it might be daunting to think you have to learn everything all at once, there is a real danger to learning a language without learning the theory and testing for the language. For one, your code will wind up clever and brittle, deeply coupled, and if you don’t write tests, you will be the only developer ever who can work on it.