Becoming a true Full-stack Engineer
The other day I was browsing around on LinkedIn and I saw that more and more of my peers were labeling themselves as full-stack engineers. Over the last several years I’ve been seeing a higher uptick of this moniker being used by engineers to self-describe their abilities. For obvious reasons, it’s quite an impressive title. And for those of you unaware, a full-stack engineer is a software engineer who can code on all layers of the technical stack. This means that the engineer can build everything from the user interface that the users interact with, to the backend API’s necessary to integrate with the UI, and all the way down to being able to define and model the database.
A little background
To give deeper history and insight on the title “full-stack engineer”, many engineers are sometimes pigeonholed into a specific specialization (whether intentional or not). The traditional "software engineers" are typically backend engineers that work on the server-side as well as parts of the data layer. However, as traditional UI experiences have gotten more and more complex, we’ve also been seeing a huge need for front-end engineers as well. As you may (or may not) have read from my last post, I was formerly a full-stack engineer at Intuit. My role and responsibilities were a little more unique vs a typical engineer at Intuit - I worked in a much smaller, scrappier team at...very much akin to a start-up, but with the financial backings of a big company. As a result, the same start-up risks still existed; we could potentially be axed if the business didn’t perform, our revenue had to grow exponentially year over year, and we had very little external support outside the core team. Naturally with any small team, every engineer had complete end-to-end ownership and was responsible for everything they built and touched. I essentially had autonomy to do whatever I wanted! This enabled me to grow in my role and slowly develop into the self-proclaimed "full-stack engineer" role.
I've often been asked what it’s like to be in this role. Now that I've had experience in this for a few years, I can now better define the responsibilities of the position and I want to talk about what I really think it means to be true full-stack engineer.
So what is a true full-stack engineer?
To me, a true full-stack engineer is a product engineer who can work in any layer of the technical stack and understands all its intricacies. But wait, that sounds just like the definition…. You’re right! It is the definition! BUT! Like many words in the dictionary, it is sometimes used in situations where it may not be as appropriate, very similar to how people use the word irony to describe a coincidence. To be nitpicky, I want to go over what I mean by “understands the intricacies” and emphasize what it means to be a product engineer. I feel that a lot of self-proclaimed full-stack engineers don’t necessarily get this right, so let me explain in the context of building web or mobile apps.
Data layer
Data engineers can ignore this part, but when it comes to the data-layer, it is important to understand both RDMS and distributed database solutions. Understanding both enable you the ability to understand the tradeoffs in order to make informed and educated decisions when it comes to storing your data. Once you make a decision, it becomes the most important decision you’ll make. It is the most important because your database is something that is extremely difficult to change once you go live in production. Once you have your first real customer, his/her data will now be permanent. Any data migrations, schema updates, optimizations, etc. have become that much harder to change. It’s imperative to keep your customers data secure, safe, and in tact. Any change to your database puts your customer’s data at risk.
As a result, it is imperative that when starting any new project or product, meaningful time is spent designing your data models and structure. To give an anecdotal example, on my previous team’s rearchitecture project, we had two engineers spend over three weeks refining the database models and schema for our web-app. Given the ease of working with NoSQL solutions and the many DaaS/PaaS solutions out there, the data-tier is sometimes the most overlooked and the weakest area for most full-stack engineers (I am guilty of this as well), but it is the most costly to change. Probably your most significant optimizations with data retrieval come from a well-defined database schema, so understanding and spending time in this tier is key.
Backend services
When working on the server-side in a web or mobile based product, its responsibilities are usually around sending/fetching data and executing some business level logic/algorithms. There are many ways to fetch/send data from the server to the client and many ways to implement your business logic. However, truly understanding the server-side involves understanding how to properly interact with your database, how to efficiently apply your rules, how to implement your code to conform to the standards/conventions/designs, and how your server may interact with various clients. If you were always a backend or server-side engineer, nothing I am saying here is new or revolutionary - this is all general software engineery stuff. Most of this stuff you should already have learned from reading certain books on design patterns or any standards/conventions. But, for those who are a little weaker in this area (i.e. Front-end engineers), it is really important to drill down on these patterns and conventions.
Anybody can write a REST API, but are you ensuring that your API is purely RESTful? (Because if you didn’t know, there’s a difference). Are you even writing an API that can be easily leveraged for multiple clients? Are you making multiple external API calls asynchronously? Should you write a composite service or expose an action verb?
Front-end experiences
When it comes to understanding the front-end, it’s more than just knowing how to write some HTML, CSS, and Javascript. In fact, it’s more than just learning a framework/library. I’ve met many backend engineers who were self-proclaimed “experts" on UI, sometimes claiming that writing code for UI is simple, easy, and not real programming. I’ve also even met many front-end engineers who could barely understand fundamental UI concepts. As you may know, over the past several years, the front-end has gotten more and more complex for both mobile and the web. Users want fast UI experiences, they want desktop-like features, they want uniformity across all their various devices, and at the end of the day, it must all look sexy. In order to achieve all of these feats, building user interfaces involves it’s own set of design patterns, standards, conventions, and principles - separate from what you may accustomed to on the server-side.
The cool and scary thing about building UI is that anyone can build something quickly that looks decently and seemingly works. But, as soon as that app starts to get bigger and bigger, just like with your backend code, if the due diligence wasn’t made to establish style guides, code modularity, UI components, state management, client-side models, and etc., you are going to have a rough time and your users will suffer from it. The UI is the first thing your users will interact with, so no matter how good your backend or database is built, if the UI experience is not done well, you will lose those customers. The dynamic landscape of current UI platforms have also made the space much more complex than it ever was. Unlike the backend, where standards and design patterns have already been well defined for many years, it's all still being figured out for the front-end. So to understand the front-end, you must stay constantly up to date, read key design patterns, understand how your platform works (i.e. browser or mobile), and learn how to build UI for large scale apps.
Be a product engineer
I consider a product engineer to be one whose sole purpose is to build stuff for somebody. “Build stuff” usually refers to your user-facing software product, whether it’s a web app or mobile app. “Somebody” usually refers to your customer, e.g. yourself, your consumers, your team, etc. Why is it important for me to make this distinction?. Because full-stack engineers can work in any layer of the stack, they can build products end-to-end for customers that just works. They are malleable, dynamic, and can essentially be single man startups.
However, one of the disadvantages of being a full-stack engineer is that they are always generalists over specialists. Notice that in the last three sections, I talk about why it was important for full-stack engineers to understand the intricacies of every layer, but I never said it was their responsibility to be an expert in each. In fact, it’s impossible to be both a implementor and a conceptual expert in every layer. People spend their entire professional career focused on just one area and oftentimes they still don’t know everything. There’s just so much to learn and know!
But it is perfectly okay to be a generalist! Full-stack engineers are perfect team players! Being a full-stack engineer gives you better insight, empathy, and skills in all the layers. If you were a full-stack engineer, you would be able to jump into any part of the code to help out your team. You can work with other more specialized engineers to better understand the pain points and help make the proper tradeoffs. This would enable you to really focus on building the core features that will solve your customer's problems, while the specialized engineers can focus on optimizations and improvements. I’ve run into many scenarios where it’s been difficult to convince a backend engineer on the tradeoffs of the API he/she built for UI consumption, as well as convince a front-end engineer on some of the limitations of the available services and data. However, my background and understanding in these areas have enabled me to work with them to make the right decisions.
Full-stack engineers are always generalists over specialists.
To get over the hurdle of being a generalist, I find the best full-stack engineers are those who not only have an understanding on the intricacies on every layer of the stack, but are also specialists in one area. This involves spending a lot of time heads down on any layer whilst spending another huge chunk of time specially in one area. However, not many people have the luxury of he time to do this. For example, I am comfortable working on any layer, but I have an inherent passion and strength on the front-end. The front-end is where I spend 80% of my time, even though I’ve had extensive enterprise experience on the backend and on the data tier. Unfortunately, it is extremely difficult to keep my skills sharp on every layer, so I often spend an additional day almost every weekend working on projects that allow me to alternate between working strictly on the front-end and working end-to-end.
Everyone should strive to be a true full-stack engineer
Despite front-end engineers being generally generalists (ha!), I fundamentally believe everyone should strive to be a full-stack engineer. I also believe it’s every full-stack engineer’s responsibility to have a specialization in a particular area. Because full-stack engineers are inherently product engineers as well, I found that full-stack engineers find themselves taking on responsibilities outside of engineering. Many become quite good at UI/UX design, interaction design, product design, dev-ops, and more!
If everyone on your team is aligned with this mentality, you’ll be amazed by how well you’ll all be able to work together and how fast you can get shit done. I’ve been very lucky to have been able to work with a team that emphasized this on day one, where every member embodied this mindset. Becoming a full-stack engineer encourages flexibility, creates empathy, provides insight on balancing short and long term decisions, and enables you to focus on solving customer problems. What's the best way to become a full-stack engineer? The best way to become a full-stack engineer is by exposing yourself to every layer. And how do you do that? By building things! Build shit! Break shit! Ship shit! Okay, well.... don't ship shit, but ship something! So have at it!