As a developer, I often asked myself: what should I learn next? How can I grow further? I always feel that if I'm not growing, I will not keep up with our domain, which is continuously changing and evolving.
Until recently, I've seen this growth only through the lens of programming languages, frameworks and tools. In other words, technology.
My journey looked something like this:
Learning new programming languages, frameworks, tools and technical practices helped me expand my knowledge and intensified my appreciation for what each one brings to the table. It helped me achieve a portion of the growth I was looking for.
More recently, I reflected on those experiences and discovered something new, namely that: The products you are working with have a huge impact on your growth! The products we work on have a huge impact on building the needed skills to become a great craftsperson.
At some point, each of us wants to be part of a team that is going to build a product from scratch, that greenfield product. Why? No more legacy code. Clean. The "right" way. Working under such conditions challenges you to think about project structure, high level architecture, deployment, infrastructure, setup and many other aspects. To be honest, you will probably want to redo everything after 3 months, but that's a topic for another day.
One experience which was tough, but helped me grow quickly was working for a startup. The urgency of delivery, the dynamic environment and the fight to get more users, shapes you in ways you will not encounter in enterprise products.
Another challenging experience is working on a product with legacy code, especially the ones that have over 10 years of history. The complexity and challenges you face just to add a new feature, require you to stretch what you think you know and even develop new working patterns. These are hard to develop if you've never worked on a legacy code base before.
Rebuilding Legacy Products
The builder inside me now loves the challenges of rebuilding legacy products. I've had the good fortune to experiment on both approaches: big rewrite and incremental rewrite. Both are difficult in the sense that they throw new obstacles at you, ones that you would unlikely encounter otherwise, ever.
Products From Different Domains
I also feel that there is a lot to learn from working on products from different domains. For example, working on a product that is in a highly regulated domain, helps you build the kind of discipline and consideration for quality that you need, as a craftsperson.
Multiple Teams Contributing
Working for a product or many products where multiple teams are contributing brings its own challenges and rewards. You will learn new skills in terms of communication, coordination, separation of concerns, but the type of technical challenges will also be different.
High Scale Products
I also find it very appealing to work on high scale products, that are heavily used or ones that process a lot of data, where you will face totally different problems of scalability. You will need to expand your system design skills as solutions you've used before might no longer be applicable.
We often think about technology when we think about growth, but a craftsperson is defined by the range of challenges s/he can overcome. Going through all these types of products and experiences challenges you to grow, to deepen your knowledge and become a better craftsperson. It sharpens your instincts and prepares you for our continuously changing and evolving industry.
I do believe we will continue to face new challenges and the best way to be prepared is to be open-minded, to be curious, to learn and to embrace new challenges, so that we can excel at change and adapt. These skills will make you a better craftsperson.
Programming languages, frameworks, and tools are important, and learning new ones help you grow. That growth can be accelerated by working on different types of product challenges.
Personally, I would look for the experiences and challenges that different types of products and engagements can bring, combined with new programming languages, frameworks and tools.