On the other side: how a frontend developer became a software engineer

Антон Никулин
IT’s Tinkoff
Published in
7 min readJun 11, 2021

I have the feeling that now, due to the high salaries in IT, a lot of self-taught people and graduates from “Become a Developer in n Months” courses are entering the market.

About 6 years ago I was that self-taught. For about 4 years I was getting experience only in frontend. Nevertheless, I was sure that it was enough to be a cool developer. But then I was lucky enough to join a team that didn’t divide into frontend, backend, testers, and DevOps. I have discovered a lot and would like to share my insights with you.

My team

First let me say a few words about the team. As I have already mentioned, there is no differentiation by specialty. Each member of the team is a Software Engineer with a different background. Someone had experience mostly in the frontend, someone wrote in Python, and someone in C++.

In terms of management, this is like any other Tinkoff team. You’re free to choose Kanban or Scrum, come up with something of your own, do some experimenting. All this leads to the result that you don’t have a job “dropped off” from above. There are goals, and how to achieve them — is a team effort.

And here is the main difference. If some task is usually worked out and divided into front and back, the front is done by frontenders, the back is done by backenders, and the infrastructure and CI/CD are often set up by a different team. In our case, you have to do it all by yourself. So, there is no way to say “I did my part, but Jack didn’t develop it, check it, and fill in the TOR”. You are responsible for the task from beginning to the end. This changes your way of thinking a lot.

After a year and a half of such work I began to look at the process of development and my own development completely differently. Let’s move on to what I learned during this time.

Do not hurry!

The most important lesson I learned was to take your time! If you come across a new technology that will take a strong position in your stack, just carefully and thoughtfully study the base: read the documentation, take a training course or, if time is running out, ask for help from experts.

A rush to learn a certain technology will quickly lead to exhaustion and burnout. Of course, much depends on individual peculiarities, but the process is the same for everyone: building new neural connections in the brain. This is a very resource-intensive process, so there is no need to complicate it.

Basic knowledge is really necessary

If you are planning to achieve your development career something more than creating components on some framework, you definitely need a basic knowledge of how memory works, the different protocols, the browser, how to write algorithms, and so on. I thought I didn’t need all that. I was quite surprised.

You may never need to set up networks in a cluster, write algorithms for databases or calculate rocket flight, but it is useful to pack your code into a Docker container or write a binary search function if needed.

For example, a very popular real-world task is to write a function that looks for an element in an array. We know that this function will be called many times. If you understand basic things, you won’t do something like this:

const some = array.find(el => el.id === someId);

This code will traverse the array to the first occurrence, that is, for every search we will traverse the entire array. Imagine there are 100 thousand elements in it. But if you think about it, it would be better to stack elements in `Map` by keys and take them from there. If there are no keys, you can use that same binary search function. Here it all depends on the situation.

The existence of the “Black boxes”

This point follows almost straight from the previous one. Everything that was not directly related to the front was a “black box” for me.

Tinkoff employs cool specialists, and I assumed that they knew better than I did what to do on their side, so I did not get into much. Before, I didn’t care about everything that happened on the back end, how the database worked, or how the application was deployed. With the new team, however, I had to open them up, and here’s what I learned.

Sharing of Responsibility — is a myth

Everything that happens in your project, from the idea to the metrics to the final feature, affects you. You can and should study it, propose your own solutions, and generally participate in every way possible. You will get very far as a professional if you do not throw responsibility on others, solve problems and deal with difficulties yourself.

There are many ways to influence the product. For example, for product teams, you can use various practices like “The Three Amigos,” where all the specialists sit down at one table to work out the best solution. You can participate in the processes of the other part of the team — watch the back team’s merge-requests or help conduct regression. It is unlikely that you will be interrupted.

The code needs to be delivered

Even if you’ve written great code, it’s of no value until it’s of real use to someone in particular. And for that, your code needs to be delivered — assembled, tested, and deployed. So any developer needs to know at least a little bit about DevOps.

You don’t have to deploy and configure a Rancher or Kubernetes cluster right away. Start small — write a Dockerfile and run your service in Docker. You don’t even need Linux for this now: thanks to WSL, you even have it on Windows 10 Home.

Experience exchange

If you have a fear of diving into another area because of having to start all over again, exhale, because that’s not the case. Often you will be able to build on your previous experience. For example, if you’ve written in Angular, Dependency Injection in Spring will create little to no difficulty, and writing a RESTful service in all languages and frameworks will follow the same principles.

When it comes to benefits for your work as a frontrunner, modern frameworks tell us to think in terms of data, not DOM elements. For the most part, we now think in components and often store business logic right there (and where else to store it?). Experience in object-oriented programming languages like Kotlin will change the way you think, and you’ll have different classes at the front end for different tasks:

  • Receiving data — SomeService
  • Data validation — SomeValidator
  • Translation into the required data model — AnotherFactory.fromSome(some)
  • Data processing — AnotherDataService
  • Data storage — AnotherDataStore
  • Data display — AnotherDataComponent

These tasks often try to fit into a single component, so that they get very large and it becomes too difficult to maintain them. I used to think this was normal and natural and not a consequence of ill-conceived architecture. Now I’m completely convinced of the opposite.

Yes, there are a lot of classes, but each of them performs only one function. Such a class is very easy to use and test. It’s an implementation of SOLID principles, which is unusual for front-enders but is used everywhere in the backend.

Metrics are important

Even when your application is running and people use it, without metrics you do not know what is really happening to it. Sooner or later, you will have to answer the following questions:

  • How does the service work?
  • Does the service handle the load?
  • Are there enough resources?
  • Who is using the service?
  • How do they use the service?
  • What kind of experience do they get?

If you do not have that data, then you know practically nothing about your service. There has been a time in my experience where we only got outage reports from user messages. It was an internal service, but nevertheless it is unacceptable.

As a result, we got down to observability — we wrote good logs, collected metrics on memory and CPU consumption, the work of the Garbage Collector, and so on. As a result, we managed to detect infinite memory consumption by the service due to a bug in one of the monitoring library dependencies. It would be impossible to find out without metrics.

About the benefits

Over the past year, I have created two Spring applications in conjunction with Kotlin, two small frontends in Angular and React, wrote several builds on TeamCity DSL and did a little work on the service in Python. The main thing I can tell right away is that the developer experience in the JavaScript or TypeScript ecosystem has gone a long way.

We are already used to running two test cases in this file, which I just fixed. It will automatically restart after making changes. You can even use QuokkaJS, and the editor will show the test coverage in real time.

We are used to not thinking about formatting the code, Prettier will do it for us, and Husky or Lint Staged will run all the checks and formatting at the time of the commit. It’s hard to imagine a JS/TS project without this automation.

So be prepared for the overhead when working on other stacks. With a few exceptions, all of these automations simply don’t exist on many other platforms. Perhaps you will be one of those who can do this.

Conclusion

Summarising all my experience, I can say that the most important thing is professional development. If you are already a little bored or just interested in something, dive into it. If you are a frontend developer, then try yourself in the backend or DevOps. The more you change your usual work, the more neural connections will be created and the brighter the new experience will be.

Moreover, the more zones you cover, the stronger the synergistic effect will be. The knowledge gained in different areas complements each other, and as a result, a complex Computer Science base is obtained. From a narrow specialist, you turn into a software engineer capable of handling any task.

--

--